| # 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. |
| |
| """ |