Home | History | Annotate | Download | only in cros
      1 # Copyright 2014 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import dbus
      6 import logging
      7 
      8 
      9 DBUS_INTERFACE_OBJECT_MANAGER = 'org.freedesktop.DBus.ObjectManager'
     10 
     11 
     12 def dbus2primitive(value):
     13     """Convert values from dbus types to python types.
     14 
     15     @param value: dbus object to convert to a primitive.
     16 
     17     """
     18     if isinstance(value, dbus.Boolean):
     19         return bool(value)
     20     elif isinstance(value, int):
     21         return int(value)
     22     elif isinstance(value, dbus.UInt16):
     23         return long(value)
     24     elif isinstance(value, dbus.UInt32):
     25         return long(value)
     26     elif isinstance(value, dbus.UInt64):
     27         return long(value)
     28     elif isinstance(value, float):
     29         return float(value)
     30     elif isinstance(value, str):
     31         return str(value)
     32     elif isinstance(value, unicode):
     33         return str(value)
     34     elif isinstance(value, list):
     35         return [dbus2primitive(x) for x in value]
     36     elif isinstance(value, tuple):
     37         return tuple([dbus2primitive(x) for x in value])
     38     elif isinstance(value, dict):
     39         return dict([(dbus2primitive(k), dbus2primitive(v))
     40                      for k,v in value.items()])
     41     else:
     42         logging.error('Failed to convert dbus object of class: %r',
     43                       value.__class__.__name__)
     44         return value
     45 
     46 
     47 def get_objects_with_interface(service_name, object_manager_path,
     48                                dbus_interface, path_prefix=None,
     49                                bus=None):
     50     """Get objects that have a particular interface via a property manager.
     51 
     52     @param service_name: string remote service exposing the object manager
     53             to query (e.g. 'org.chromium.peerd').
     54     @param object_manager_path: string DBus path of object manager on remote
     55             service (e.g. '/org/chromium/peerd')
     56     @param dbus_interface: string interface of object we're interested in.
     57     @param path_prefix: string prefix of DBus path to filter for.  If not
     58             None, we'll return only objects in the remote service whose
     59             paths start with this prefix.
     60     @param bus: dbus.Bus object, defaults to dbus.SystemBus().  Note that
     61             normally, dbus.SystemBus() multiplexes a single DBus connection
     62             among its instances.
     63     @return dict that maps object paths to dicts of interface name to properties
     64             exposed by that interface.  This is similar to the structure
     65             returned by org.freedesktop.DBus.ObjectManaber.GetManagedObjects().
     66 
     67     """
     68     if bus is None:
     69         bus = dbus.SystemBus()
     70     object_manager = dbus.Interface(
     71             bus.get_object(service_name, object_manager_path),
     72             dbus_interface=DBUS_INTERFACE_OBJECT_MANAGER)
     73     objects = dbus2primitive(object_manager.GetManagedObjects())
     74     logging.debug('Saw objects %r', objects)
     75     # Filter by interface.
     76     objects = [(path, interfaces)
     77                for path, interfaces in objects.iteritems()
     78                if dbus_interface in interfaces]
     79     if path_prefix is not None:
     80         objects = [(path, interfaces)
     81                    for path, interfaces in objects
     82                    if path.startswith(path_prefix)]
     83     objects = dict(objects)
     84     logging.debug('Filtered objects: %r', objects)
     85     return objects
     86