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 5import dbus 6import logging 7 8 9DBUS_INTERFACE_OBJECT_MANAGER = 'org.freedesktop.DBus.ObjectManager' 10 11 12def 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 47def 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