blob: 92f26494a2050f37397c65d3d9308d8f1a383b0f [file] [log] [blame]
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import dbus
import dbus.service
class NoSuchPropertyException(Exception):
"""Raised when someone requests a property that has not been registered."""
pass
class DBusPropertyExposer(dbus.service.Object):
"""Exports the org.freedesktop.DBus.Properties interface."""
def __init__(self, bus, path, interface_name):
super(DBusPropertyExposer, self).__init__(bus, path)
self.interface_name = interface_name
self._properties = dict()
def register_property(self, property_name, property_getter):
"""Subclasses should call this function for each exposed property.
@param property_name: string name of property to expose.
@param property_getter: function that takes no arguments and returns
a value for the property, in its proper DBus typing.
"""
self._properties[property_name] = property_getter
def on_property_changed(self, property_name):
"""Subclasses should call this function when property values change.
@param property_name: string name of property that changed.
"""
self.PropertiesChanged(dbus.String(self.interface_name),
self.property_getter(),
dbus.Array([], 's'))
def property_getter(self):
"""Method suitable for giving to the ObjectManager.
@return map of DBus strings to variants.
"""
results = dbus.Dictionary(dict(), 'sv')
for property_name, property_getter in self._properties.iteritems():
results[dbus.String(property_name)] = property_getter()
return results
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ss', out_signature='v')
def Get(self, interface_name, requested_property_name):
"""Implements org.freedesktop.DBus.Properties.Get().
@param interface_name: string interface to get properties of.
@param requested_property_name: string, self explanatory.
@return variant value of the given property.
"""
if interface_name != self.interface_name:
return ''
for property_name, property_getter in self._properties.iteritems():
if property_name == requested_property_name:
return property_getter()
raise NoSuchPropertyException('Could not find property %s' %
requested_property_name)
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='s', out_signature='a{sv}')
def GetAll(self, interface_name):
"""Implements org.freedesktop.DBus.Properties.GetAll().
@param interface_name: string interface to get properties of.
@return dict which maps property names to values.
"""
results = dbus.Dictionary(dict(), 'sv')
if interface_name != self.interface_name:
return results
for property_name, property_getter in self._properties.iteritems():
results[dbus.String(property_name)] = property_getter()
return results
@dbus.service.signal(dbus_interface=dbus.PROPERTIES_IFACE,
signature='sa{sv}as')
def PropertiesChanged(self, interface_name, properties, invalid_properties):
"""Implementation of DBus interface signal.
org.freedesktop.DBus.Properties.PropertiesChanged (
STRING interface_name,
DICT<STRING,VARIANT> changed_properties,
ARRAY<STRING> invalidated_properties);
@param interface_name: See above.
@param properties: See above.
@param invalid_properties: See above.
"""