# Copyright 2014 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 logging
DBUS_INTERFACE_OBJECT_MANAGER = 'org.freedesktop.DBus.ObjectManager'
def dbus2primitive(value):
"""Convert values from dbus types to python types.
@param value: dbus object to convert to a primitive.
"""
if isinstance(value, dbus.Boolean):
return bool(value)
elif isinstance(value, int):
return int(value)
elif isinstance(value, dbus.UInt16):
return long(value)
elif isinstance(value, dbus.UInt32):
return long(value)
elif isinstance(value, dbus.UInt64):
return long(value)
elif isinstance(value, float):
return float(value)
elif isinstance(value, str):
return str(value)
elif isinstance(value, unicode):
return str(value)
elif isinstance(value, list):
return [dbus2primitive(x) for x in value]
elif isinstance(value, tuple):
return tuple([dbus2primitive(x) for x in value])
elif isinstance(value, dict):
return dict([(dbus2primitive(k), dbus2primitive(v))
for k,v in value.items()])
else:
logging.error('Failed to convert dbus object of class: %r',
value.__class__.__name__)
return value
def get_objects_with_interface(service_name, object_manager_path,
dbus_interface, path_prefix=None,
bus=None):
"""Get objects that have a particular interface via a property manager.
@param service_name: string remote service exposing the object manager
to query (e.g. 'org.chromium.peerd').
@param object_manager_path: string DBus path of object manager on remote
service (e.g. '/org/chromium/peerd')
@param dbus_interface: string interface of object we're interested in.
@param path_prefix: string prefix of DBus path to filter for. If not
None, we'll return only objects in the remote service whose
paths start with this prefix.
@param bus: dbus.Bus object, defaults to dbus.SystemBus(). Note that
normally, dbus.SystemBus() multiplexes a single DBus connection
among its instances.
@return dict that maps object paths to dicts of interface name to properties
exposed by that interface. This is similar to the structure
returned by org.freedesktop.DBus.ObjectManaber.GetManagedObjects().
"""
if bus is None:
bus = dbus.SystemBus()
object_manager = dbus.Interface(
bus.get_object(service_name, object_manager_path),
dbus_interface=DBUS_INTERFACE_OBJECT_MANAGER)
objects = dbus2primitive(object_manager.GetManagedObjects())
logging.debug('Saw objects %r', objects)
# Filter by interface.
objects = [(path, interfaces)
for path, interfaces in objects.iteritems()
if dbus_interface in interfaces]
if path_prefix is not None:
objects = [(path, interfaces)
for path, interfaces in objects
if path.startswith(path_prefix)]
objects = dict(objects)
logging.debug('Filtered objects: %r', objects)
return objects