blob: 675ad403eef1cd78359d058ea5c5591b8a81008c [file] [log] [blame]
Brad Bishop732c6db2015-10-19 14:49:21 -04001#!/usr/bin/env python
2
Brad Bishopb3385602016-03-04 15:32:01 -05003# Contributors Listed Below - COPYRIGHT 2016
Brad Bishop732c6db2015-10-19 14:49:21 -04004# [+] International Business Machines Corp.
5#
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16# implied. See the License for the specific language governing
17# permissions and limitations under the License.
18
Brad Bishop732c6db2015-10-19 14:49:21 -040019import dbus
20import dbus.service
Brad Bishopae0c0af2015-11-09 18:41:28 -050021import dbus.exceptions
Brad Bishop732c6db2015-10-19 14:49:21 -040022import dbus.mainloop.glib
23import gobject
Brad Bishopfb1f58e2016-03-04 15:19:13 -050024from obmc.dbuslib.introspection import IntrospectionParser
25import obmc.utils.pathtree
26import obmc.utils.misc
27import obmc.mapper
Brad Bishopfed968e2016-03-18 10:47:26 -040028import obmc.dbuslib.bindings
Brad Bishopd9fc21c2016-03-18 12:24:42 -040029import obmc.dbuslib.enums
Brad Bishop732c6db2015-10-19 14:49:21 -040030
Brad Bishop4b849412016-02-04 15:40:26 -050031
Brad Bishopae0c0af2015-11-09 18:41:28 -050032class MapperNotFoundException(dbus.exceptions.DBusException):
Brad Bishopfb1f58e2016-03-04 15:19:13 -050033 _dbus_error_name = obmc.mapper.MAPPER_NOT_FOUND
Brad Bishop4b849412016-02-04 15:40:26 -050034
35 def __init__(self, path):
36 super(MapperNotFoundException, self).__init__(
Brad Bishop9cff26b2016-03-18 11:16:47 -040037 "path or object not found: %s" % path)
Brad Bishop4b849412016-02-04 15:40:26 -050038
Brad Bishopae0c0af2015-11-09 18:41:28 -050039
Brad Bishopd9fc21c2016-03-18 12:24:42 -040040class Association(dbus.service.Object):
41 def __init__(self, bus, path, endpoints):
42 super(Association, self).__init__(bus, path)
43 self.endpoints = endpoints
44
45 def __getattr__(self, name):
46 if name == 'properties':
47 return {
48 obmc.dbuslib.enums.OBMC_ASSOC_IFACE: {
49 'endpoints': self.endpoints}}
50 return super(Association, self).__getattr__(name)
51
52 def emit_signal(self, old):
53 if old != self.endpoints:
54 self.PropertiesChanged(
55 obmc.dbuslib.enums.OBMC_ASSOC_IFACE,
56 {'endpoints': self.endpoints}, ['endpoints'])
57
58 def append(self, endpoints):
59 old = self.endpoints
60 self.endpoints = list(set(endpoints).union(self.endpoints))
61 self.emit_signal(old)
62
63 def remove(self, endpoints):
64 old = self.endpoints
65 self.endpoints = list(set(self.endpoints).difference(endpoints))
66 self.emit_signal(old)
67
68 @dbus.service.method(dbus.PROPERTIES_IFACE, 'ss', 'as')
69 def Get(self, interface_name, property_name):
70 if property_name != 'endpoints':
71 raise dbus.exceptions.DBusException(name=DBUS_UNKNOWN_PROPERTY)
72 return self.GetAll(interface_name)[property_name]
73
74 @dbus.service.method(dbus.PROPERTIES_IFACE, 's', 'a{sas}')
75 def GetAll(self, interface_name):
76 if interface_name != obmc.dbuslib.enums.OBMC_ASSOC_IFACE:
77 raise dbus.exceptions.DBusException(DBUS_UNKNOWN_INTERFACE)
78 return {'endpoints': self.endpoints}
79
80 @dbus.service.signal(
81 dbus.PROPERTIES_IFACE, signature='sa{sas}as')
82 def PropertiesChanged(
83 self, interface_name, changed_properties, invalidated_properties):
84 pass
85
86
87class Manager(obmc.dbuslib.bindings.DbusObjectManager):
88 def __init__(self, bus, path):
89 obmc.dbuslib.bindings.DbusObjectManager.__init__(self)
90 dbus.service.Object.__init__(self, bus.dbus, path)
91
92
Brad Bishop732c6db2015-10-19 14:49:21 -040093class ObjectMapper(dbus.service.Object):
Brad Bishop4b849412016-02-04 15:40:26 -050094 def __init__(self, bus, path,
Brad Bishopfb1f58e2016-03-04 15:19:13 -050095 name_match=obmc.utils.misc.org_dot_openbmc_match,
96 intf_match=obmc.utils.misc.org_dot_openbmc_match):
Brad Bishop4b849412016-02-04 15:40:26 -050097 super(ObjectMapper, self).__init__(bus.dbus, path)
Brad Bishopfb1f58e2016-03-04 15:19:13 -050098 self.cache = obmc.utils.pathtree.PathTree()
Brad Bishop4b849412016-02-04 15:40:26 -050099 self.bus = bus
100 self.name_match = name_match
101 self.intf_match = intf_match
Brad Bishopfb1f58e2016-03-04 15:19:13 -0500102 self.tag_match = obmc.utils.misc.ListMatch(['children', 'interface'])
Brad Bishop4b849412016-02-04 15:40:26 -0500103 self.service = None
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400104 self.index = {}
105 self.manager = Manager(bus, obmc.dbuslib.bindings.OBJ_PREFIX)
106 self.unique = bus.dbus.get_unique_name()
Brad Bishop732c6db2015-10-19 14:49:21 -0400107
Brad Bishop4b849412016-02-04 15:40:26 -0500108 gobject.idle_add(self.discover)
109 self.bus.dbus.add_signal_receiver(
110 self.bus_handler,
111 dbus_interface=
112 dbus.BUS_DAEMON_IFACE,
113 signal_name='NameOwnerChanged')
114 self.bus.dbus.add_signal_receiver(
115 self.interfaces_added_handler,
116 dbus_interface=
117 dbus.BUS_DAEMON_IFACE + '.ObjectManager',
118 signal_name='InterfacesAdded',
Brad Bishopc568e022016-03-23 14:50:05 -0400119 sender_keyword='sender',
120 path_keyword='sender_path')
Brad Bishop4b849412016-02-04 15:40:26 -0500121 self.bus.dbus.add_signal_receiver(
122 self.interfaces_removed_handler,
123 dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager',
124 signal_name='InterfacesRemoved',
Brad Bishopc568e022016-03-23 14:50:05 -0400125 sender_keyword='sender',
126 path_keyword='sender_path')
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400127 self.bus.dbus.add_signal_receiver(
128 self.properties_changed_handler,
129 dbus_interface=dbus.PROPERTIES_IFACE,
130 signal_name='PropertiesChanged',
131 path_keyword='path',
132 sender_keyword='sender')
Brad Bishop732c6db2015-10-19 14:49:21 -0400133
Brad Bishop9cff26b2016-03-18 11:16:47 -0400134 def bus_match(self, owner):
135 # Ignore my own signals
136 return owner != obmc.mapper.MAPPER_NAME and \
137 self.name_match(owner)
Brad Bishop65b7ceb2015-11-04 23:05:56 -0500138
Brad Bishop4b849412016-02-04 15:40:26 -0500139 def discovery_pending(self):
140 return not bool(self.service)
Brad Bishopcb7aa602015-11-03 10:40:17 -0500141
Brad Bishop10abe042016-05-02 23:11:19 -0400142 def cache_get(self, path):
143 cache_entry = self.cache.get(path, {})
144 if cache_entry is None:
145 # hide path elements without any interfaces
146 cache_entry = {}
147 return cache_entry
148
Brad Bishopc568e022016-03-23 14:50:05 -0400149 def add_new_objmgr(self, path, owner):
150 # We don't get a signal for the ObjectManager
151 # interface itself, so if we see a signal from
152 # make sure its in our cache, and add it if not.
Brad Bishop10abe042016-05-02 23:11:19 -0400153 cache_entry = self.cache_get(path)
Brad Bishopc568e022016-03-23 14:50:05 -0400154 old = self.interfaces_get(cache_entry, owner)
155 new = list(set(old).union([dbus.BUS_DAEMON_IFACE + '.ObjectManager']))
156 self.update_interfaces(path, owner, old, new)
157
Brad Bishop4b849412016-02-04 15:40:26 -0500158 def interfaces_added_handler(self, path, iprops, **kw):
Brad Bishopfed968e2016-03-18 10:47:26 -0400159 path = str(path)
160 owner = str(kw['sender'])
161 interfaces = self.get_signal_interfaces(owner, iprops.iterkeys())
Brad Bishop10abe042016-05-02 23:11:19 -0400162 if interfaces:
163 self.add_new_objmgr(str(kw['sender_path']), owner)
164 cache_entry = self.cache_get(path)
Brad Bishopfed968e2016-03-18 10:47:26 -0400165 old = self.interfaces_get(cache_entry, owner)
166 new = list(set(interfaces).union(old))
167 self.update_interfaces(path, owner, old, new)
Brad Bishop732c6db2015-10-19 14:49:21 -0400168
Brad Bishop4b849412016-02-04 15:40:26 -0500169 def interfaces_removed_handler(self, path, interfaces, **kw):
Brad Bishopfed968e2016-03-18 10:47:26 -0400170 path = str(path)
171 owner = str(kw['sender'])
172 interfaces = self.get_signal_interfaces(owner, interfaces)
Brad Bishop10abe042016-05-02 23:11:19 -0400173 if interfaces:
174 self.add_new_objmgr(str(kw['sender_path']), owner)
175 cache_entry = self.cache_get(path)
Brad Bishopfed968e2016-03-18 10:47:26 -0400176 old = self.interfaces_get(cache_entry, owner)
177 new = list(set(old).difference(interfaces))
178 self.update_interfaces(path, owner, old, new)
Brad Bishop732c6db2015-10-19 14:49:21 -0400179
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400180 def properties_changed_handler(self, interface, new, old, **kw):
181 owner = str(kw['sender'])
182 path = str(kw['path'])
183 interfaces = self.get_signal_interfaces(owner, [interface])
184 if not self.is_association(interfaces):
185 return
186 associations = new.get('associations', None)
187 if associations is None:
188 return
189
190 associations = [
191 (str(x), str(y), str(z)) for x, y, z in associations]
192 self.update_associations(
193 path, owner,
194 self.index_get_associations(path, [owner]),
195 associations)
196
Brad Bishop9cff26b2016-03-18 11:16:47 -0400197 def process_new_owner(self, owner):
Brad Bishop4b849412016-02-04 15:40:26 -0500198 # unique name
Brad Bishop9cff26b2016-03-18 11:16:47 -0400199 return self.discover([IntrospectionParser(owner,
Brad Bishop4b849412016-02-04 15:40:26 -0500200 self.bus.dbus,
201 self.tag_match,
202 self.intf_match)])
Brad Bishop732c6db2015-10-19 14:49:21 -0400203
Brad Bishop9cff26b2016-03-18 11:16:47 -0400204 def process_old_owner(self, owner):
Brad Bishopfed968e2016-03-18 10:47:26 -0400205 for path, item in self.cache.dataitems():
Brad Bishop9cff26b2016-03-18 11:16:47 -0400206 old = self.interfaces_get(item, owner)
Brad Bishopfed968e2016-03-18 10:47:26 -0400207 # remove all interfaces for this service
208 self.update_interfaces(
Brad Bishop9cff26b2016-03-18 11:16:47 -0400209 path, owner, old=old, new=[])
Brad Bishop732c6db2015-10-19 14:49:21 -0400210
Brad Bishopfed968e2016-03-18 10:47:26 -0400211 def bus_handler(self, owner, old, new):
212 valid = False
213 if not obmc.dbuslib.bindings.is_unique(owner):
214 valid = self.valid_signal(owner)
Brad Bishop732c6db2015-10-19 14:49:21 -0400215
Brad Bishopfed968e2016-03-18 10:47:26 -0400216 if valid and new:
Brad Bishop4b849412016-02-04 15:40:26 -0500217 self.process_new_owner(new)
Brad Bishopfed968e2016-03-18 10:47:26 -0400218 if valid and old:
Brad Bishop4b849412016-02-04 15:40:26 -0500219 self.process_old_owner(old)
Brad Bishop732c6db2015-10-19 14:49:21 -0400220
Brad Bishopfed968e2016-03-18 10:47:26 -0400221 def update_interfaces(self, path, owner, old, new):
222 cache_entry = self.cache.setdefault(path, {})
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400223 created = [] if self.has_interfaces(cache_entry) else [path]
Brad Bishopfed968e2016-03-18 10:47:26 -0400224 added = list(set(new).difference(old))
225 removed = list(set(old).difference(new))
226 self.interfaces_append(cache_entry, owner, added)
227 self.interfaces_remove(cache_entry, owner, removed, path)
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400228 destroyed = [] if self.has_interfaces(cache_entry) else [path]
229
230 # react to anything that requires association updates
231 new_assoc = []
232 old_assoc = []
233 if self.is_association(added):
234 new_assoc = self.dbus_get_associations(path, owner)
235 if self.is_association(removed):
236 old_assoc = self.index_get_associations(path, [owner])
237 self.update_associations(
238 path, owner, old_assoc, new_assoc, created, destroyed)
Brad Bishop86398d22015-10-28 21:58:31 -0400239
Brad Bishop4b849412016-02-04 15:40:26 -0500240 def add_items(self, owner, bus_items):
Brad Bishopfed968e2016-03-18 10:47:26 -0400241 for path, items in bus_items.iteritems():
242 # convert dbus types to native.
243 interfaces = [str(i) for i in items.get('interfaces', [])]
244 self.update_interfaces(path, str(owner), old=[], new=interfaces)
Brad Bishop86398d22015-10-28 21:58:31 -0400245
Brad Bishop9cff26b2016-03-18 11:16:47 -0400246 def discover(self, owners=[]):
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400247 def match(iface):
248 return iface == dbus.BUS_DAEMON_IFACE + '.ObjectManager' or \
249 self.intf_match(iface)
Brad Bishop4b849412016-02-04 15:40:26 -0500250 if not owners:
Brad Bishop9cff26b2016-03-18 11:16:47 -0400251 owners = [
252 IntrospectionParser(
253 x, self.bus.dbus,
254 self.tag_match,
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400255 match)
Brad Bishop9cff26b2016-03-18 11:16:47 -0400256 for x in self.bus.get_owner_names(self.bus_match)]
Brad Bishop4b849412016-02-04 15:40:26 -0500257 for o in owners:
258 self.add_items(o.name, o.introspect())
Brad Bishop732c6db2015-10-19 14:49:21 -0400259
Brad Bishop4b849412016-02-04 15:40:26 -0500260 if self.discovery_pending():
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400261 # add my object mananger instance
262 self.add_items(
263 self.unique,
264 {obmc.dbuslib.bindings.OBJ_PREFIX:
265 {'interfaces':
266 [dbus.BUS_DAEMON_IFACE + '.ObjectManager']}})
267
Brad Bishop4b849412016-02-04 15:40:26 -0500268 print "ObjectMapper discovery complete..."
269 self.service = dbus.service.BusName(
Brad Bishopfb1f58e2016-03-04 15:19:13 -0500270 obmc.mapper.MAPPER_NAME, self.bus.dbus)
Brad Bishop732c6db2015-10-19 14:49:21 -0400271
Brad Bishopfed968e2016-03-18 10:47:26 -0400272 def valid_signal(self, owner):
273 if obmc.dbuslib.bindings.is_unique(owner):
274 owner = self.bus.get_owned_name(self.bus_match, owner)
275
276 return owner is not None and not self.discovery_pending() and \
277 self.bus_match(owner)
278
279 def get_signal_interfaces(self, owner, interfaces):
280 filtered = []
281 if self.valid_signal(owner):
282 filtered = [str(x) for x in interfaces if self.intf_match(x)]
283
284 return filtered
285
286 @staticmethod
287 def interfaces_get(item, owner, default=[]):
288 return item.get(owner, default)
289
290 @staticmethod
291 def interfaces_append(item, owner, append):
292 interfaces = item.setdefault(owner, [])
293 item[owner] = list(set(append).union(interfaces))
294
295 def interfaces_remove(self, item, owner, remove, path):
296 interfaces = item.get(owner, [])
297 item[owner] = list(set(interfaces).difference(remove))
298
299 if not item[owner]:
300 # remove the owner if there aren't any interfaces left
301 del item[owner]
302
303 if item:
304 # other owners remain
305 return
306
307 if self.cache.get_children(path):
308 # there are still references to this path
309 # from objects further down the tree.
310 # mark it for removal if that changes
311 self.cache.demote(path)
312 else:
313 # delete the entire path if everything is gone
314 del self.cache[path]
315
Brad Bishopfb1f58e2016-03-04 15:19:13 -0500316 @dbus.service.method(obmc.mapper.MAPPER_IFACE, 's', 'a{sas}')
Brad Bishop4b849412016-02-04 15:40:26 -0500317 def GetObject(self, path):
Brad Bishop10abe042016-05-02 23:11:19 -0400318 o = self.cache_get(path)
Brad Bishop4b849412016-02-04 15:40:26 -0500319 if not o:
320 raise MapperNotFoundException(path)
321 return o
Brad Bishop732c6db2015-10-19 14:49:21 -0400322
Brad Bishopfb1f58e2016-03-04 15:19:13 -0500323 @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'si', 'as')
Brad Bishop4b849412016-02-04 15:40:26 -0500324 def GetSubTreePaths(self, path, depth):
325 try:
326 return self.cache.iterkeys(path, depth)
327 except KeyError:
328 raise MapperNotFoundException(path)
Brad Bishop732c6db2015-10-19 14:49:21 -0400329
Brad Bishopfb1f58e2016-03-04 15:19:13 -0500330 @dbus.service.method(obmc.mapper.MAPPER_IFACE, 'si', 'a{sa{sas}}')
Brad Bishop4b849412016-02-04 15:40:26 -0500331 def GetSubTree(self, path, depth):
332 try:
333 return {x: y for x, y in self.cache.dataitems(path, depth)}
334 except KeyError:
335 raise MapperNotFoundException(path)
336
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400337 @staticmethod
338 def has_interfaces(item):
339 for owner in item.iterkeys():
340 if ObjectMapper.interfaces_get(item, owner):
341 return True
342 return False
343
344 @staticmethod
345 def is_association(interfaces):
346 return obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE in interfaces
347
348 def index_get(self, index, path, owners):
349 items = []
350 item = self.index.get(index, {})
351 item = item.get(path, {})
352 for o in owners:
353 items.extend(item.get(o, []))
354 return items
355
356 def index_append(self, index, path, owner, assoc):
357 item = self.index.setdefault(index, {})
358 item = item.setdefault(path, {})
359 item = item.setdefault(owner, [])
360 item.append(assoc)
361
362 def index_remove(self, index, path, owner, assoc):
363 index = self.index.get(index, {})
364 owners = index.get(path, {})
365 items = owners.get(owner, [])
366 if assoc in items:
367 items.remove(assoc)
368 if not items:
369 del owners[owner]
370 if not owners:
371 del index[path]
372
373 def dbus_get_associations(self, path, owner):
374 obj = self.bus.dbus.get_object(owner, path, introspect=False)
375 iface = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
376 return [(str(f), str(r), str(e)) for f, r, e in iface.Get(
377 obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE,
378 'associations')]
379
380 def index_get_associations(self, path, owners=[], direction='forward'):
381 forward = 'forward' if direction == 'forward' else 'reverse'
382 reverse = 'reverse' if direction == 'forward' else 'forward'
383
384 associations = []
385 if not owners:
386 index = self.index.get(forward, {})
387 owners = index.get(path, {}).keys()
388
389 # f: forward
390 # r: reverse
391 for rassoc in self.index_get(forward, path, owners):
392 elements = rassoc.split('/')
393 rtype = ''.join(elements[-1:])
394 fendpoint = '/'.join(elements[:-1])
395 for fassoc in self.index_get(reverse, fendpoint, owners):
396 elements = fassoc.split('/')
397 ftype = ''.join(elements[-1:])
398 rendpoint = '/'.join(elements[:-1])
399 if rendpoint != path:
400 continue
401 associations.append((ftype, rtype, fendpoint))
402
403 return associations
404
405 def update_association(self, path, removed, added):
406 iface = obmc.dbuslib.enums.OBMC_ASSOC_IFACE
407 create = [] if self.manager.get(path, False) else [iface]
408
409 if added and create:
410 self.manager.add(
411 path, Association(self.bus.dbus, path, added))
412 elif added:
413 self.manager.get(path).append(added)
414
415 obj = self.manager.get(path, None)
416 if obj and removed:
417 obj.remove(removed)
418
419 if obj and not obj.endpoints:
420 self.manager.remove(path)
421
422 delete = [] if self.manager.get(path, False) else [iface]
423
424 if create != delete:
425 self.update_interfaces(
426 path, self.unique, delete, create)
427
428 def update_associations(
429 self, path, owner, old, new, created=[], destroyed=[]):
430 added = list(set(new).difference(old))
431 removed = list(set(old).difference(new))
432 for forward, reverse, endpoint in added:
433 # update the index
434 forward_path = str(path + '/' + forward)
435 reverse_path = str(endpoint + '/' + reverse)
436 self.index_append(
437 'forward', path, owner, reverse_path)
438 self.index_append(
439 'reverse', endpoint, owner, forward_path)
440
441 # create the association if the endpoint exists
Brad Bishop10abe042016-05-02 23:11:19 -0400442 if not self.cache_get(endpoint):
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400443 continue
444
445 self.update_association(forward_path, [], [endpoint])
446 self.update_association(reverse_path, [], [path])
447
448 for forward, reverse, endpoint in removed:
449 # update the index
450 forward_path = str(path + '/' + forward)
451 reverse_path = str(endpoint + '/' + reverse)
452 self.index_remove(
453 'forward', path, owner, reverse_path)
454 self.index_remove(
455 'reverse', endpoint, owner, forward_path)
456
457 # destroy the association if it exists
458 self.update_association(forward_path, [endpoint], [])
459 self.update_association(reverse_path, [path], [])
460
461 # If the associations interface endpoint comes
462 # or goes create or destroy the appropriate
463 # associations
464 for path in created:
465 for forward, reverse, endpoint in \
466 self.index_get_associations(path, direction='reverse'):
467 forward_path = str(path + '/' + forward)
468 reverse_path = str(endpoint + '/' + reverse)
469 self.update_association(forward_path, [], [endpoint])
470 self.update_association(reverse_path, [], [path])
471
472 for path in destroyed:
473 for forward, reverse, endpoint in \
474 self.index_get_associations(path, direction='reverse'):
475 forward_path = str(path + '/' + forward)
476 reverse_path = str(endpoint + '/' + reverse)
477 self.update_association(forward_path, [endpoint], [])
478 self.update_association(reverse_path, [path], [])
479
480 @dbus.service.method(obmc.mapper.MAPPER_IFACE, 's', 'a{sa{sas}}')
481 def GetAncestors(self, path):
482 elements = filter(bool, path.split('/'))
483 paths = []
484 objs = {}
485 while elements:
486 elements.pop()
487 paths.append('/' + '/'.join(elements))
488 if path != '/':
489 paths.append('/')
490
491 for path in paths:
Brad Bishop10abe042016-05-02 23:11:19 -0400492 obj = self.cache_get(path)
493 if not obj:
Brad Bishopd9fc21c2016-03-18 12:24:42 -0400494 continue
495 objs[path] = obj
496
497 return objs
498
Brad Bishop732c6db2015-10-19 14:49:21 -0400499
Brad Bishop732c6db2015-10-19 14:49:21 -0400500class BusWrapper:
Brad Bishop4b849412016-02-04 15:40:26 -0500501 def __init__(self, bus):
502 self.dbus = bus
Brad Bishop732c6db2015-10-19 14:49:21 -0400503
Brad Bishop4b849412016-02-04 15:40:26 -0500504 def get_owned_name(self, match, bus):
505 for x in self.get_service_names(match):
506 if self.dbus.get_name_owner(x) == bus:
507 return x
Brad Bishop5ffc2a32015-11-25 08:46:01 -0500508
Brad Bishop4b849412016-02-04 15:40:26 -0500509 def get_service_names(self, match):
510 # these are well known names
511 return [x for x in self.dbus.list_names()
512 if match(x)]
Brad Bishop732c6db2015-10-19 14:49:21 -0400513
Brad Bishop4b849412016-02-04 15:40:26 -0500514 def get_owner_names(self, match):
515 # these are unique connection names
516 return list(set(
517 [self.dbus.get_name_owner(x)
518 for x in self.get_service_names(match)]))
Brad Bishop732c6db2015-10-19 14:49:21 -0400519
Brad Bishop732c6db2015-10-19 14:49:21 -0400520if __name__ == '__main__':
Brad Bishop4b849412016-02-04 15:40:26 -0500521 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
522 bus = dbus.SystemBus()
Brad Bishopfb1f58e2016-03-04 15:19:13 -0500523 o = ObjectMapper(BusWrapper(bus), obmc.mapper.MAPPER_PATH)
Brad Bishop4b849412016-02-04 15:40:26 -0500524 loop = gobject.MainLoop()
Brad Bishop732c6db2015-10-19 14:49:21 -0400525
Brad Bishop4b849412016-02-04 15:40:26 -0500526 loop.run()