1 """Bus mixin, for use within dbus-python only. See `_BusMixin`."""
3 # Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
5 # Licensed under the Academic Free License version 2.1
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU Lesser General Public License as published
9 # by the Free Software Foundation; either version 2.1 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 from dbus
import UInt32
, UTF8String
22 from dbus
.proxies
import BUS_DAEMON_NAME
, BUS_DAEMON_PATH
, BUS_DAEMON_IFACE
24 from _dbus_bindings
import validate_interface_name
, validate_member_name
,\
25 validate_bus_name
, validate_object_path
,\
28 def _noop(*args
, **kwargs
):
29 """A universal no-op function"""
31 class _BusDaemonMixin(object):
32 """This mixin must be mixed-in with something with a get_object method
33 (obviously, it's meant to be the dbus.Bus). It provides simple blocking
34 wrappers for various methods on the org.freedesktop.DBus bus-daemon
35 object, to reduce the amount of C code we need.
38 def get_unix_user(self
, bus_name
):
39 """Get the numeric uid of the process owning the given bus name.
43 A bus name, either unique or well-known
44 :Returns: a `dbus.UInt32`
46 validate_bus_name(bus_name
)
47 return self
.get_object(BUS_DAEMON_NAME
,
48 BUS_DAEMON_PATH
).GetConnectionUnixUser(bus_name
,
49 dbus_interface
=BUS_DAEMON_IFACE
)
51 def start_service_by_name(self
, bus_name
, flags
=0):
52 """Start a service which will implement the given bus name on this Bus.
56 The well-known bus name to be activated.
58 Flags to pass to StartServiceByName (currently none are
61 :Returns: A tuple of 2 elements. The first is always True, the
62 second is either START_REPLY_SUCCESS or
63 START_REPLY_ALREADY_RUNNING.
65 :Raises DBusException: if the service could not be started.
67 validate_bus_name(bus_name
)
68 ret
= self
.get_object(BUS_DAEMON_NAME
,
69 BUS_DAEMON_PATH
).StartServiceByName(bus_name
, UInt32(flags
),
70 dbus_interface
=BUS_DAEMON_IFACE
)
73 # XXX: it might be nice to signal IN_QUEUE, EXISTS by exception,
74 # but this would not be backwards-compatible
75 def request_name(self
, name
, flags
=0):
76 """Request a bus name.
80 The well-known name to be requested
82 A bitwise-OR of 0 or more of the flags
83 `DBUS_NAME_FLAG_ALLOW_REPLACEMENT`,
84 `DBUS_NAME_FLAG_REPLACE_EXISTING`
85 and `DBUS_NAME_FLAG_DO_NOT_QUEUE`
86 :Returns: `DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER`,
87 `DBUS_REQUEST_NAME_REPLY_IN_QUEUE`,
88 `DBUS_REQUEST_NAME_REPLY_EXISTS` or
89 `DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER`
90 :Raises DBusException: if the bus daemon cannot be contacted or
93 validate_bus_name(name
, allow_unique
=False)
94 return self
.get_object(BUS_DAEMON_NAME
,
95 BUS_DAEMON_PATH
).RequestName(name
, UInt32(flags
),
96 dbus_interface
=BUS_DAEMON_IFACE
)
98 def release_name(self
, name
):
99 """Release a bus name.
103 The well-known name to be released
104 :Returns: `DBUS_RELEASE_NAME_REPLY_RELEASED`,
105 `DBUS_RELEASE_NAME_REPLY_NON_EXISTENT`
106 or `DBUS_RELEASE_NAME_REPLY_NOT_OWNER`
107 :Raises DBusException: if the bus daemon cannot be contacted or
110 validate_bus_name(name
, allow_unique
=False)
111 return self
.get_object(BUS_DAEMON_NAME
,
112 BUS_DAEMON_PATH
).ReleaseName(name
,
113 dbus_interface
=BUS_DAEMON_IFACE
)
115 def name_has_owner(self
, bus_name
):
116 """Return True iff the given bus name has an owner on this bus.
120 The bus name to look up
123 return bool(self
.get_object(BUS_DAEMON_NAME
,
124 BUS_DAEMON_PATH
).NameHasOwner(bus_name
,
125 dbus_interface
=BUS_DAEMON_IFACE
))
127 # AddMatchString is not bound here
128 # RemoveMatchString either
130 def add_match_string(self
, rule
):
131 """Arrange for this application to receive messages on the bus that
132 match the given rule. This version will block.
137 :Raises: `DBusException` on error.
139 self
.get_object(BUS_DAEMON_NAME
,
140 BUS_DAEMON_PATH
).AddMatch(rule
,
141 dbus_interface
=BUS_DAEMON_IFACE
)
143 # FIXME: add an async success/error handler capability?
144 # FIXME: tell the bus daemon not to bother sending us a reply
145 # (and the same for remove_...)
146 def add_match_string_non_blocking(self
, rule
):
147 """Arrange for this application to receive messages on the bus that
148 match the given rule. This version will not block, but any errors
155 :Raises: `DBusException` on error.
157 self
.get_object(BUS_DAEMON_NAME
,
158 BUS_DAEMON_PATH
).AddMatch(rule
,
159 dbus_interface
=BUS_DAEMON_IFACE
,
163 def remove_match_string(self
, rule
):
164 """Arrange for this application to receive messages on the bus that
165 match the given rule. This version will block.
170 :Raises: `DBusException` on error.
172 self
.get_object(BUS_DAEMON_NAME
,
173 BUS_DAEMON_PATH
).RemoveMatch(rule
,
174 dbus_interface
=BUS_DAEMON_IFACE
)
176 def remove_match_string_non_blocking(self
, rule
):
177 """Arrange for this application to receive messages on the bus that
178 match the given rule. This version will not block, but any errors
185 :Raises: `DBusException` on error.
187 self
.get_object(BUS_DAEMON_NAME
,
188 BUS_DAEMON_PATH
).RemoveMatch(rule
,
189 dbus_interface
=BUS_DAEMON_IFACE
,