|
Packit |
130fc8 |
"""Implementation for dbus.Bus. Not to be imported directly."""
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
# Copyright (C) 2003, 2004, 2005, 2006 Red Hat Inc. <http://www.redhat.com/>
|
|
Packit |
130fc8 |
# Copyright (C) 2003 David Zeuthen
|
|
Packit |
130fc8 |
# Copyright (C) 2004 Rob Taylor
|
|
Packit |
130fc8 |
# Copyright (C) 2005, 2006 Collabora Ltd. <http://www.collabora.co.uk/>
|
|
Packit |
130fc8 |
#
|
|
Packit |
130fc8 |
# Permission is hereby granted, free of charge, to any person
|
|
Packit |
130fc8 |
# obtaining a copy of this software and associated documentation
|
|
Packit |
130fc8 |
# files (the "Software"), to deal in the Software without
|
|
Packit |
130fc8 |
# restriction, including without limitation the rights to use, copy,
|
|
Packit |
130fc8 |
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
130fc8 |
# of the Software, and to permit persons to whom the Software is
|
|
Packit |
130fc8 |
# furnished to do so, subject to the following conditions:
|
|
Packit |
130fc8 |
#
|
|
Packit |
130fc8 |
# The above copyright notice and this permission notice shall be
|
|
Packit |
130fc8 |
# included in all copies or substantial portions of the Software.
|
|
Packit |
130fc8 |
#
|
|
Packit |
130fc8 |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
130fc8 |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
130fc8 |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
130fc8 |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
130fc8 |
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
Packit |
130fc8 |
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Packit |
130fc8 |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Packit |
130fc8 |
# DEALINGS IN THE SOFTWARE.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
from __future__ import generators
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
__all__ = ('Bus', 'SystemBus', 'SessionBus', 'StarterBus')
|
|
Packit |
130fc8 |
__docformat__ = 'reStructuredText'
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
from dbus.exceptions import DBusException
|
|
Packit |
130fc8 |
from _dbus_bindings import (
|
|
Packit |
130fc8 |
BUS_DAEMON_IFACE, BUS_DAEMON_NAME, BUS_DAEMON_PATH, BUS_SESSION,
|
|
Packit |
130fc8 |
BUS_STARTER, BUS_SYSTEM, DBUS_START_REPLY_ALREADY_RUNNING,
|
|
Packit |
130fc8 |
DBUS_START_REPLY_SUCCESS, validate_bus_name,
|
|
Packit |
130fc8 |
validate_interface_name, validate_member_name, validate_object_path)
|
|
Packit |
130fc8 |
from dbus.bus import BusConnection
|
|
Packit |
130fc8 |
from dbus.lowlevel import SignalMessage
|
|
Packit |
130fc8 |
from dbus._compat import is_py2
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if is_py2:
|
|
Packit |
130fc8 |
from _dbus_bindings import UTF8String
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
class Bus(BusConnection):
|
|
Packit |
130fc8 |
"""A connection to one of three possible standard buses, the SESSION,
|
|
Packit |
130fc8 |
SYSTEM, or STARTER bus. This class manages shared connections to those
|
|
Packit |
130fc8 |
buses.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
If you're trying to subclass `Bus`, you may be better off subclassing
|
|
Packit |
130fc8 |
`BusConnection`, which doesn't have all this magic.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
_shared_instances = {}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
def __new__(cls, bus_type=BusConnection.TYPE_SESSION, private=False,
|
|
Packit |
130fc8 |
mainloop=None):
|
|
Packit |
130fc8 |
"""Constructor, returning an existing instance where appropriate.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
The returned instance is actually always an instance of `SessionBus`,
|
|
Packit |
130fc8 |
`SystemBus` or `StarterBus`.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Parameters:
|
|
Packit |
130fc8 |
`bus_type` : cls.TYPE_SESSION, cls.TYPE_SYSTEM or cls.TYPE_STARTER
|
|
Packit |
130fc8 |
Connect to the appropriate bus
|
|
Packit |
130fc8 |
`private` : bool
|
|
Packit |
130fc8 |
If true, never return an existing shared instance, but instead
|
|
Packit |
130fc8 |
return a private connection.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Deprecated: since 0.82.3. Use dbus.bus.BusConnection for
|
|
Packit |
130fc8 |
private connections.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
`mainloop` : dbus.mainloop.NativeMainLoop
|
|
Packit |
130fc8 |
The main loop to use. The default is to use the default
|
|
Packit |
130fc8 |
main loop if one has been set up, or raise an exception
|
|
Packit |
130fc8 |
if none has been.
|
|
Packit |
130fc8 |
:Changed: in dbus-python 0.80:
|
|
Packit |
130fc8 |
converted from a wrapper around a Connection to a Connection
|
|
Packit |
130fc8 |
subclass.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
if (not private and bus_type in cls._shared_instances):
|
|
Packit |
130fc8 |
return cls._shared_instances[bus_type]
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
# this is a bit odd, but we create instances of the subtypes
|
|
Packit |
130fc8 |
# so we can return the shared instances if someone tries to
|
|
Packit |
130fc8 |
# construct one of them (otherwise we'd eg try and return an
|
|
Packit |
130fc8 |
# instance of Bus from __new__ in SessionBus). why are there
|
|
Packit |
130fc8 |
# three ways to construct this class? we just don't know.
|
|
Packit |
130fc8 |
if bus_type == BUS_SESSION:
|
|
Packit |
130fc8 |
subclass = SessionBus
|
|
Packit |
130fc8 |
elif bus_type == BUS_SYSTEM:
|
|
Packit |
130fc8 |
subclass = SystemBus
|
|
Packit |
130fc8 |
elif bus_type == BUS_STARTER:
|
|
Packit |
130fc8 |
subclass = StarterBus
|
|
Packit |
130fc8 |
else:
|
|
Packit |
130fc8 |
raise ValueError('invalid bus_type %s' % bus_type)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
bus._bus_type = bus_type
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if not private:
|
|
Packit |
130fc8 |
cls._shared_instances[bus_type] = bus
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
return bus
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
def close(self):
|
|
Packit |
130fc8 |
t = self._bus_type
|
|
Packit |
130fc8 |
if self.__class__._shared_instances.get(t) is self:
|
|
Packit |
130fc8 |
del self.__class__._shared_instances[t]
|
|
Packit |
130fc8 |
super(Bus, self).close()
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
def get_connection(self):
|
|
Packit |
130fc8 |
"""Return self, for backwards compatibility with earlier dbus-python
|
|
Packit |
130fc8 |
versions where Bus was not a subclass of Connection.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Deprecated: since 0.80.0
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
return self
|
|
Packit |
130fc8 |
_connection = property(get_connection, None, None,
|
|
Packit |
130fc8 |
"""self._connection == self, for backwards
|
|
Packit |
130fc8 |
compatibility with earlier dbus-python versions
|
|
Packit |
130fc8 |
where Bus was not a subclass of Connection.""")
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
def get_session(private=False):
|
|
Packit |
130fc8 |
"""Static method that returns a connection to the session bus.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Parameters:
|
|
Packit |
130fc8 |
`private` : bool
|
|
Packit |
130fc8 |
If true, do not return a shared connection.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
return SessionBus(private=private)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
get_session = staticmethod(get_session)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
def get_system(private=False):
|
|
Packit |
130fc8 |
"""Static method that returns a connection to the system bus.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Parameters:
|
|
Packit |
130fc8 |
`private` : bool
|
|
Packit |
130fc8 |
If true, do not return a shared connection.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
return SystemBus(private=private)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
get_system = staticmethod(get_system)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
def get_starter(private=False):
|
|
Packit |
130fc8 |
"""Static method that returns a connection to the starter bus.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Parameters:
|
|
Packit |
130fc8 |
`private` : bool
|
|
Packit |
130fc8 |
If true, do not return a shared connection.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
return StarterBus(private=private)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
get_starter = staticmethod(get_starter)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
def __repr__(self):
|
|
Packit |
130fc8 |
if self._bus_type == BUS_SESSION:
|
|
Packit |
130fc8 |
name = 'session'
|
|
Packit |
130fc8 |
elif self._bus_type == BUS_SYSTEM:
|
|
Packit |
130fc8 |
name = 'system'
|
|
Packit |
130fc8 |
elif self._bus_type == BUS_STARTER:
|
|
Packit |
130fc8 |
name = 'starter'
|
|
Packit |
130fc8 |
else:
|
|
Packit |
130fc8 |
name = 'unknown bus type'
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
return '<%s.%s (%s) at %#x>' % (self.__class__.__module__,
|
|
Packit |
130fc8 |
self.__class__.__name__,
|
|
Packit |
130fc8 |
name, id(self))
|
|
Packit |
130fc8 |
__str__ = __repr__
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
# FIXME: Drop the subclasses here? I can't think why we'd ever want
|
|
Packit |
130fc8 |
# polymorphism
|
|
Packit |
130fc8 |
class SystemBus(Bus):
|
|
Packit |
130fc8 |
"""The system-wide message bus."""
|
|
Packit |
130fc8 |
def __new__(cls, private=False, mainloop=None):
|
|
Packit |
130fc8 |
"""Return a connection to the system bus.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Parameters:
|
|
Packit |
130fc8 |
`private` : bool
|
|
Packit |
130fc8 |
If true, never return an existing shared instance, but instead
|
|
Packit |
130fc8 |
return a private connection.
|
|
Packit |
130fc8 |
`mainloop` : dbus.mainloop.NativeMainLoop
|
|
Packit |
130fc8 |
The main loop to use. The default is to use the default
|
|
Packit |
130fc8 |
main loop if one has been set up, or raise an exception
|
|
Packit |
130fc8 |
if none has been.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
return Bus.__new__(cls, Bus.TYPE_SYSTEM, mainloop=mainloop,
|
|
Packit |
130fc8 |
private=private)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
class SessionBus(Bus):
|
|
Packit |
130fc8 |
"""The session (current login) message bus."""
|
|
Packit |
130fc8 |
def __new__(cls, private=False, mainloop=None):
|
|
Packit |
130fc8 |
"""Return a connection to the session bus.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Parameters:
|
|
Packit |
130fc8 |
`private` : bool
|
|
Packit |
130fc8 |
If true, never return an existing shared instance, but instead
|
|
Packit |
130fc8 |
return a private connection.
|
|
Packit |
130fc8 |
`mainloop` : dbus.mainloop.NativeMainLoop
|
|
Packit |
130fc8 |
The main loop to use. The default is to use the default
|
|
Packit |
130fc8 |
main loop if one has been set up, or raise an exception
|
|
Packit |
130fc8 |
if none has been.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
return Bus.__new__(cls, Bus.TYPE_SESSION, private=private,
|
|
Packit |
130fc8 |
mainloop=mainloop)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
class StarterBus(Bus):
|
|
Packit |
130fc8 |
"""The bus that activated this process (only valid if
|
|
Packit |
130fc8 |
this process was launched by DBus activation).
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
def __new__(cls, private=False, mainloop=None):
|
|
Packit |
130fc8 |
"""Return a connection to the bus that activated this process.
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
:Parameters:
|
|
Packit |
130fc8 |
`private` : bool
|
|
Packit |
130fc8 |
If true, never return an existing shared instance, but instead
|
|
Packit |
130fc8 |
return a private connection.
|
|
Packit |
130fc8 |
`mainloop` : dbus.mainloop.NativeMainLoop
|
|
Packit |
130fc8 |
The main loop to use. The default is to use the default
|
|
Packit |
130fc8 |
main loop if one has been set up, or raise an exception
|
|
Packit |
130fc8 |
if none has been.
|
|
Packit |
130fc8 |
"""
|
|
Packit |
130fc8 |
return Bus.__new__(cls, Bus.TYPE_STARTER, private=private,
|
|
Packit |
130fc8 |
mainloop=mainloop)
|