Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/dbus/helper.py : 73%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python
2# This file is part of Xpra.
3# Copyright (C) 2011-2019 Antoine Martin <antoine@xpra.org>
4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
5# later version. See the file COPYING for details.
7import dbus
9from xpra.log import Logger
12def dbus_to_native(value):
13 #log("dbus_to_native(%s) type=%s", value, type(value))
14 if value is None:
15 return None
16 if isinstance(value, int):
17 return int(value)
18 if isinstance(value, dict):
19 d = {}
20 for k,v in value.items():
21 d[dbus_to_native(k)] = dbus_to_native(v)
22 return d
23 if isinstance(value, str):
24 return str(value)
25 if isinstance(value, float):
26 return float(value)
27 if isinstance(value, list):
28 return [dbus_to_native(x) for x in value]
29 if isinstance(value, dbus.Struct):
30 return [dbus_to_native(value[i]) for i in range(len(value))]
31 return value
33def native_to_dbus(value):
34 if value is None:
35 return None
36 if isinstance(value, int):
37 return dbus.types.Int64(value)
38 if isinstance(value, str):
39 return dbus.types.String(value)
40 if isinstance(value, float):
41 return dbus.types.Double(value)
42 if isinstance(value, (tuple, list, bytearray)):
43 if not value:
44 return dbus.Array(signature="s")
45 keytypes = set(type(x) for x in value)
46 sig = None
47 if len(keytypes)==1:
48 #just one type of key:
49 keytype = tuple(keytypes)[0]
50 if keytype is int:
51 sig = "i"
52 elif keytype is bool:
53 sig = "b"
54 elif keytype is float:
55 sig = "d"
56 if sig:
57 value = [native_to_dbus(v) for v in value]
58 else:
59 sig = "s"
60 #use strings as keys
61 value = [native_to_dbus(str(v)) for v in value]
62 return dbus.types.Array(value)
63 if isinstance(value, dict):
64 if not value:
65 return dbus.types.Dictionary({}, signature="sv")
66 keytypes = set(type(x) for x in value.keys())
67 sig = None
68 if len(keytypes)==1:
69 #just one type of key:
70 keytype = tuple(keytypes)[0]
71 if keytype is int:
72 sig = "i"
73 elif keytype is bool:
74 sig = "b"
75 elif keytype is float:
76 sig = "d"
77 if sig:
78 value = dict((k, native_to_dbus(v)) for k,v in value.items())
79 else:
80 sig = "s"
81 #use strings as keys
82 value = dict((str(k), native_to_dbus(v)) for k,v in value.items())
83 return dbus.types.Dictionary(value, signature="%sv" % sig)
84 return dbus.types.String(value)
87class DBusHelper:
89 def __init__(self):
90 from xpra.dbus.common import init_session_bus
91 self.bus = init_session_bus()
93 def get_session_bus(self):
94 return self.bus
96 def dbus_to_native(self, *args):
97 return dbus_to_native(*args)
100 def call_function(self, bus_name, path, interface, function, args, ok_cb, err_cb):
101 log = Logger("dbus")
102 try:
103 #remote_object = self.bus.get_object("com.example.SampleService","/SomeObject")
104 obj = self.bus.get_object(bus_name, path)
105 log("dbus.get_object(%s, %s)=%s", bus_name, path, obj)
106 except dbus.DBusException:
107 msg = "failed to locate object at: %s:%s" % (bus_name, path)
108 log("DBusHelper: %s", msg)
109 err_cb(msg)
110 return
111 try:
112 fn = obj.get_dbus_method(function, interface)
113 log("%s.get_dbus_method(%s, %s)=%s", obj, function, interface, fn)
114 except Exception:
115 msg = "failed to locate remote function '%s' on %s" % (function, obj)
116 log("DBusHelper: %s", msg)
117 err_cb(msg)
118 return
119 try:
120 log("calling %s(%s)", fn, args)
121 keywords = {"dbus_interface" : interface,
122 "reply_handler" : ok_cb,
123 "error_handler" : err_cb}
124 fn.call_async(*args, **keywords)
125 except Exception as e:
126 msg = "error invoking %s on %s: %s" % (function, obj, e)
127 log("DBusHelper: %s", msg)
128 err_cb(msg)