예제 #1
0
class OdsBase(dbus.proxies.Interface, GObject.GObject):
    # def OdsMethod(fn):
    #		def new(self, *args, **kwargs):

    #			fn(self, *args, **kwargs)
    #			getattr(super(OdsBase,self), fn.__name__)(*args, **kwargs)
    #		return new

    def __init__(self, service_name, obj_path):
        self.bus = dbus.SessionBus()
        self._signals = SignalTracker()

        service = self.bus.get_object("org.openobex", obj_path)
        GObject.GObject.__init__(self)
        dbus.proxies.Interface.__init__(self, service, service_name)

    def DisconnectAll(self):
        self._signals.DisconnectAll()

    def Handle(self, signame, handler):
        self._signals.Handle("dbus", self.bus, handler, signame,
                             self.dbus_interface, None, self.object_path)

    def GHandle(self, *args):
        self._signals.Handle("gobject", self, *args)
예제 #2
0
class GameControllerWakelock(AppletPlugin):
    __description__ = _("Temporarily suspends the screensaver when a bluetooth game controller is connected.")
    __author__ = "bwRavencl"
    __icon__ = "input-gaming"

    def on_load(self, applet):
        self.wake_lock = 0
        self.root_window_id = "0x%x" % Gdk.Screen.get_default().get_root_window().get_xid()

        self.signals = SignalTracker()
        self.signals.Handle("bluez", bluez.Device(), self.on_device_property_changed, "PropertyChanged", path_keyword="path")

    def on_unload(self):
        if self.wake_lock:
            self.wake_lock = 1
            self.suspend_screensaver("resume")
        self.signals.DisconnectAll()

    def on_device_property_changed(self, key, value, path):
        if key == "Connected":
            klass = Device(path).get_properties()["Class"] & 0x1fff

            if klass == 0x504 or klass == 0x508:
                if value:
                    self.xdg_screensaver("suspend")
                else:
                    self.xdg_screensaver("resume")

    def xdg_screensaver(self, action):
        if action == "resume":
            if self.wake_lock == 0:
                pass
            elif self.wake_lock > 1:
                self.wake_lock -= 1
                pass
        elif action == "suspend" and self.wake_lock >= 1:
             self.wake_lock += 1
             pass

        command = ["xdg-screensaver", action, self.root_window_id]

        try:
            process = subprocess.Popen(command, stderr=subprocess.PIPE)
            _, stderr = process.communicate()

            if process.returncode != 0:
                dprint(" ".join(command) + " failed with: " + stderr)
                pass

            if action == "suspend":
                self.wake_lock += 1
            elif action == "resume":
                self.wake_lock = 0
        except:
            dprint(traceback.format_exc())
예제 #3
0
class NMMonitor(MonitorBase):
    def __init__(self, device, nm_dev_path):
        MonitorBase.__init__(self, device, "NM")
        dprint("created nm monitor for path", nm_dev_path)
        self.signals = SignalTracker()
        self.signals.Handle("dbus",
                            dbus.SystemBus(),
                            self.on_ppp_stats,
                            "PppStats",
                            "org.freedesktop.NetworkManager.Device.Serial",
                            path=nm_dev_path)

        self.signals.Handle(device, "property-changed", self.on_device_property_changed)

    def on_ppp_stats(self, rx, tx):
        self.update_stats(tx, rx)

    def on_device_property_changed(self, device, key, value):
        if key == "Connected" and not value:
            self.signals.DisconnectAll()
            self.Disconnect()
예제 #4
0
class Device(GObject.GObject):
    __gsignals__ = {
        str('invalidated'): (GObject.SignalFlags.NO_HOOKS, None, ()),
        str('property-changed'): (GObject.SignalFlags.NO_HOOKS, None, (
            GObject.TYPE_PYOBJECT,
            GObject.TYPE_PYOBJECT,
        )),
    }

    def __init__(self, instance):
        GObject.GObject.__init__(self)

        self.Properties = {}
        self.Fake = True
        self.Temp = False

        if hasattr(instance, "format") and hasattr(instance, "upper"):
            self.Device = BluezDevice(instance)
        else:
            self.Device = instance

        #set fallback icon, fixes lp:#327718
        self.Device.Icon = "blueman"
        self.Device.Class = "unknown"
        self.Device.Appearance = 0

        self.Valid = True

        self.Signals = SignalTracker()

        dprint("caching initial properties")
        self.Properties = self.Device.get_properties()

        if not "Fake" in self.Properties:
            self.Fake = False

        w = weakref.ref(self)
        if not self.Fake:
            self._obj_path = self.Device.get_object_path()
            self.Signals.Handle(
                "bluez", self.Device,
                lambda key, value: w() and w().property_changed(key, value),
                "PropertyChanged")
            object_path = self.Device.get_object_path()
            adapter = Adapter(
                object_path.replace("/" + os.path.basename(object_path), ""))
            self.Signals.Handle(
                "bluez", adapter,
                lambda path: w() and w().on_device_removed(path),
                "DeviceRemoved")

    def get_service(self, uuid):
        for name, cls in inspect.getmembers(blueman.services, inspect.isclass):
            if uuid128_to_uuid16(uuid) == cls.__svclass_id__:
                return cls(self, uuid)

    def get_services(self):
        if self.Fake:
            return []
        services = (self.get_service(uuid) for uuid in self.UUIDs)
        return [service for service in services if service]

    def __del__(self):
        dprint("deleting device", self.get_object_path())
        self.Destroy()

    def get_object_path(self):
        if not self.Fake:
            return self._obj_path

    def on_device_removed(self, path):
        if path == self._obj_path:
            self.emit("invalidated")
            self.Destroy()

    def Copy(self):
        if not self.Valid:
            raise Exception("Attempted to copy an invalidated device")
        return Device(self.Device)

    def property_changed(self, key, value):
        self.emit("property-changed", key, value)
        self.Properties[key] = value

    def Destroy(self):
        dprint("invalidating device", self.get_object_path())
        self.Valid = False
        #self.Device = None
        self.Signals.DisconnectAll()

    #def __del__(self):
    #	dprint("DEBUG: deleting Device instance")

    def get_properties(self):
        #print "Properties requested"
        if not self.Valid:
            raise Exception(
                "Attempted to get properties for an invalidated device")
        return self.Properties

    def __getattr__(self, name):
        if name in self.__dict__["Properties"]:
            if not self.Valid:
                #traceback.print_stack()
                dprint(
                    "Warning: Attempted to get %s property for an invalidated device"
                    % name)
            return self.__dict__["Properties"][name]
        else:
            return getattr(self.Device, name)

    def __setattr__(self, key, value):
        if not key in self.__dict__ and "Properties" in self.__dict__ and key in self.__dict__[
                "Properties"]:
            if not self.Valid:
                raise Exception(
                    "Attempted to set properties for an invalidated device")
            dprint("Setting property", key, value)
            self.__dict__["Device"].set(key, value)
        else:
            self.__dict__[key] = value
예제 #5
0
class Networking(AppletPlugin):
    __icon__ = "network"
    __description__ = _("Manages local network services, like NAP bridges")
    __author__ = "Walmis"

    def on_load(self, applet):
        self.Applet = applet
        self.Signals = SignalTracker()

        self.Config = Config("org.blueman.network")
        self.Signals.Handle("gobject", self.Config, "changed",
                            self.on_config_changed)

        self.load_nap_settings()

    def on_manager_state_changed(self, state):
        if state:
            self.update_status()

    def load_nap_settings(self):
        dprint("Loading NAP settings")

        def reply():
            pass

        def err(excp):
            d = NetworkErrorDialog(
                excp,
                "You might not be able to connect to the Bluetooth network via this machine"
            )
            d.expander.props.margin_left = 9

            d.run()
            d.destroy()

        m = Mechanism()
        m.ReloadNetwork(reply_handler=reply, error_handler=err)

    def on_unload(self):
        self.Signals.DisconnectAll()

    def on_adapter_added(self, path):
        self.update_status()

    def update_status(self):
        self.set_nap(self.Config["nap-enable"])

    def on_config_changed(self, config, key):
        if key == "nap-enable":
            self.set_nap(config[key])

    def set_nap(self, on):
        dprint("set nap", on)
        if self.Applet.Manager != None:
            adapters = self.Applet.Manager.list_adapters()
            for adapter in adapters:
                s = NetworkServer(adapter.get_object_path())
                if on:
                    s.register("nap", "pan1")
                else:
                    s.unregister("nap")
예제 #6
0
class KillSwitch(AppletPlugin):
    __author__ = "Walmis"
    __description__ = _(
        "Toggles a platform Bluetooth killswitch when Bluetooth power state changes. Useless with USB dongles."
    )
    __depends__ = ["PowerManager", "StatusIcon"]
    __icon__ = "system-shutdown"
    __options__ = {"checked": {"type": bool, "default": False}}

    def on_load(self, applet):
        self.signals = SignalTracker()

        try:
            self.Manager = KillSwitchNG()
            self.signals.Handle(self.Manager, "switch-changed",
                                self.on_switch_changed)
            dprint("Using the new killswitch system")
        except OSError as e:
            dprint("Using the old killswitch system, reason:", e)
            if _KillSwitch is None:
                raise Exception("Failed to initialize killswitch manager")
            else:
                self.Manager = _KillSwitch.Manager()

            if not self.get_option("checked"):
                GObject.timeout_add(1000, self.check)

        self.signals.Handle(self.Manager, "switch-added", self.on_switch_added)
        self.signals.Handle(self.Manager, "switch-removed",
                            self.on_switch_removed)

    def on_switch_added(self, manager, switch):
        if switch.type == RFKillType.BLUETOOTH:
            dprint("killswitch registered", switch.idx)
        #			if manager.HardBlocked:
        #				self.Applet.Plugins.PowerManager.SetPowerChangeable(False)
        #
        #			if not self.Manager.GetGlobalState():
        #				self.Applet.Plugins.PowerManager.SetBluetoothStatus(False)
        #
        #			pm_state = self.Applet.Plugins.PowerManager.GetBluetoothStatus()
        #			if self.Manager.GetGlobalState() != pm_state:
        #				self.Manager.SetGlobalState(pm_state)

    def on_switch_changed(self, manager, switch):
        if switch.type == RFKillType.BLUETOOTH:
            s = manager.GetGlobalState()
            dprint("Global state:", s, "\nswitch.soft:", switch.soft,
                   "\nswitch.hard:", switch.hard)
            self.Applet.Plugins.PowerManager.UpdatePowerState()
            self.Applet.Plugins.StatusIcon.QueryVisibility()

    def on_switch_removed(self, manager, switch):
        if switch.type == RFKillType.BLUETOOTH:
            if len(manager.devices) == 0:
                self.Applet.Plugins.StatusIcon.QueryVisibility()

    def on_power_state_query(self, manager):
        if self.Manager.HardBlocked:
            return manager.STATE_OFF_FORCED
        else:
            dprint(self.Manager.GetGlobalState())
            if self.Manager.GetGlobalState():
                return manager.STATE_ON
            else:
                return manager.STATE_OFF

    def check(self):
        try:
            if len(self.Manager.devices) == 0:
                self.set_option("checked", True)
                #this machine does not support bluetooth killswitch, let's unload
                self.Applet.Plugins.SetConfig("KillSwitch", False)
        except:
            pass

    def on_power_state_change_requested(self, manager, state, cb):
        dprint(state)

        def reply(*_):
            cb(True)

        def error(*_):
            cb(False)

        if not self.Manager.HardBlocked:
            self.Manager.SetGlobalState(state,
                                        reply_handler=reply,
                                        error_handler=error)
        else:
            cb(True)

    def on_unload(self):
        self.signals.DisconnectAll()

    def on_query_status_icon_visibility(self):
        if self.Manager.HardBlocked:
            return 1

        state = self.Manager.GetGlobalState()
        if state:
            if isinstance(self.Manager, KillSwitchNG) and len(
                    self.Manager.devices) > 0 and self.Applet.Manager:
                return 2

            return 1  # StatusIcon.SHOW
        elif len(self.Manager.devices) > 0 and not state:
            #if killswitch removes the bluetooth adapter, dont hide the statusicon,
            #so that the user could turn bluetooth back on.
            return 2  # StatusIcon.FORCE_SHOW

        return 1
예제 #7
0
class DhcpClient(AppletPlugin):
    __description__ = _(
        "Provides a basic dhcp client for Bluetooth PAN connections.")
    __icon__ = "network"
    __author__ = "Walmis"
    __priority__ = 3

    def on_load(self, applet):
        self.Signals = SignalTracker()

        self.add_dbus_method(self.DhcpClient, in_signature="s")

        self.Signals.Handle("dbus",
                            dbus.SystemBus(),
                            self.on_network_prop_changed,
                            "PropertyChanged",
                            "org.bluez.Network",
                            path_keyword="path")

        self.quering = []

    def on_unload(self):
        self.Signals.DisconnectAll()

    def DhcpClient(self, interface):
        self.dhcp_acquire(interface)

    def on_network_prop_changed(self, key, value, path):
        if key == "Interface":
            if value != "":
                self.dhcp_acquire(value)

    def dhcp_acquire(self, device):
        if device not in self.quering:
            self.quering.append(device)
        else:
            return

        if device != "":

            def reply(ip_address):

                Notification(_("Bluetooth Network"),
                             _("Interface %(0)s bound to IP address %(1)s") % {
                                 "0": device,
                                 "1": ip_address
                             },
                             pixbuf=get_icon("gtk-network", 48),
                             status_icon=self.Applet.Plugins.StatusIcon)

                self.quering.remove(device)

            def err(msg):
                dprint(msg)
                Notification(_("Bluetooth Network"),
                             _("Failed to obtain an IP address on %s") %
                             (device),
                             pixbuf=get_icon("gtk-network", 48),
                             status_icon=self.Applet.Plugins.StatusIcon)

                self.quering.remove(device)

            Notification(
                _("Bluetooth Network"),
                _("Trying to obtain an IP address on %s\nPlease wait..." %
                  device),
                pixbuf=get_icon("gtk-network", 48),
                status_icon=self.Applet.Plugins.StatusIcon)

            m = Mechanism()
            m.DhcpClient(device,
                         reply_handler=reply,
                         error_handler=err,
                         timeout=120)
예제 #8
0
class NMMonitor(AppletPlugin, GObject.GObject):
    __gsignals__ = {
        #args: udi
        'disconnected':
        (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_STRING, )),
        #args: udi
        'modem-removed':
        (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_STRING, )),
        #args: udi, bdaddr
        'modem-added': (GObject.SignalFlags.NO_HOOKS, None, (
            GObject.TYPE_STRING,
            GObject.TYPE_STRING,
        )),
    }

    __icon__ = "network"
    __description__ = _(
        "Monitors NetworkManager's modem connections and automatically disconnects Bluetooth link after the network connection is closed"
    )
    __author__ = "Walmis"

    def on_load(self, applet):
        GObject.GObject.__init__(self)

        self.bus = dbus.SystemBus()
        obj = self.bus.get_object('org.freedesktop.Hal',
                                  '/org/freedesktop/Hal/Manager')

        self.hal_mgr = dbus.Interface(obj, 'org.freedesktop.Hal.Manager')

        self.monitored_udis = []

        self.signals = SignalTracker()

        self.signals.Handle("dbus",
                            self.bus,
                            self.on_device_state_changed,
                            "StateChanged",
                            "org.freedesktop.NetworkManager.Device",
                            path_keyword="udi")
        self.signals.Handle("dbus", self.bus, self.on_device_added,
                            "DeviceAdded", "org.freedesktop.Hal.Manager")
        self.signals.Handle("dbus", self.bus, self.on_device_removed,
                            "DeviceRemoved", "org.freedesktop.Hal.Manager")
#		self.signals.Handle("bluez", device.Device, self.on_device_propery_changed, "PropertyChanged")

    def on_unload(self):
        self.signals.DisconnectAll()

    def on_device_removed(self, udi):
        if udi in self.monitored_udis:
            self.monitored_udis.remove(udi)
            self.emit("modem-removed", udi)

    def on_device_added(self, udi):
        obj = self.bus.get_object('org.freedesktop.Hal', udi)
        device = dbus.Interface(obj, 'org.freedesktop.Hal.Device')
        try:
            if device.QueryCapability("modem") and device.GetPropertyString(
                    "info.linux.driver") == "rfcomm":
                self.monitored_udis.append(udi)
                self.emit("modem-added", udi,
                          device.GetPropertyString("info.bluetooth_address"))
        except:
            pass

    def on_device_state_changed(self, state, prev_state, reason, udi):
        if udi in self.monitored_udis:
            dprint("state=%u prev_state=%u reason=%u" %
                   (state, prev_state, reason))
            if state <= 3 and 3 < prev_state <= 8:
                self.emit("disconnected", udi)
예제 #9
0
class ConnectionHandler:
    def __init__(self, parent, device, uuid, reply, err):
        self.parent = parent
        self.device = device
        self.uuid = uuid
        self.reply = reply
        self.err = err
        self.rfcomm_dev = None
        self.timeout = None

        self.signals = SignalTracker()
        self.signals.Handle("dbus", self.parent.bus, self.on_mm_device_added,
                            "DeviceAdded", "org.freedesktop.ModemManager")

        #for some reason these handlers take a reference and don't give it back
        #so i have to workaround :(
        w = weakref.ref(self)
        device.Services["serial"].Connect(
            uuid,
            reply_handler=lambda *args: w() and w().on_connect_reply(*args),
            error_handler=lambda *args: w() and w().on_connect_error(*args))

    def __del__(self):
        dprint("deleting")

    def on_connect_reply(self, rfcomm):
        self.rfcomm_dev = rfcomm
        self.timeout = gobject.timeout_add(10000, self.on_timeout)

    def on_connect_error(self, *args):
        self.err(*args)
        self.cleanup()

    def cleanup(self):
        if self.timeout:
            gobject.source_remove(self.timeout)
        self.signals.DisconnectAll()

        del self.device

    def on_mm_device_added(self, path):
        dprint(path)
        props = self.parent.bus.call_blocking(
            "org.freedesktop.ModemManager", path,
            "org.freedesktop.DBus.Properties", "GetAll", "s",
            ["org.freedesktop.ModemManager.Modem"])

        if self.rfcomm_dev and props["Driver"] == "bluetooth" and props[
                "Device"] in self.rfcomm_dev:
            dprint("It's our bluetooth modem!")

            modem = get_icon("modem", 24)
            blueman = get_icon("blueman", 48)

            icon = composite_icon(blueman, [(modem, 24, 24, 255)])

            Notification(
                _("Bluetooth Dialup"),
                _("DUN connection on %s will now be available in Network Manager"
                  ) % self.device.Alias,
                pixbuf=icon,
                status_icon=self.parent.Applet.Plugins.StatusIcon)

            self.reply(self.rfcomm_dev)
            self.cleanup()

    def on_timeout(self):
        self.timeout = None
        self.err(
            dbus.DBusException(
                _("Modem Manager did not support the connection")))
        self.cleanup()
예제 #10
0
class NewConnectionBuilder:
    DEVICE_STATE_DISCONNECTED = 30
    DEVICE_STATE_ACTIVATED = 100
    DEVICE_STATE_DEACTIVATING = 110
    DEVICE_STATE_FAILED = 120

    def __init__(self, parent, service, ok_cb, err_cb):
        self.parent = parent
        self.ok_cb = ok_cb
        self.err_cb = err_cb

        self.signals = SignalTracker()

        self.device = None
        self.connection = None

        self.signals.Handle("dbus", parent.bus, self.on_nm_device_added,
                            "DeviceAdded", "org.freedesktop.NetworkManager")
        self.signals.Handle("dbus", parent.bus, self.on_nma_new_connection,
                            "NewConnection", self.parent.settings_interface)

        self.device = self.parent.find_device(service.device.Address)

        self.connection = self.parent.find_connection(service.device.Address,
                                                      "panu")
        if not self.connection:
            # This is for compatibility with network-manager < 0.9.8.6. Newer versions that support BlueZ 5 add a
            # default connection automatically
            addr_bytes = bytearray.fromhex(
                str.replace(str(service.device.Address), ':', ' '))
            parent.nma.AddConnection({
                'connection': {
                    'id': '%s on %s' % (service.name, service.device.Alias),
                    'uuid': str(uuid1()),
                    'autoconnect': False,
                    'type': 'bluetooth'
                },
                'bluetooth': {
                    'bdaddr': dbus.ByteArray(addr_bytes),
                    'type': 'panu'
                },
                'ipv4': {
                    'method': 'auto'
                },
                'ipv6': {
                    'method': 'auto'
                }
            })
            GObject.timeout_add(1000, self.signal_wait_timeout)
        else:
            self.init_connection()

    def cleanup(self):
        self.signals.DisconnectAll()

    def signal_wait_timeout(self):
        if not self.device or not self.connection:
            self.err_cb(
                dbus.DBusException(
                    "Network Manager did not support the connection"))
            if self.connection:
                self.remove_connection()
            self.cleanup()

    def on_nm_device_added(self, path):
        dprint(path)
        self.device = path
        if self.device and self.connection:
            self.init_connection()

    def on_nma_new_connection(self, path):
        dprint(path)
        self.connection = path
        if self.device and self.connection:
            self.init_connection()

    def init_connection(self):
        self.cleanup()
        dprint("activating", self.connection, self.device)
        if not self.device or not self.connection:
            self.err_cb(
                dbus.DBusException(
                    "Network Manager did not support the connection"))
            if self.connection:
                self.remove_connection()
            self.cleanup()
        else:
            self.signals.Handle("dbus",
                                self.parent.bus,
                                self.on_device_state,
                                "StateChanged",
                                "org.freedesktop.NetworkManager.Device",
                                path=self.device)

            args = [self.connection, self.device, self.connection]

            if self.parent.legacy:
                args.insert(0, self.parent.settings_bus)

            self.parent.nm.ActivateConnection(*args)

    def remove_connection(self):
        self.parent.remove_connection(self.connection)

    def on_device_state(self, state, oldstate, reason):
        dprint("state=", state, "oldstate=", oldstate, "reason=", reason)
        if (state <= self.DEVICE_STATE_DISCONNECTED or state == self.DEVICE_STATE_DEACTIVATING) and \
                                self.DEVICE_STATE_DISCONNECTED < oldstate <= self.DEVICE_STATE_ACTIVATED:
            if self.err_cb:
                self.err_cb(dbus.DBusException("Connection was interrupted"))

            self.remove_connection()
            self.cleanup()

        elif state == self.DEVICE_STATE_FAILED:
            self.err_cb(
                dbus.DBusException(
                    "Network Manager Failed to activate the connection"))
            self.remove_connection()
            self.cleanup()

        elif state == self.DEVICE_STATE_ACTIVATED:
            self.ok_cb()
            self.err_cb = None
            self.ok_cb = None
예제 #11
0
class NMPANSupport(AppletPlugin):
	__depends__ = ["DBusService"]
	__conflicts__ = ["DhcpClient", "NMIntegration"]
	__icon__ = "network"
	__author__ = "Walmis"
	__description__ = _("Provides support for Personal Area Networking (PAN) introduced in NetworkManager 0.8")
	__priority__ = 2
	
	def on_load(self, applet):
		self.bus = dbus.SystemBus()
		self.nma = None
		self.nm = None
		self.nm_signals = SignalTracker()
		self.nma_signals = SignalTracker()
		
		self.watch1 = self.bus.watch_name_owner("org.freedesktop.NetworkManagerUserSettings", self.on_nma_owner_changed)
		self.watch2 = self.bus.watch_name_owner("org.freedesktop.NetworkManager", self.on_nm_owner_changed)
		
		self.client = gconf.client_get_default ()
		
	def set_gconf(self, key, value):
		func = None
	
		if type(value) == str or type(value) == unicode:
			func = self.client.set_string
		elif type(value) == int:
			func = self.client.set_int
		elif type(value) == bool:
			func = self.client.set_bool
		elif type(value) == float:
			func = self.client.set_float
		elif type(value) == list:
			def x(key, val):
				self.client.set_list(key, gconf.VALUE_STRING, val)
			func = x
			
		elif type(value) == dbus.Array:
			if value.signature == "i":
				def x(key, val):
					self.client.set_list(key, gconf.VALUE_INT, val)
				func = x
			elif value.signature == "s":
				def x(key, val):
					self.client.set_list(key, gconf.VALUE_STRING, val)
				func = x
			else:
				raise AttributeError("Cant set this type in gconf")							
			
		else:
			raise AttributeError("Cant set %s in gconf" % type(value))
			
		func(key, value)
	
	def find_free_gconf_slot(self):
		dirs = list(self.client.all_dirs ("/system/networking/connections"))
		dirs.sort()
		
		i = 1
		for d in dirs:
			try:
				d = int(os.path.basename(d))
			except:
				continue
			if d != i:
				return i
			
			i+=1
			
		return i
		
	def add_connection(self, params):
		slot = self.find_free_gconf_slot()
		
		base_path = "/system/networking/connections/%d" % slot
		
		for group, settings in params.iteritems():
			path = base_path + "/%s" % group
			for k, v in settings.iteritems():
				key = path + "/%s" % k
				self.set_gconf(key, v)
				
	def remove_connection(self, path):
		self.bus.call_blocking("org.freedesktop.NetworkManagerUserSettings", path, "org.freedesktop.NetworkManagerSettings.Connection", "Delete", "", [])	
				
	def format_bdaddr(self, addr):
		return "%02X:%02X:%02X:%02X:%02X:%02X" % (addr[0], addr[1], addr[2], addr[3], addr[4], addr[5])

	
	def find_device(self, bdaddr):
		devices = self.nm.GetDevices()
		for dev in devices:
			try:
				d = self.bus.call_blocking("org.freedesktop.NetworkManager", dev, "org.freedesktop.DBus.Properties", "GetAll", "s", ["org.freedesktop.NetworkManager.Device.Bluetooth"])	
				if d["HwAddress"] == bdaddr:
					dprint(d["HwAddress"])
					return dev
						
			except dbus.DBusException:
				pass	
							
	def find_connection(self, address, t):
		conns = self.nma.ListConnections()
		for conn in conns:
			c = self.bus.call_blocking("org.freedesktop.NetworkManagerUserSettings", conn, "org.freedesktop.NetworkManagerSettings.Connection", "GetSettings", "", [])
			try:
				if (self.format_bdaddr(c["bluetooth"]["bdaddr"]) == address) and c["bluetooth"]["type"] == t:
					return conn
			except:
				pass
				
	def find_active_connection(self, address, type):
		props = self.bus.call_blocking("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.DBus.Properties", "GetAll", "s", ["org.freedesktop.NetworkManager"])			
		
		nma_connection = self.find_connection(address, type)
		if nma_connection:
			active_conns = props["ActiveConnections"]
			for conn in active_conns:
				conn_props = self.bus.call_blocking("org.freedesktop.NetworkManager", 
								    conn, 
								    "org.freedesktop.DBus.Properties", 
								    "GetAll", 
								    "s", 
								    ["org.freedesktop.NetworkManager.Connection.Active"])	
								    
				if conn_props["Connection"] == nma_connection:
					return conn	
				
	def on_nma_owner_changed(self, owner):
		if owner == "":
			self.nma = None
		else:
			service = self.bus.get_object("org.freedesktop.NetworkManagerUserSettings", "/org/freedesktop/NetworkManagerSettings")
			self.nma = dbus.proxies.Interface(service, "org.freedesktop.NetworkManagerSettings")		
			
	def on_nm_owner_changed(self, owner):
		if owner == "":
			self.nm = None
			self.nm_signals.DisconnectAll()
		else:		
			service = self.bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
			self.nm = dbus.proxies.Interface(service, "org.freedesktop.NetworkManager")
			
		
	def on_unload(self):
		self.nm_signals.DisconnectAll()
		self.nma_signals.DisconnectAll()
		
		self.watch1.cancel()
		self.watch2.cancel()
		
	def service_connect_handler(self, interface, object_path, method, args, ok, err):
		if interface == "org.bluez.Network" and method == "Connect":
			uuid = args[0]
			name = uuid16_to_name(uuid128_to_uuid16(uuid))
			d = Device(object_path)
			
			conn = self.find_active_connection(d.Address, "panu")
			if conn:
				err(dbus.DBusException(_("Already connected")))
			else:
				params = {}
				params["bluetooth"] = {"name": "bluetooth", "bdaddr":  str(d.Address), "type" : "panu"}
				params["connection"] = {"autoconnect": False, "id": str("%s on %s") % (name, d.Alias), "uuid" : str(uuid1()), "type": "bluetooth"}
				params['ipv4'] = {'addresses': dbus.Array([], dbus.Signature("i")), 'dns': dbus.Array([], dbus.Signature("i")), "method": "auto", "routes": dbus.Array([], dbus.Signature("i"))}		
			
				NewConnectionBuilder(self, params, ok, err)
				
			return True
			
		elif interface == "org.bluez.Network" and method == "Disconnect":
			d = Device(object_path)
			active_conn_path = self.find_active_connection(d.Address, "panu")
			if active_conn_path:
				self.bus.call_blocking("org.freedesktop.NetworkManager", 
						       "/org/freedesktop/NetworkManager", 
						       "org.freedesktop.NetworkManager", 
						       "DeactivateConnection", 
						       "o", 
						       [active_conn_path])
				ok()		       	
				return True
예제 #12
0
class PowerManager(AppletPlugin):
    __depends__ = ["StatusIcon", "Menu"]
    __unloadable__ = True
    __description__ = _("Controls Bluetooth adapter power states")
    __author__ = "Walmis"
    __icon__ = "gnome-power-manager"

    def on_load(self, applet):
        AppletPlugin.add_method(self.on_power_state_query)
        AppletPlugin.add_method(self.on_power_state_change_requested)
        AppletPlugin.add_method(self.on_power_state_changed)

        self.add_dbus_method(self.SetBluetoothStatus,
                             in_signature="b",
                             out_signature="")

        self.add_dbus_method(self.GetBluetoothStatus,
                             in_signature="",
                             out_signature="b")

        self.BluetoothStatusChanged = self.add_dbus_signal(
            "BluetoothStatusChanged", signature="b")

        self.Applet = applet

        self.item = create_menuitem(_("<b>Bluetooth Off</b>"),
                                    get_icon("gtk-stop", 16))
        self.item.get_child().set_markup(_("<b>Turn Bluetooth Off</b>"))

        self.item.props.tooltip_text = _("Turn off all adapters")

        self.signals = SignalTracker()
        self.signals.Handle("dbus",
                            dbus.SystemBus(),
                            self.adapter_property_changed,
                            "PropertyChanged",
                            "org.bluez.Adapter",
                            "org.bluez",
                            path_keyword="path")

        self.signals.Handle(self.item, "activate",
                            lambda x: self.on_bluetooth_toggled())

        self.Applet.Plugins.Menu.Register(self, self.item, 0)

        self.adapter_state = True
        self.current_state = True
        self.power_changeable = True

        self.request_in_progress = False

        self.STATE_ON = 2
        self.STATE_OFF = 1
        self.STATE_OFF_FORCED = 0

    def on_unload(self):
        self.signals.DisconnectAll()
        self.Applet.Plugins.Menu.Unregister(self)

    @property
    def CurrentState(self):
        return self.current_state

    def on_manager_state_changed(self, state):
        if state:

            def timeout():
                self.adapter_state = self.get_adapter_state()
                self.RequestPowerState(self.adapter_state)

            gobject.timeout_add(1000, timeout)

    def get_adapter_state(self):
        adapters = self.Applet.Manager.ListAdapters()
        for adapter in adapters:
            props = adapter.GetProperties()
            if not props["Powered"]:
                return False
        return bool(adapters)

    def set_adapter_state(self, state):
        try:
            dprint(state)
            adapters = self.Applet.Manager.ListAdapters()
            for adapter in adapters:
                adapter.SetProperty("Powered", state)

            self.adapter_state = state
        except Exception as e:
            dprint("Exception occurred", e)

    class Callback(object):
        def __init__(self, parent, state):
            self.parent = parent
            self.num_cb = 0
            self.called = 0
            self.state = state
            self.success = False
            self.timer = gobject.timeout_add(5000, self.timeout)

        def __call__(self, result):
            self.called += 1

            if result:
                self.success = True

            self.check()

        def check(self):
            if self.called == self.num_cb:
                dprint("callbacks done")
                self.parent.set_adapter_state(self.state)
                gobject.source_remove(self.timer)
                self.parent.request_in_progress = False

        def timeout(self):
            dprint("Timeout reached while setting power state")
            self.parent.UpdatePowerState()
            self.parent.request_in_progress = False

    def RequestPowerState(self, state):
        if self.current_state != state:
            if not self.request_in_progress:
                self.request_in_progress = True
                dprint("Requesting", state)
                cb = PowerManager.Callback(self, state)

                rets = self.Applet.Plugins.Run(
                    "on_power_state_change_requested", self, state, cb)
                cb.num_cb = len(rets)
                cb.check()
                self.UpdatePowerState()
            else:
                dprint("Another request in progress")

    def on_power_state_change_requested(self, pm, state, cb):
        cb(None)

    def on_power_state_query(self, pm):
        if self.adapter_state:
            return self.STATE_ON
        else:
            return self.STATE_OFF

    def on_power_state_changed(self, manager, state):
        pass

    #queries other plugins to determine the current power state
    def UpdatePowerState(self):
        rets = self.Applet.Plugins.Run("on_power_state_query", self)

        off = True in map(lambda x: x < self.STATE_ON, rets)
        foff = self.STATE_OFF_FORCED in rets
        on = self.STATE_ON in rets

        new_state = True
        if foff or off:

            self.item.get_child().set_markup(_("<b>Turn Bluetooth On</b>"))
            self.item.props.tooltip_text = _("Turn on all adapters")
            self.item.set_image(
                gtk.image_new_from_pixbuf(get_icon("gtk-yes", 16)))

            if foff:
                self.item.props.sensitive = False
            else:
                self.item.props.sensitive = True

            new_state = False

        elif on and self.current_state != True:
            self.item.get_child().set_markup(_("<b>Turn Bluetooth Off</b>"))
            self.item.props.tooltip_text = _("Turn off all adapters")
            self.item.set_image(
                gtk.image_new_from_pixbuf(get_icon("gtk-stop", 16)))
            self.item.props.sensitive = True

            new_state = True

        dprint("off", off, "\nfoff", foff, "\non", on, "\ncurrent state",
               self.current_state, "\nnew state", new_state)

        if self.current_state != new_state:
            dprint("Signalling", new_state)
            self.current_state = new_state

            self.BluetoothStatusChanged(new_state)
            self.Applet.Plugins.Run("on_power_state_changed", self, new_state)
            self.Applet.Plugins.StatusIcon.IconShouldChange()

    #dbus method
    def SetBluetoothStatus(self, status):
        self.RequestPowerState(status)

    #dbus method
    def GetBluetoothStatus(self):
        return self.CurrentState

    def adapter_property_changed(self, key, value, path):
        if key == "Powered":
            if value and not self.CurrentState:
                dprint(
                    "adapter powered on while in off state, turning bluetooth on"
                )
                self.RequestPowerState(True)

            self.UpdatePowerState()

    def on_bluetooth_toggled(self):
        self.RequestPowerState(not self.CurrentState)

    def on_status_icon_query_icon(self):
        #opacity = 255 if self.GetBluetoothStatus() else 100
        #pixbuf = opacify_pixbuf(pixbuf, opacity)

        #if opacity < 255:
        #	x_size = int(pixbuf.props.height)
        #	x = get_icon("blueman-x", x_size)
        #	pixbuf = composite_icon(pixbuf, [(x, pixbuf.props.height - x_size, pixbuf.props.height - x_size, 255)])

        #return pixbuf
        if not self.GetBluetoothStatus():
            return ("blueman-tray-disabled", "bluetooth-disabled")

    def on_adapter_added(self, path):
        adapter = Bluez.Adapter(path)

        def on_ready():
            if not self.adapter_state:
                adapter.SetProperty("Powered", False)
            else:
                adapter.SetProperty("Powered", True)

        wait_for_adapter(adapter, on_ready)
예제 #13
0
class SerialManager(AppletPlugin):
    __icon__ = "blueman-serial"
    __author__ = "Walmis"
    __description__ = _(
        "Standard SPP profile connection handler, allows executing custom actions"
    )
    __author__ = "walmis"
    __options__ = {
        "script": {
            "type":
            str,
            "default":
            "",
            "name":
            _("Script to execute on connection"),
            "desc":
            _("<span size=\"small\">The following arguments will be passed:\n"
              "Address, Name, service name, uuid16s, rfcomm node\n"
              "For example:\n"
              "AA:BB:CC:DD:EE:FF, Phone, DUN service, 0x1103, /dev/rfcomm0\n"
              "uuid16s are returned as a comma seperated list\n\n"
              "Upon device disconnection the script will be sent a HUP signal</span>"
              )
        },
    }

    def on_load(self, applet):
        self.signals = SignalTracker()
        self.signals.Handle("dbus",
                            dbus.SystemBus(),
                            self.on_device_property_changed,
                            "PropertyChanged",
                            "org.bluez.Device",
                            path_keyword="path")

        self.scripts = {}

    def on_unload(self):
        self.signals.DisconnectAll()
        for k in self.scripts.iterkeys():
            self.terminate_all_scripts(k)

    def on_device_property_changed(self, key, value, path):
        if key == "Connected" and not value:
            d = Device(path)
            self.terminate_all_scripts(d.Address)

    def on_rfcomm_connected(self, device, port, uuid):
        uuid16 = sdp_get_serial_type(device.Address, uuid)
        if SERIAL_PORT_SVCLASS_ID in uuid16:
            Notification(
                _("Serial port connected"),
                _("Serial port service on device <b>%s</b> now will be available via <b>%s</b>"
                  ) % (device.Alias, port),
                pixbuf=get_icon("blueman-serial", 48),
                status_icon=self.Applet.Plugins.StatusIcon)

            self.call_script(device.Address, device.Alias,
                             sdp_get_serial_name(device.Address, uuid), uuid16,
                             port)

    def terminate_all_scripts(self, address):
        try:
            for p in self.scripts[address].itervalues():
                dprint("Sending HUP to", p.pid)
                os.killpg(p.pid, signal.SIGHUP)
        except:
            pass

    def on_script_closed(self, pid, cond, (address, node)):
        del self.scripts[address][node]
        dprint("Script with PID", pid, "closed")
예제 #14
0
class DeviceList(GenericList):
    __gsignals__ = {
        #@param: device
        'device-found': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
        #@param: device TreeIter
        #note: None None is given when there ar no more rows, or when selected device is removed
        'device-selected': (
            gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,)
        ),
        #@param: device, TreeIter, (key, value)
        #note: there is a special property "Fake", it's not a real property,
        #but it is used to notify when device changes state from "Fake" to a real BlueZ object
        #the callback would be called with Fake=False
        'device-property-changed': (
            gobject.SIGNAL_RUN_LAST,
            gobject.TYPE_NONE,
            (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,)
        ),
        #@param: adapter, (key, value)
        'adapter-property-changed': (
        gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,)),
        #@param: progress (0 to 1)
        'discovery-progress': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_FLOAT,)),

        #@param: new adapter path, None if there are no more adapters
        'adapter-changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),

        #@param: adapter path
        'adapter-added': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
        'adapter-removed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
    }

    def __del__(self):
        dprint("deleting mainlist")

    def __init__(self, adapter=None, tabledata=None):
        if not tabledata:
            tabledata = []

        def on_adapter_removed(path):
            self.emit("adapter-removed", path)
            if path == self.__adapter_path:
                self.clear()
                self.Adapter = None
                self.SetAdapter()

        def on_adapter_added(path):
            def on_activate():
                dprint("adapter powered", path)

                if self.Adapter is None:
                    self.SetAdapter(path)

                self.emit("adapter-added", path)

            a = Bluez.Adapter(path)
            wait_for_adapter(a, on_activate)

        #cache for fast lookup in the list
        self.address_to_row = {}
        self.path_to_row = {}

        self.monitored_devices = []
        self.discovered_devices = []

        self.signals = SignalTracker()

        try:
            self.Manager = Bluez.Manager("gobject")
            self.signals.Handle(self.Manager, on_adapter_removed, "AdapterRemoved")
            self.signals.Handle(self.Manager, on_adapter_added, "AdapterAdded")
        except:
            self.Manager = None

        self.__discovery_time = 0
        self.__adapter_path = None
        self.Adapter = None
        self.discovering = False

        data = []
        data = data + tabledata

        data = data + [
            ["device", object],
            ["dbus_path", str]
        ]

        GenericList.__init__(self, data)
        self.adapter_signals = SignalTracker()
        self.device_signals = SignalTracker()

        self.SetAdapter(adapter)

        self.signals.Handle(self.selection, "changed", self.on_selection_changed)

    def destroy(self):
        dprint("destroying")
        self.adapter_signals.DisconnectAll()
        self.device_signals.DisconnectAll()
        self.signals.DisconnectAll()
        self.device_signals = None
        #self.clear()
        if len(self.liststore):
            for i in self.liststore:
                iter = i.iter
                device = self.get(iter, "device")["device"]
            #device.Destroy()
        GenericList.destroy(self)

    def on_selection_changed(self, selection):
        iter = self.selected()
        if iter:
            row = self.get(iter, "device")
            dev = row["device"]
            self.emit("device-selected", dev, iter)


    def on_device_found(self, address, props):
        if self.discovering:
            dprint("Device discovered", address)

            props["Address"] = address
            props["Fake"] = True
            dev = FakeDevice(props)
            device = Device(dev)

            if not address in self.discovered_devices:
                self.emit("device-found", device)
                self.discovered_devices.append(address)

            iter = self.find_device(dev)
            if not iter:
                self.device_add_event(device)
                iter = self.find_device(device)
                self.row_update_event(iter, "RSSI", props["RSSI"])
            else:
                self.row_update_event(iter, "Alias", props["Alias"])

            print "RSSI:", props["RSSI"]


    def on_property_changed(self, key, value):
        dprint("adapter propery changed", key, value)
        if key == "Discovering":
            if not value and self.discovering:
                self.StopDiscovery()

            self.discovered_devices = []

        self.emit("adapter-property-changed", self.Adapter, (key, value))

    def on_device_property_changed(self, key, value, path, *args, **kwargs):
        dprint("list: device_prop_ch", key, value, path, args, kwargs)

        iter = self.find_device_by_path(path)

        if iter != None:
            dev = self.get(iter, "device")["device"]
            self.row_update_event(iter, key, value)

            self.emit("device-property-changed", dev, iter, (key, value))

            if key == "Connected":
                if value:
                    self.monitor_power_levels(dev)
                else:
                    r = gtk.TreeRowReference(self.props.model, self.props.model.get_path(iter))
                    self.level_setup_event(r, dev, None)

            elif key == "Paired":
                if value and dev.Temp:
                    dev.Temp = False

    def monitor_power_levels(self, device):
        def update(row_ref, cinfo, address):
            if not row_ref.valid():
                dprint("stopping monitor (row does not exist)")
                cinfo.deinit()
                self.monitored_devices.remove(props["Address"])
                return False

            if not self.props.model:
                self.monitored_devices.remove(props["Address"])
                return False

            iter = self.props.model.get_iter(row_ref.get_path())
            device = self.get(iter, "device")["device"]
            if not device.Valid or not device.Connected:
                dprint("stopping monitor (not connected)")
                cinfo.deinit()
                self.level_setup_event(row_ref, device, None)
                self.monitored_devices.remove(props["Address"])
                return False
            else:
                self.level_setup_event(row_ref, device, cinfo)
                return True


        props = device.GetProperties()

        if "Connected" in props and props["Connected"] and props["Address"] not in self.monitored_devices:
            dprint("starting monitor")
            iter = self.find_device(device)

            hci = os.path.basename(self.Adapter.GetObjectPath())
            try:
                cinfo = conn_info(props["Address"], hci)
            except:
                dprint("Failed to get power levels")
            else:
                r = gtk.TreeRowReference(self.props.model, self.props.model.get_path(iter))
                self.level_setup_event(r, device, cinfo)
                gobject.timeout_add(1000, update, r, cinfo, props["Address"])
                self.monitored_devices.append(props["Address"])

    ##### virtual funcs #####

    #called when power levels need updating
    #if cinfo is None then info icons need to be removed
    def level_setup_event(self, iter, device, cinfo):
        pass

    #called when row needs to be initialized
    def row_setup_event(self, iter, device):
        pass

    #called when a property for a device changes
    def row_update_event(self, iter, key, value):
        pass

    #called when device needs to be added to the list
    #default action: append
    def device_add_event(self, device):
        self.AppendDevice(device)

    def device_remove_event(self, device, iter):
        self.RemoveDevice(device, iter)


    #########################

    def on_device_created(self, path):
        dprint("created", path)
        iter = self.find_device_by_path(path)
        if iter == None:
            dev = Bluez.Device(path)
            dev = Device(dev)
            dev.Temp = True
            self.device_add_event(dev)


    def on_device_removed(self, path):
        iter = self.find_device_by_path(path)
        if iter:
            row = self.get(iter, "device")
            dev = row["device"]

            self.device_remove_event(dev, iter)

    def SetAdapter(self, adapter=None):
        self.clear()
        if self.discovering:
            self.emit("adapter-property-changed", self.Adapter, ("Discovering", False))
            self.StopDiscovery()

        if adapter is not None and not re.match("hci[0-9]*", adapter):
            adapter = adapter_path_to_name(adapter)

        dprint(adapter)
        if self.Adapter is not None:
            self.adapter_signals.DisconnectAll()

        try:
            self.Adapter = self.Manager.GetAdapter(adapter)
            self.adapter_signals.Handle(self.Adapter, self.on_device_found, "DeviceFound")
            self.adapter_signals.Handle(self.Adapter, self.on_property_changed, "PropertyChanged")
            self.adapter_signals.Handle(self.Adapter, self.on_device_created, "DeviceCreated")
            self.adapter_signals.Handle(self.Adapter, self.on_device_removed, "DeviceRemoved")
            self.__adapter_path = self.Adapter.GetObjectPath()

            self.emit("adapter-changed", self.__adapter_path)
        except Bluez.errors.DBusNoSuchAdapterError as e:
            dprint(e)
            #try loading default adapter
            if len(self.Manager.ListAdapters()) > 0 and adapter != None:
                self.SetAdapter()
            else:
                self.Adapter = None
                self.emit("adapter-changed", None)

        except dbus.DBusServiceUnknownError:
            dprint("Dbus error while trying to get adapter.")
            self.Adapter = None
            self.emit("adapter-changed", None)


    def update_progress(self, time, totaltime):
        if not self.discovering:
            return False

        self.__discovery_time += time

        progress = self.__discovery_time / totaltime
        if progress >= 1.0:
            progress = 1.0
        #if self.__discovery_time >= totaltime:
        #self.StopDiscovery()
        #return False

        self.emit("discovery-progress", progress)
        return True


    def add_device(self, device, append=True):
        iter = self.find_device(device)
        #device belongs to another adapter
        if not device.Fake:
            if not device.get_object_path().startswith(self.Adapter.GetObjectPath()):
                return

        if iter == None:
            dprint("adding new device")
            if append:
                iter = self.liststore.append()
            else:
                iter = self.liststore.prepend()

            self.set(iter, device=device)
            self.row_setup_event(iter, device)

            props = device.GetProperties()
            try:
                self.set(iter, dbus_path=device.GetObjectPath())
            except:
                pass

            if not "Fake" in props:
                self.device_signals.Handle("bluez", device,
                                           self.on_device_property_changed,
                                           "PropertyChanged",
                                           sigid=device.GetObjectPath(),
                                           path_keyword="path")
                if props["Connected"]:
                    self.monitor_power_levels(device)


        else:
            row = self.get(iter, "device")
            existing_dev = row["device"]

            props = existing_dev.GetProperties()
            props_new = device.GetProperties()

            #turn a Fake device to a Real device
            n = not "Fake" in props and not "Fake" in props_new
            if n:
                dprint("Updating existing dev")
                self.device_signals.Disconnect(existing_dev.GetObjectPath())
            #existing_dev.Destroy()

            if ("Fake" in props and not "Fake" in props_new) or n:
                self.set(iter, device=device, dbus_path=device.GetObjectPath())
                self.row_setup_event(iter, device)

                if not n:
                    self.emit("device-property-changed", device, iter, ("Fake", False))
                    self.row_update_event(iter, "Fake", False)

                self.device_signals.Handle("bluez", device,
                                           self.on_device_property_changed,
                                           "PropertyChanged",
                                           sigid=device.GetObjectPath(),
                                           path_keyword="path")

                if props_new["Connected"]:
                    self.monitor_power_levels(device)

            #turn a Real device to a Fake device
            elif not "Fake" in props and "Fake" in props_new:
                dprint("converting: real to discovered")
                self.set(iter, device=device, dbus_path=None)
                self.row_setup_event(iter, device)
                self.emit("device-property-changed", device, iter, ("Fake", True))
                self.row_update_event(iter, "Fake", True)


    def DisplayKnownDevices(self, autoselect=False):
        self.clear()
        devices = self.Adapter.ListDevices()
        for device in devices:
            self.device_add_event(Device(device))

        if autoselect:
            self.selection.select_path(0)

    def DiscoverDevices(self, time=10.24):
        if not self.discovering:
            self.__discovery_time = 0
            self.Adapter.StartDiscovery()
            self.discovering = True
            T = 1.0 / 15 * 1000
            gobject.timeout_add(int(T), self.update_progress, T / 1000, time)

    def IsValidAdapter(self):
        if self.Adapter == None:
            return False
        else:
            return True

    def GetAdapterPath(self):
        if self.IsValidAdapter():
            return self.__adapter_path

    def StopDiscovery(self):
        self.discovering = False
        if self.Adapter != None:
            self.Adapter.StopDiscovery()

    def PrependDevice(self, device):
        self.add_device(device, False)

    def AppendDevice(self, device):
        self.add_device(device, True)

    def RemoveDevice(self, device, iter=None, force=False):
        dprint(device)
        if iter == None:
            iter = self.find_device(device)

        if not device.Temp and self.compare(self.selected(), iter):
            self.emit("device-selected", None, None)

        try:
            props = device.GetProperties()
        except:
            self.device_signals.Disconnect(device.get_object_path())
        else:
            if not "Fake" in props:
                self.device_signals.Disconnect(device.GetObjectPath())

        if device.Temp and not force:
            dprint("converting to fake")

            props = copy.deepcopy(props)
            props["Fake"] = True
            dev = FakeDevice(props)

            device = Device(dev)
            self.device_add_event(device)

        else:
            #device.Destroy()
            self.delete(iter)

    def GetSelectedDevice(self):
        selected = self.selected()
        if selected != None:
            row = self.get(selected, "device")
            device = row["device"]
            return device

    def clear(self):
        if len(self.liststore):
            for i in self.liststore:
                iter = i.iter
                device = self.get(iter, "device")["device"]
                self.RemoveDevice(device, iter, True)
            self.liststore.clear()
            self.emit("device-selected", None, None)

        self.address_to_row = {}
        self.path_to_row = {}

    def find_device(self, device):
        if type(device) == str:
            address = device
        else:
            address = device.Address

        try:
            row = self.address_to_row[address]
            if row.valid():
                path = row.get_path()
                iter = self.props.model.get_iter(path)
                return iter
            else:
                del self.address_to_row[address]
                return None

        except KeyError:
            return None

    def find_device_by_path(self, path):
        try:
            row = self.path_to_row[path]
            if row.valid():
                path = row.get_path()
                iter = self.props.model.get_iter(path)
                return iter
            else:
                del self.path_to_row[path]
                return None
        except KeyError:
            return None

    def do_cache(self, iter, kwargs):
        if "device" in kwargs:
            if kwargs["device"]:
                self.address_to_row[kwargs["device"].Address] = gtk.TreeRowReference(self.props.model,
                                                                                     self.props.model.get_path(iter))
                dprint("Caching new device %s" % kwargs["device"].Address)

        if "dbus_path" in kwargs:
            if kwargs["dbus_path"] != None:
                self.path_to_row[kwargs["dbus_path"]] = gtk.TreeRowReference(self.props.model,
                                                                             self.props.model.get_path(iter))
            else:
                existing = self.get(iter, "dbus_path")["dbus_path"]
                if existing != None:
                    del self.path_to_row[existing]

    def append(self, **columns):
        iter = GenericList.append(self, **columns)
        self.do_cache(iter, columns)

    def prepend(self, **columns):
        iter = GenericList.prepend(self, **columns)
        self.do_cache(iter, columns)

    def set(self, iter, **kwargs):
        self.do_cache(iter, kwargs)
        GenericList.set(self, iter, **kwargs)
예제 #15
0
파일: NetUsage.py 프로젝트: vis-ram/blueman
class NetUsage(AppletPlugin, GObject.GObject):
    __depends__ = ["Menu"]
    __icon__ = "network-wireless"
    __description__ = _(
        "Allows you to monitor your (mobile broadband) network traffic usage. Useful for limited data access plans. This plugin tracks every device seperately."
    )
    __author__ = "Walmis"
    __autoload__ = False
    __gsignals__ = {
        str('monitor-added'):
        (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT, )),
        str('monitor-removed'):
        (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT, )),
        #monitor, tx, rx
        str('stats'): (GObject.SignalFlags.NO_HOOKS, None, (
            GObject.TYPE_PYOBJECT,
            GObject.TYPE_PYOBJECT,
            GObject.TYPE_PYOBJECT,
        )),
    }

    def on_load(self, applet):
        GObject.GObject.__init__(self)
        self.monitors = []
        self.devices = weakref.WeakValueDictionary()
        self.signals = SignalTracker()

        bus = self.bus = dbus.SystemBus()
        self.signals.Handle('bluez',
                            Network(),
                            self.on_network_property_changed,
                            'PropertyChanged',
                            path_keyword="path")

        item = create_menuitem(_("Network _Usage"),
                               get_icon("network-wireless", 16))
        item.props.tooltip_text = _("Shows network traffic usage")
        self.signals.Handle(item, "activate", self.activate_ui)
        self.Applet.Plugins.Menu.Register(self, item, 84, True)

        self.signals.Handle("dbus",
                            bus,
                            self.on_nm_ppp_stats,
                            "PppStats",
                            "org.freedesktop.NetworkManager.Device.Serial",
                            path_keyword="path")
        self.nm_paths = {}

    def on_nm_ppp_stats(self, down, up, path):
        if not path in self.nm_paths:
            props = self.bus.call_blocking(
                "org.freedesktop.NetworkManager", path,
                "org.freedesktop.DBus.Properties", "GetAll", "s",
                ["org.freedesktop.NetworkManager.Device"])

            if props["Driver"] == "bluetooth" and "rfcomm" in props[
                    "Interface"]:
                self.nm_paths[path] = True

                portid = int(props["Interface"].strip("rfcomm"))

                ls = rfcomm_list()
                for dev in ls:
                    if dev["id"] == portid:
                        adapter = self.Applet.Manager.get_adapter(dev["src"])
                        device = adapter.find_device(dev["dst"])
                        device = Device(device)

                        self.monitor_interface(NMMonitor, device, path)

                        return
            else:
                self.nm_paths[path] = False

    def on_network_property_changed(self, key, value, path):
        dprint(key, value, path)
        if key == "Interface" and value != "":
            d = BluezDevice(path)
            d = Device(d)
            self.monitor_interface(Monitor, d, value)

    def activate_ui(self, item):
        Dialog(self)

    def on_unload(self):
        self.signals.DisconnectAll()
        self.Applet.Plugins.Menu.Unregister(self)

    def monitor_interface(self, montype, *args):
        m = montype(*args)
        self.monitors.append(m)
        self.signals.Handle(m, "stats", self.on_stats, sigid=m)
        self.signals.Handle(m,
                            "disconnected",
                            self.on_monitor_disconnected,
                            sigid=m)
        self.emit("monitor-added", m)

    def on_ppp_connected(self, device, rfcomm, ppp_port):
        self.monitor_interface(Monitor, device, ppp_port)

    def on_monitor_disconnected(self, monitor):
        self.monitors.remove(monitor)
        self.signals.Disconnect(monitor)
        self.emit("monitor-removed", monitor)

    def on_stats(self, monitor, tx, rx):
        self.emit("stats", monitor, tx, rx)
예제 #16
0
파일: NetUsage.py 프로젝트: vis-ram/blueman
class Dialog:
    running = False

    def __init__(self, parent):
        if not Dialog.running:
            Dialog.running = True
        else:
            return
        self.config = None
        self.parent = parent
        builder = Gtk.Builder()
        builder.add_from_file(UI_PATH + "/net-usage.ui")
        builder.set_translation_domain("blueman")

        self.dialog = builder.get_object("dialog")
        self.dialog.connect("response", self.on_response)
        cr1 = Gtk.CellRendererText()
        cr1.props.ellipsize = Pango.EllipsizeMode.END

        self.devices = {}
        self.signals = SignalTracker()

        self.signals.Handle(parent, "monitor-added", self.monitor_added)
        self.signals.Handle(parent, "monitor-removed", self.monitor_removed)
        self.signals.Handle(parent, "stats", self.on_stats)

        cr2 = Gtk.CellRendererText()
        cr2.props.sensitive = False
        cr2.props.style = Pango.Style.ITALIC

        self.liststore = Gtk.ListStore(str, str, str, object)

        self.e_ul = builder.get_object("e_ul")
        self.e_dl = builder.get_object("e_dl")
        self.e_total = builder.get_object("e_total")

        self.l_started = builder.get_object("l_started")
        self.l_duration = builder.get_object("l_duration")

        self.b_reset = builder.get_object("b_reset")
        self.b_reset.connect("clicked", self.on_reset)

        self.cb_device = builder.get_object("cb_device")
        self.cb_device.props.model = self.liststore
        self.cb_device.connect("changed", self.on_selection_changed)

        self.cb_device.pack_start(cr1, True)
        self.cb_device.add_attribute(cr1, 'markup', 1)

        self.cb_device.pack_start(cr2, False)
        self.cb_device.add_attribute(cr2, 'markup', 2)

        general_config = Config("org.blueman.general")

        added = False
        for d in general_config["netusage-dev-list"]:
            for m in parent.monitors:
                if d == m.device.Address:
                    iter = self.liststore.append([
                        d,
                        self.get_caption(m.device.Alias, m.device.Address),
                        _("Connected:") + " " + m.interface, m
                    ])
                    if self.cb_device.get_active() == -1:
                        self.cb_device.set_active_iter(iter)
                    added = True
                    break
            if not added:
                name = d
                if self.parent.Applet.Manager:
                    for a in self.parent.Applet.Manager.list_adapters():
                        try:
                            device = a.find_device(d)
                            device = Device(device)
                            name = self.get_caption(device.Alias,
                                                    device.Address)
                        except:
                            pass

                self.liststore.append([d, name, _("Not Connected"), None])
            added = False
        if len(self.liststore) > 0:
            if self.cb_device.get_active() == -1:
                self.cb_device.set_active(0)
        else:
            d = Gtk.MessageDialog(
                parent=self.dialog,
                flags=Gtk.DialogFlags.MODAL,
                type=Gtk.MessageType.INFO,
                buttons=Gtk.ButtonsType.CLOSE,
                message_format=
                _("No usage statistics are available yet. Try establishing a connection first and then check this page."
                  ))
            d.props.icon_name = "blueman"
            d.run()
            d.destroy()
            self.on_response(None, None)
            return

        self.dialog.show()

    def on_response(self, dialog, response):
        self.signals.DisconnectAll()
        Dialog.running = False
        self.dialog.destroy()

    def update_time(self):
        time = self.config["time"]
        if time:
            self.datetime = datetime.datetime.fromtimestamp(time)

            self.l_started.props.label = str(self.datetime)

            delta = datetime.datetime.now() - self.datetime

            d = gettext.ngettext("day", "days", delta.days)
            h = gettext.ngettext("hour", "hours", delta.seconds / 3600)
            m = gettext.ngettext("minute", "minutes",
                                 delta.seconds % 3600 / 60)

            self.l_duration.props.label = _("%d %s %d %s and %d %s") % (
                delta.days, d, delta.seconds / 3600, h,
                delta.seconds % 3600 / 60, m)
        else:
            self.l_started.props.label = _("Unknown")
            self.l_duration.props.label = _("Unknown")

    def on_selection_changed(self, cb):
        iter = cb.get_active_iter()
        (addr, ) = self.liststore.get(iter, 0)
        self.config = Config("org.blueman.plugins.netusage",
                             "/org/blueman/plugins/netusages/%s/" % addr)
        self.update_counts(self.config["tx"], self.config["rx"])
        self.update_time()

    def get_caption(self, name, address):
        return "%s\n<small>%s</small>" % (cgi.escape(name), address)

    def update_counts(self, tx, rx):
        tx = int(tx)
        rx = int(rx)

        (num, suffix) = format_bytes(tx)
        self.e_ul.props.text = "%.2f %s" % (num, suffix)

        (num, suffix) = format_bytes(rx)
        self.e_dl.props.text = "%.2f %s" % (num, suffix)

        (num, suffix) = format_bytes(int(tx) + int(rx))
        self.e_total.props.text = "%.2f %s" % (num, suffix)

        self.update_time()

    def on_reset(self, button):
        d = Gtk.MessageDialog(
            parent=self.dialog,
            flags=Gtk.DialogFlags.MODAL,
            type=Gtk.MessageType.QUESTION,
            buttons=Gtk.ButtonsType.YES_NO,
            message_format=_("Are you sure you want to reset the counter?"))
        res = d.run()
        d.destroy()
        if res == Gtk.ResponseType.YES:
            self.config["rx"] = 0
            self.config["tx"] = 0
            self.config["time"] = int(time.time())

            self.update_counts(0, 0)

    def on_stats(self, parent, monitor, tx, rx):
        iter = self.cb_device.get_active_iter()
        (mon, ) = self.liststore.get(iter, 3)
        if mon == monitor:
            self.update_counts(tx, rx)

    def monitor_added(self, parent, monitor):
        for row in self.liststore:
            iter = row.iter
            (val, ) = self.liststore.get(iter, 0)

            if val == monitor.device.Address:
                self.liststore.set(
                    iter, 1,
                    self.get_caption(monitor.device.Alias,
                                     monitor.device.Address), 2,
                    _("Connected:") + " " + monitor.interface, 3, monitor)
                return

        self.liststore.append([
            monitor.device.Address,
            self.get_caption(monitor.device.Alias, monitor.device.Address),
            _("Connected:") + " " + monitor.interface, monitor
        ])

    def monitor_removed(self, parent, monitor):
        for row in self.liststore:
            iter = row.iter
            (val, ) = self.liststore.get(iter, 0)

            if val == monitor.device.Address:
                self.liststore.set(
                    iter, 1,
                    self.get_caption(monitor.device.Alias,
                                     monitor.device.Address), 2,
                    _("Not Connected"), 3, None)
                return
예제 #17
0
class ShowConnected(AppletPlugin):
    __author__ = "Walmis"
    __depends__ = ["StatusIcon"]
    __icon__ = "blueman-active"
    __description__ = _(
        "Adds an indication on the status icon when Bluetooth is active and shows the number of connections in the tooltip.")

    def on_load(self, applet):
        self.num_connections = 0
        self.active = False
        self.initialized = False

        self.signals = SignalTracker()
        self.signals.Handle('bluez', bluez.Device(), self.on_device_property_changed, 'PropertyChanged')

    def on_unload(self):
        self.signals.DisconnectAll()
        self.Applet.Plugins.StatusIcon.SetTextLine(1, None)
        self.num_connections = 0
        self.Applet.Plugins.StatusIcon.IconShouldChange()


    def on_status_icon_query_icon(self):
        if self.num_connections > 0:
            self.active = True
            #			x_size = int(pixbuf.props.height)
            #			x = get_icon("blueman-txrx", x_size)
            #			pixbuf = composite_icon(pixbuf,
            #				[(x, pixbuf.props.height - x_size, 0, 255)])
            #
            #			return pixbuf
            return ("blueman-active",)
        else:
            self.active = False

    def enumerate_connections(self):
        self.num_connections = 0
        adapters = self.Applet.Manager.list_adapters()
        for adapter in adapters:
            devices = adapter.list_devices()
            for device in devices:
                props = device.get_properties()
                if "Connected" in props:
                    if props["Connected"]:
                        self.num_connections += 1

        dprint("Found %d existing connections" % self.num_connections)
        if (self.num_connections > 0 and not self.active) or \
                (self.num_connections == 0 and self.active):
            self.Applet.Plugins.StatusIcon.IconShouldChange()

        self.update_statusicon()

    def update_statusicon(self):
        if self.num_connections > 0:
            self.Applet.Plugins.StatusIcon.SetTextLine(0,
                                                       _("Bluetooth Active"))
            self.Applet.Plugins.StatusIcon.SetTextLine(1,
                                                       ngettext("<b>%d Active Connection</b>",
                                                                "<b>%d Active Connections</b>",
                                                                self.num_connections) % self.num_connections)
        else:
            self.Applet.Plugins.StatusIcon.SetTextLine(1, None)
            try:
                if self.Applet.Plugins.PowerManager.GetBluetoothStatus():
                    self.Applet.Plugins.StatusIcon.SetTextLine(0,
                                                               _("Bluetooth Enabled"))
            except:
                #bluetooth should be always enabled if powermanager is
                #not loaded
                self.Applet.Plugins.StatusIcon.SetTextLine(0,
                                                           _("Bluetooth Enabled"))

    def on_manager_state_changed(self, state):
        if state:
            if not self.initialized:
                GObject.timeout_add(0, self.enumerate_connections)
                self.initialized = True
            else:
                GObject.timeout_add(1000,
                                    self.enumerate_connections)
        else:
            self.num_connections = 0
            self.update_statusicon()

    def on_device_property_changed(self, key, value):
        if key == "Connected":
            if value:
                self.num_connections += 1
            else:
                self.num_connections -= 1

            if (self.num_connections > 0 and not self.active) or \
                    (self.num_connections == 0 and self.active):
                self.Applet.Plugins.StatusIcon.IconShouldChange()

            self.update_statusicon()

    def on_adapter_added(self, adapter):
        self.enumerate_connections()

    def on_adapter_removed(self, adapter):
        self.enumerate_connections()
예제 #18
0
class NMPANSupport(AppletPlugin):
    __depends__ = ["DBusService"]
    __conflicts__ = ["DhcpClient"]
    __icon__ = "network"
    __author__ = "Walmis"
    __description__ = _(
        "Provides support for Personal Area Networking (PAN) introduced in NetworkManager 0.8"
    )
    __priority__ = 2

    def on_load(self, applet):
        self.bus = dbus.SystemBus()
        self.nma = None
        self.nm = None
        self.nm_signals = SignalTracker()
        self.nma_signals = SignalTracker()

        self.watches = [
            self.bus.watch_name_owner("org.freedesktop.NetworkManager",
                                      self.on_nm_owner_changed)
        ]

        self.legacy = self.bus.name_has_owner(
            'org.freedesktop.NetworkManagerUserSettings')

        if self.legacy:
            self.watches.append(
                self.bus.watch_name_owner(
                    "org.freedesktop.NetworkManagerUserSettings",
                    self.on_nma_owner_changed))
            self.settings_bus = 'org.freedesktop.NetworkManagerUserSettings'
            self.settings_interface = 'org.freedesktop.NetworkManagerSettings'
            self.connection_settings_interface = 'org.freedesktop.NetworkManagerSettings.Connection'
            self.settings_path = "/org/freedesktop/NetworkManagerSettings"
            NewConnectionBuilder.DEVICE_STATE_DISCONNECTED = 3
            NewConnectionBuilder.DEVICE_STATE_ACTIVATED = 8
            NewConnectionBuilder.DEVICE_STATE_FAILED = 9
        else:
            self.settings_bus = 'org.freedesktop.NetworkManager'
            self.settings_interface = 'org.freedesktop.NetworkManager.Settings'
            self.connection_settings_interface = 'org.freedesktop.NetworkManager.Settings.Connection'
            self.settings_path = "/org/freedesktop/NetworkManager/Settings"

    def remove_connection(self, path):
        self.bus.call_blocking(self.settings_bus, path,
                               self.connection_settings_interface, "Delete",
                               "", [])

    @staticmethod
    def format_bdaddr(addr):
        return "%02X:%02X:%02X:%02X:%02X:%02X" % (addr[0], addr[1], addr[2],
                                                  addr[3], addr[4], addr[5])

    def find_device(self, bdaddr):
        devices = self.nm.GetDevices()
        for dev in devices:
            try:
                d = self.bus.call_blocking(
                    "org.freedesktop.NetworkManager", dev,
                    "org.freedesktop.DBus.Properties", "GetAll", "s",
                    ["org.freedesktop.NetworkManager.Device.Bluetooth"])
                if d["HwAddress"] == bdaddr:
                    dprint(d["HwAddress"])
                    return dev

            except dbus.DBusException:
                pass

    def find_connection(self, address, t):
        conns = self.nma.ListConnections()
        for conn in conns:
            c = self.bus.call_blocking(self.settings_bus, conn,
                                       self.connection_settings_interface,
                                       "GetSettings", "", [])
            try:
                if (self.format_bdaddr(c["bluetooth"]["bdaddr"])
                        == address) and c["bluetooth"]["type"] == t:
                    return conn
            except:
                pass

    def find_active_connection(self, address, type):
        props = self.bus.call_blocking("org.freedesktop.NetworkManager",
                                       "/org/freedesktop/NetworkManager",
                                       "org.freedesktop.DBus.Properties",
                                       "GetAll", "s",
                                       ["org.freedesktop.NetworkManager"])

        nma_connection = self.find_connection(address, type)
        if nma_connection:
            active_conns = props["ActiveConnections"]
            for conn in active_conns:
                conn_props = self.bus.call_blocking(
                    "org.freedesktop.NetworkManager", conn,
                    "org.freedesktop.DBus.Properties", "GetAll", "s",
                    ["org.freedesktop.NetworkManager.Connection.Active"])

                if conn_props["Connection"] == nma_connection:
                    return conn

    def on_nma_owner_changed(self, owner):
        if owner == "":
            self.nma = None
        else:
            service = self.bus.get_object(self.settings_bus,
                                          self.settings_path)
            self.nma = dbus.proxies.Interface(service, self.settings_interface)

    def on_nm_owner_changed(self, owner):
        if owner == "":
            self.nm = None
            self.nm_signals.DisconnectAll()
        else:
            service = self.bus.get_object("org.freedesktop.NetworkManager",
                                          "/org/freedesktop/NetworkManager")
            self.nm = dbus.proxies.Interface(service,
                                             "org.freedesktop.NetworkManager")
            if not self.legacy:
                self.on_nma_owner_changed(owner)

    def on_unload(self):
        self.nm_signals.DisconnectAll()
        self.nma_signals.DisconnectAll()

        for watch in self.watches:
            watch.cancel()

    def service_connect_handler(self, service, ok, err):
        if service.group != 'network':
            return

        if self.find_active_connection(service.device.Address, "panu"):
            err(dbus.DBusException(_("Already connected")))
        else:
            NewConnectionBuilder(self, service, ok, err)

        return True

    def service_disconnect_handler(self, service, ok, err):
        if service.group != 'network':
            return

        d = service.device
        active_conn_path = self.find_active_connection(d.Address, "panu")

        if not active_conn_path:
            return

        self.bus.call_blocking("org.freedesktop.NetworkManager",
                               "/org/freedesktop/NetworkManager",
                               "org.freedesktop.NetworkManager",
                               "DeactivateConnection", "o", [active_conn_path])
        ok()
        return True
예제 #19
0
class NMIntegration(AppletPlugin):
    __description__ = _(
        "<b>Deprecated</b>\nMakes DUN/PAN connections available for NetworkManager 0.7"
    )
    __icon__ = "modem"
    __depends__ = ["DBusService"]
    __conflicts__ = ["PPPSupport", "DhcpClient"]
    __author__ = "Walmis"
    if HAL_ENABLED:
        __priority__ = 2

    def on_load(self, applet):
        self.Signals = SignalTracker()

        self.Signals.Handle('bluez',
                            Network(),
                            self.on_network_prop_changed,
                            'PropertyChanged',
                            path_keyword='path')

    def on_unload(self):
        self.Signals.DisconnectAll()

    def on_network_prop_changed(self, key, value, path):
        if key == "Interface":
            if value != "":
                m = Mechanism()
                m.HalRegisterNetDev(value)

    #in: bluez_device_path, rfcomm_device
    #@dbus.service.method(dbus_interface='org.blueman.Applet', in_signature="ss", out_signature="")
    def RegisterModem(self, device_path, rfcomm_device):
        dev = Bluez.Device(device_path)
        props = dev.get_properties()

        m = Mechanism()

        def reply():
            dprint("Registered modem")

        def err(excp):
            d = Gtk.MessageDialog(None, type=Gtk.MessageType.WARNING)
            d.props.icon_name = "blueman"
            d.props.text = _("CDMA or GSM not supported")
            d.props.secondary_text = _(
                "The device %s does not appear to support GSM/CDMA.\nThis connection will not work."
            ) % props["Alias"]

            d.add_button(Gtk.STOCK_OK, Gtk.ResponseType.NO)
            resp = d.run()
            d.destroy()

        m.HalRegisterModemPort(rfcomm_device,
                               props["Address"],
                               reply_handler=reply,
                               error_handler=err)

    #in: bluez_device_path, rfcomm_device
    #@dbus.service.method(dbus_interface='org.blueman.Applet', in_signature="s", out_signature="")
    def UnregisterModem(self, device):
        m = Mechanism()
        m.HalUnregisterModemPortDev(device)

        dprint("Unregistered modem")

    def on_rfcomm_connected(self, device, port, uuid):
        signals = SignalTracker()

        def modem_added(mon, udi, address):
            if device.Address == address:
                dprint(udi)
                device.udi = udi

        def modem_removed(mon, udi):
            if device.udi == udi:
                dprint(udi)
                signals.DisconnectAll()

        def disconnected(mon, udi):
            device.Services["serial"].Disconnect(port)
            self.UnregisterModem(port)

        def device_propery_changed(key, value):
            if key == "Connected" and not value:
                self.UnregisterModem(port)

        uuid16 = sdp_get_serial_type(device.Address, uuid)
        if DIALUP_NET_SVCLASS_ID in uuid16:
            try:
                signals.Handle(self.Applet.Plugins.NMMonitor, "modem-added",
                               modem_added)
                signals.Handle(self.Applet.Plugins.NMMonitor, "modem-removed",
                               modem_removed)
                signals.Handle(self.Applet.Plugins.NMMonitor, "disconnected",
                               disconnected)
            except KeyError:
                pass

            signals.Handle("bluez", device.Device, device_propery_changed,
                           "PropertyChanged")
            self.RegisterModem(device.get_object_path(), port)

    def rfcomm_connect_handler(self, device, uuid, reply_handler,
                               error_handler):
        uuid16 = sdp_get_serial_type(device.Address, uuid)
        if DIALUP_NET_SVCLASS_ID in uuid16:
            device.Services["serial"].Connect(uuid,
                                              reply_handler=reply_handler,
                                              error_handler=error_handler)
            return True
        else:
            return False

    def on_rfcomm_disconnect(self, port):
        self.UnregisterModem(port)
예제 #20
0
class Networking(AppletPlugin):
    __icon__ = "network"
    __description__ = _("Manages local network services, like NAP bridges")
    __author__ = "Walmis"

    def on_load(self, applet):
        self.Applet = applet
        self.Signals = SignalTracker()

        self.Config = Config("network")
        self.Signals.Handle("gobject", self.Config, "property-changed",
                            self.on_config_changed)

        self.load_nap_settings()

    def on_manager_state_changed(self, state):
        if state:
            self.update_status()

    def load_nap_settings(self):
        dprint("Loading NAP settings")

        def reply():
            pass

        def err(excp):
            lines = str(excp).splitlines()
            d = Gtk.MessageDialog(None,
                                  buttons=Gtk.ButtonsType.OK,
                                  type=Gtk.MessageType.ERROR)
            d.props.text = _("Failed to apply network settings")
            d.props.secondary_text = lines[-1] + "\n\n" + _(
                "You might not be able to connect to the Bluetooth network via this machine"
            )
            d.run()
            d.destroy()

        m = Mechanism()
        m.ReloadNetwork(reply_handler=reply, error_handler=err)

    def on_unload(self):
        self.Signals.DisconnectAll()

    def on_adapter_added(self, path):
        self.update_status()

    def update_status(self):
        self.set_nap(self.Config.props.nap_enable or False)

    def on_config_changed(self, config, key, value):
        if key == "nap_enable":
            self.set_nap(value)

    def set_nap(self, on):
        dprint("set nap", on)
        if self.Applet.Manager != None:
            adapters = self.Applet.Manager.list_adapters()
            for adapter in adapters:
                s = NetworkServer(adapter.get_object_path())
                if on:
                    s.register("nap", "pan1")
                else:
                    s.unregister("nap")
예제 #21
0
class NewConnectionBuilder:
	def __init__(self, parent, params, ok_cb, err_cb):
		self.parent = parent
		self.params = params
		self.ok_cb = ok_cb
		self.err_cb = err_cb
		
		self.signals = SignalTracker()
		
		self.device = None
		self.connection = None
		
		self.signals.Handle("dbus", parent.bus, self.on_nm_device_added, "DeviceAdded", "org.freedesktop.NetworkManager")
		self.signals.Handle("dbus", parent.bus, self.on_nma_new_connection, "NewConnection", "org.freedesktop.NetworkManagerSettings")
		
		self.device = self.parent.find_device(params["bluetooth"]["bdaddr"])

		self.connection = self.parent.find_connection(params["bluetooth"]["bdaddr"], "panu")
		if not self.connection:
			parent.add_connection(params)
			gobject.timeout_add(1000, self.signal_wait_timeout)
		else:
			self.init_connection()
			
	def cleanup(self):
		self.signals.DisconnectAll()
			
	def signal_wait_timeout(self):
		if not self.device or not self.connection:
			self.err_cb(dbus.DBusException("Network Manager did not support the connection"))
			if self.connection:
				self.remove_connection()		
			self.cleanup()
		
	def on_nm_device_added(self, path):
		dprint(path)
		self.device = path
		if self.device and self.connection:
			self.init_connection()
	
	def on_nma_new_connection(self, path):
		dprint(path)
		self.connection = path
		if self.device and self.connection:
			self.init_connection()
			
	def init_connection(self):
		self.cleanup()
		dprint("activating", self.connection, self.device)
		if not self.device or not self.connection:
			self.err_cb(dbus.DBusException("Network Manager did not support the connection"))
			if self.connection:
				self.remove_connection()
			self.cleanup()
		else:
			self.signals.Handle("dbus", self.parent.bus, self.on_device_state, "StateChanged", "org.freedesktop.NetworkManager.Device", path=self.device)
		
			self.parent.nm.ActivateConnection("org.freedesktop.NetworkManagerUserSettings", self.connection, self.device, self.connection)
		
	def remove_connection(self):
		self.parent.remove_connection(self.connection)
		
	def on_device_state(self, state, oldstate, reason):
		dprint("state=",state, "oldstate=", oldstate, "reason=", reason)
		if state <= NMDeviceState.DISCONNECTED and NMDeviceState.DISCONNECTED < oldstate <= NMDeviceState.ACTIVATED:
			if self.err_cb:
				self.err_cb(dbus.DBusException("Connection was interrupted"))
			
			self.remove_connection()
			self.cleanup()
		
		elif state == NMDeviceState.FAILED:
			self.err_cb(dbus.DBusException("Network Manager Failed to activate the connection"))
			self.remove_connection()
			self.cleanup()		
		
		elif state == NMDeviceState.ACTIVATED:
			self.ok_cb()
			self.err_cb = None
			self.ok_cb = None
예제 #22
0
파일: Device.py 프로젝트: posophe/blueman
class Device(GObject.GObject):
    __gsignals__ = {
        'invalidated': (GObject.SignalFlags.NO_HOOKS, None, ()),
        'property-changed': (GObject.SignalFlags.NO_HOOKS, None, (
            GObject.TYPE_PYOBJECT,
            GObject.TYPE_PYOBJECT,
        )),
    }

    def __init__(self, instance):
        GObject.GObject.__init__(self)

        self.Properties = {}
        self.Fake = True
        self.Temp = False

        if isinstance(instance, str) or isinstance(instance, unicode):
            self.Device = BluezDevice(instance)
        else:
            self.Device = instance

        #set fallback icon, fixes lp:#327718
        self.Device.Icon = "blueman"
        self.Device.Class = "unknown"

        self.__services = {}

        self.Valid = True

        self.Signals = SignalTracker()

        dprint("caching initial properties")
        self.Properties = self.Device.get_properties()

        if not "Fake" in self.Properties:
            self.Fake = False

        w = weakref.ref(self)
        if not self.Fake:
            self._obj_path = self.Device.get_object_path()
            self.Signals.Handle(
                "bluez", self.Device,
                lambda key, value: w() and w().property_changed(key, value),
                "PropertyChanged")
            object_path = self.Device.get_object_path()
            adapter = Adapter(
                object_path.replace("/" + os.path.basename(object_path), ""))
            self.Signals.Handle(
                "bluez", adapter,
                lambda path: w() and w().on_device_removed(path),
                "DeviceRemoved")

    @property
    def Services(self):
        if len(self.__services) == 0:
            self.init_services()

        return self.__services

    def __del__(self):
        dprint("deleting device", self.get_object_path())
        self.Destroy()

    def get_object_path(self):
        if not self.Fake:
            return self._obj_path

    def on_device_removed(self, path):
        if path == self._obj_path:
            self.emit("invalidated")
            self.Destroy()

    def init_services(self):
        dprint("Loading services")

        if not self.Fake:
            services = self.Device.list_services()
            self.__services = {}
            for service in services:
                name = service.get_interface_name().split(".")
                if name[0] == 'org' and name[1] == 'bluez':
                    name = name[2].lower()
                    if name.endswith('1'):
                        name = name[:-1]
                    self.__services[name] = service

    def Copy(self):
        if not self.Valid:
            raise Exception("Attempted to copy an invalidated device")
        return Device(self.Device)

    def property_changed(self, key, value):
        self.emit("property-changed", key, value)
        self.Properties[key] = value
        if key == "UUIDs":
            self.init_services()

    def Destroy(self):
        dprint("invalidating device", self.get_object_path())
        self.Valid = False
        #self.Device = None
        self.Signals.DisconnectAll()

    #def __del__(self):
    #	dprint("DEBUG: deleting Device instance")

    def get_properties(self):
        #print "Properties requested"
        if not self.Valid:
            raise Exception(
                "Attempted to get properties for an invalidated device")
        return self.Properties

    def __getattr__(self, name):
        if name in self.__dict__["Properties"]:
            if not self.Valid:
                #traceback.print_stack()
                dprint(
                    "Warning: Attempted to get %s property for an invalidated device"
                    % name)
            return self.__dict__["Properties"][name]
        else:
            return getattr(self.Device, name)

    def __setattr__(self, key, value):
        if not key in self.__dict__ and "Properties" in self.__dict__ and key in self.__dict__[
                "Properties"]:
            if not self.Valid:
                raise Exception(
                    "Attempted to set properties for an invalidated device")
            dprint("Setting property", key, value)
            self.__dict__["Device"].set(key, value)
        else:
            self.__dict__[key] = value
예제 #23
0
class SerialManager(AppletPlugin):
    __icon__ = "blueman-serial"
    __description__ = _(
        "Standard SPP profile connection handler, allows executing custom actions"
    )
    __author__ = "walmis"

    __gsettings__ = {
        "schema": "org.blueman.plugins.serialmanager",
        "path": None
    }
    __options__ = {
        "script": {
            "type":
            str,
            "default":
            "",
            "name":
            _("Script to execute on connection"),
            "desc":
            _("<span size=\"small\">The following arguments will be passed:\n"
              "Address, Name, service name, uuid16s, rfcomm node\n"
              "For example:\n"
              "AA:BB:CC:DD:EE:FF, Phone, DUN service, 0x1103, /dev/rfcomm0\n"
              "uuid16s are returned as a comma seperated list\n\n"
              "Upon device disconnection the script will be sent a HUP signal</span>"
              )
        },
    }

    def on_load(self, applet):
        self.signals = SignalTracker()
        self.signals.Handle('bluez',
                            Bluez.Device(),
                            self.on_device_property_changed,
                            'PropertyChanged',
                            path_keyword="path")

        self.scripts = {}

    def on_unload(self):
        self.signals.DisconnectAll()
        for k in self.scripts.keys():
            self.terminate_all_scripts(k)

    def on_device_property_changed(self, key, value, path):
        if key == "Connected" and not value:
            d = Device(path)
            self.terminate_all_scripts(d.Address)

    def on_rfcomm_connected(self, service, port):
        device = service.device
        uuid16 = uuid128_to_uuid16(service.uuid)
        if SERIAL_PORT_SVCLASS_ID == uuid16:
            Notification(
                _("Serial port connected"),
                _("Serial port service on device <b>%s</b> now will be available via <b>%s</b>"
                  ) % (device.Alias, port),
                pixbuf=get_icon("blueman-serial", 48),
                status_icon=self.Applet.Plugins.StatusIcon)

            self.call_script(device.Address, device.Alias,
                             uuid16_to_name(uuid16), uuid16, port)

    def terminate_all_scripts(self, address):
        try:
            for p in self.scripts[address].values():
                dprint("Sending HUP to", p.pid)
                os.killpg(p.pid, signal.SIGHUP)
        except:
            pass

    def on_script_closed(self, pid, cond, address_node):
        address, node = address_node
        del self.scripts[address][node]
        dprint("Script with PID", pid, "closed")

    def manage_script(self, address, node, process):
        if not address in self.scripts:
            self.scripts[address] = {}

        if node in self.scripts[address]:
            self.scripts[address][node].terminate()

        self.scripts[address][node] = process
        GObject.child_watch_add(process.pid, self.on_script_closed,
                                (address, node))

    def call_script(self, address, name, sv_name, uuid16, node):
        c = self.get_option("script")
        if c and c != "":
            args = c.split(" ")
            try:
                args += [
                    address, name, sv_name,
                    ",".join(map(lambda x: hex(x), uuid16)), node
                ]
                dprint(args)
                p = Popen(args, preexec_fn=lambda: os.setpgid(0, 0))

                self.manage_script(address, node, p)

            except Exception as e:
                Notification(_("Serial port connection script failed"),
                             _("There was a problem launching script %s\n"
                               "%s") % (c, str(e)),
                             pixbuf=get_icon("blueman-serial", 48),
                             status_icon=self.Applet.Plugins.StatusIcon)

    def on_rfcomm_disconnect(self, node):
        for k, v in self.scripts.items():
            if node in v:
                dprint("Sending HUP to", v[node].pid)
                os.killpg(v[node].pid, signal.SIGHUP)

    def rfcomm_connect_handler(self, service, reply, err):
        if SERIAL_PORT_SVCLASS_ID == uuid128_to_uuid16(service.uuid):
            service.connect(reply_handler=reply, error_handler=err)
            return True
        else:
            return False

    def on_device_disconnect(self, device):
        self.terminate_all_scripts(device.Address)

        serial_services = [
            service for service in device.get_services()
            if service.group == 'serial'
        ]

        if not serial_services:
            return

        ports = rfcomm_list()

        def flt(dev):
            if dev["dst"] == device.Address and dev["state"] == "connected":
                return dev["id"]

        active_ports = map(flt, ports)

        for port in active_ports:
            name = "/dev/rfcomm%d" % port
            try:
                dprint("Disconnecting", name)
                serial_services[0].disconnect(name)
            except:
                dprint("Failed to disconnect", name)
예제 #24
0
class ManagerDeviceMenu(gtk.Menu):
    __ops__ = {}
    __instances__ = []

    def __init__(self, blueman):
        gtk.Menu.__init__(self)
        self.Blueman = blueman
        self.SelectedDevice = None

        self.is_popup = False

        #object, args,
        self.Signals = SignalTracker()
        self.MainSignals = SignalTracker()

        self.MainSignals.Handle("gobject", self.Blueman.List,
                                "device-property-changed",
                                self.on_device_property_changed)

        ManagerDeviceMenu.__instances__.append(self)

        self.Generate()

    def __del__(self):
        dprint("deleting devicemenu")

    #	gobject.GObject.__del__(self)

    def popup(self, *args):
        self.is_popup = True

        self.MainSignals.DisconnectAll()
        self.MainSignals.Handle("gobject", self.Blueman.List,
                                "device-property-changed",
                                self.on_device_property_changed)

        def disconnectall(x):
            self.MainSignals.DisconnectAll()

        self.MainSignals.Handle("gobject", self, "selection-done",
                                disconnectall)

        self.Generate()

        gtk.Menu.popup(self, *args)

    def clear(self):
        self.Signals.DisconnectAll()

        def each(child):
            self.remove(child)
            child.destroy()

        self.foreach(each)

    def set_op(self, device, message):
        ManagerDeviceMenu.__ops__[device.GetObjectPath()] = message
        for inst in ManagerDeviceMenu.__instances__:
            dprint("op: regenerating instance", inst)
            if inst.SelectedDevice == self.SelectedDevice and not (
                    inst.is_popup and not inst.props.visible):
                inst.Generate()

    def get_op(self, device):
        try:
            return ManagerDeviceMenu.__ops__[device.GetObjectPath()]
        except:
            return None

    def unset_op(self, device):
        del ManagerDeviceMenu.__ops__[device.GetObjectPath()]
        for inst in ManagerDeviceMenu.__instances__:
            dprint("op: regenerating instance", inst)
            if inst.SelectedDevice == self.SelectedDevice and not (
                    inst.is_popup and not inst.props.visible):
                inst.Generate()

    def service_property_changed(self, key, value):
        if key == "Connected":
            self.Generate()

    def on_connect(self, item, device, service_id, *args):
        def success(*args2):
            try:
                uuid16 = sdp_get_serial_type(device.Address, args[0])
            except:
                uuid16 = 0

            dprint("success", args2)
            prog.message(_("Success!"))

            if service_id == "serial" and SERIAL_PORT_SVCLASS_ID in uuid16:
                MessageArea.show_message(
                    _("Serial port connected to %s") % args2[0],
                    gtk.STOCK_DIALOG_INFO)
            else:
                MessageArea.close()

            self.unset_op(device)

        def fail(*args):
            prog.message(_("Failed"))

            self.unset_op(device)
            dprint("fail", args)
            MessageArea.show_message(
                _("Connection Failed: ") + e_(str(args[0])))

        def cancel(prog, *args):
            try:
                svc.Disconnect(*args)
            except:
                pass
            prog.message(_("Cancelled"))
            self.unset_op(device)

        svc = device.Services[service_id]
        self.set_op(device, _("Connecting..."))
        prog = ManagerProgressbar(self.Blueman, False)

        try:
            appl = AppletService()
        except:
            dprint("** Failed to connect to applet")
            fail()
            return
        try:
            appl.SetTimeHint(gtk.get_current_event_time())
        except:
            pass

        if service_id == "network":
            uuid = args[0]
            appl.ServiceProxy(svc.GetInterfaceName(),
                              svc.GetObjectPath(),
                              "Connect", [uuid],
                              reply_handler=success,
                              error_handler=fail,
                              timeout=200)
        #prog.set_cancellable(True)
        #prog.connect("cancelled", cancel)

        elif service_id == "input":
            appl.ServiceProxy(svc.GetInterfaceName(),
                              svc.GetObjectPath(),
                              "Connect", [],
                              reply_handler=success,
                              error_handler=fail,
                              timeout=200)
        #prog.connect("cancelled", cancel)

        elif service_id == "serial":
            uuid = str(args[0])

            appl.RfcommConnect(device.GetObjectPath(),
                               uuid,
                               reply_handler=success,
                               error_handler=fail,
                               timeout=200)

        else:
            appl.ServiceProxy(svc.GetInterfaceName(),
                              svc.GetObjectPath(),
                              "Connect", [],
                              reply_handler=success,
                              error_handler=fail,
                              timeout=200)

        prog.start()

    def on_disconnect(self, item, device, service_id, *args):
        svc = device.Services[service_id]
        if service_id == "serial":
            try:
                appl = AppletService()
            except:
                dprint("** Failed to connect to applet")
            else:
                appl.RfcommDisconnect(device.GetObjectPath(), args[0])
                self.Generate()
        else:
            try:
                appl = AppletService()
            except:
                dprint("** Failed to connect to applet")
                return
            appl.ServiceProxy(svc.GetInterfaceName(), svc.GetObjectPath(),
                              "Disconnect", [])

    def on_device_property_changed(self, List, device, iter, (key, value)):
        #		print "menu:", key, value
        if List.compare(iter, List.selected()):
            if key == "Connected" \
                or key == "Fake" \
                or key == "UUIDs" \
                or key == "Trusted" \
                or key == "Paired":
                self.Generate()
예제 #25
0
class ManagerDeviceMenu(Gtk.Menu):
    __ops__ = {}
    __instances__ = []

    def __init__(self, blueman):
        GObject.GObject.__init__(self)
        self.Blueman = blueman
        self.SelectedDevice = None

        self.is_popup = False

        #object, args,
        self.Signals = SignalTracker()
        self.MainSignals = SignalTracker()

        self.MainSignals.Handle("gobject", self.Blueman.List,
                                "device-property-changed",
                                self.on_device_property_changed)

        ManagerDeviceMenu.__instances__.append(self)

        self.Generate()

    def __del__(self):
        dprint("deleting devicemenu")

    #	GObject.GObject.__del__(self)

    def popup(self, *args):
        self.is_popup = True

        self.MainSignals.DisconnectAll()
        self.MainSignals.Handle("gobject", self.Blueman.List,
                                "device-property-changed",
                                self.on_device_property_changed)

        def disconnectall(x):
            self.MainSignals.DisconnectAll()

        self.MainSignals.Handle("gobject", self, "selection-done",
                                disconnectall)

        self.Generate()

        Gtk.Menu.popup(self, *args)

    def clear(self):
        self.Signals.DisconnectAll()

        def each(child, data):
            self.remove(child)
            child.destroy()

        self.foreach(each, None)

    def set_op(self, device, message):
        ManagerDeviceMenu.__ops__[device.get_object_path()] = message
        for inst in ManagerDeviceMenu.__instances__:
            dprint("op: regenerating instance", inst)
            if inst.SelectedDevice == self.SelectedDevice and not (
                    inst.is_popup and not inst.props.visible):
                inst.Generate()

    def get_op(self, device):
        try:
            return ManagerDeviceMenu.__ops__[device.get_object_path()]
        except:
            return None

    def unset_op(self, device):
        del ManagerDeviceMenu.__ops__[device.get_object_path()]
        for inst in ManagerDeviceMenu.__instances__:
            dprint("op: regenerating instance", inst)
            if inst.SelectedDevice == self.SelectedDevice and not (
                    inst.is_popup and not inst.props.visible):
                inst.Generate()

    def service_property_changed(self, key, value):
        if key == "Connected":
            self.Generate()

    def on_connect(self, _item, service):
        device = service.device

        def success(*args2):
            dprint("success", args2)
            prog.message(_("Success!"))

            if isinstance(service, SerialPort
                          ) and SERIAL_PORT_SVCLASS_ID == uuid128_to_uuid16(
                              service.uuid):
                MessageArea.show_message(
                    _("Serial port connected to %s") % args2[0],
                    "dialog-information")
            else:
                MessageArea.close()

            self.unset_op(device)

        def fail(*args):
            prog.message(_("Failed"))

            self.unset_op(device)
            dprint("fail", args)
            MessageArea.show_message(
                _("Connection Failed: ") + e_(str(args[0])))

        self.set_op(device, _("Connecting..."))
        prog = ManagerProgressbar(self.Blueman, False)

        try:
            appl = AppletService()
        except:
            dprint("** Failed to connect to applet")
            fail()
            return
        try:
            appl.SetTimeHint(Gtk.get_current_event_time())
        except:
            pass

        appl.connect_service(device.get_object_path(),
                             service.uuid,
                             reply_handler=success,
                             error_handler=fail,
                             timeout=200)

        prog.start()

    def on_disconnect(self, item, service, port=0):
        try:
            appl = AppletService()
        except:
            dprint("** Failed to connect to applet")
            return

        appl.disconnect_service(service.device.get_object_path(), service.uuid,
                                port)
        self.Generate()

    def on_device_property_changed(self, List, device, iter, key_value):
        key, value = key_value
        # print "menu:", key, value
        if List.compare(iter, List.selected()):
            if key == "Connected" \
                or key == "Fake" \
                or key == "UUIDs" \
                or key == "Trusted" \
                or key == "Paired":
                self.Generate()

    def Generate(self):
        self.clear()

        appl = AppletService()

        items = []

        if not self.is_popup or self.props.visible:
            selected = self.Blueman.List.selected()
            if not selected:
                return
            device = self.Blueman.List.get(selected, "device")["device"]
        else:
            (x, y) = self.Blueman.List.get_pointer()
            path = self.Blueman.List.get_path_at_pos(x, y)
            if path != None:
                device = self.Blueman.List.get(path[0], "device")["device"]
            else:
                return

        if not device.Valid:
            return
        self.SelectedDevice = device

        op = self.get_op(device)

        if op != None:
            item = create_menuitem(op, get_icon("network-transmit-recieve",
                                                16))
            item.props.sensitive = False
            item.show()
            self.append(item)
            return

        rets = self.Blueman.Plugins.Run("on_request_menu_items", self, device)

        for ret in rets:
            if ret:
                for (item, pos) in ret:
                    items.append((pos, item))

        if device.Fake:
            item = create_menuitem(_("_Add Device"), get_icon("list-add", 16))
            self.Signals.Handle("gobject", item, "activate",
                                lambda x: self.Blueman.add_device(device))
            item.show()
            self.append(item)
            item.props.tooltip_text = _(
                "Add this device to known devices list")

            item = create_menuitem(_("_Setup..."),
                                   get_icon("document-properties", 16))
            self.append(item)
            self.Signals.Handle("gobject", item, "activate",
                                lambda x: self.Blueman.setup(device))
            item.show()
            item.props.tooltip_text = _(
                "Run the setup assistant for this device")

            item = create_menuitem(_("_Pair"), get_icon("dialog-password", 16))
            self.Signals.Handle("gobject", item, "activate",
                                lambda x: self.Blueman.bond(device))
            self.append(item)
            item.show()
            item.props.tooltip_text = _("Pair with the device")

            item = Gtk.SeparatorMenuItem()
            item.show()
            self.append(item)

            send_item = create_menuitem(_("Send a _File..."),
                                        get_icon("edit-copy", 16))
            self.Signals.Handle("gobject", send_item, "activate",
                                lambda x: self.Blueman.send(device))
            send_item.show()
            self.append(send_item)

        else:
            dprint(device.Alias)

            item = None

            have_disconnectables = False
            have_connectables = False

            if True in map(lambda x: x[0] >= 100 and x[0] < 200, items):
                have_disconnectables = True

            if True in map(lambda x: x[0] < 100, items):
                have_connectables = True

            if True in map(lambda x: x[0] >= 200,
                           items) and (have_connectables
                                       or have_disconnectables):
                item = Gtk.SeparatorMenuItem()
                item.show()
                items.append((199, item))

            if have_connectables:
                item = Gtk.MenuItem()
                label = Gtk.Label()
                label.set_markup(_("<b>Connect To:</b>"))
                label.props.xalign = 0.0

                label.show()
                item.add(label)
                item.props.sensitive = False
                item.show()
                items.append((0, item))

            if have_disconnectables:
                item = Gtk.MenuItem()
                label = Gtk.Label()
                label.set_markup(_("<b>Disconnect:</b>"))
                label.props.xalign = 0.0

                label.show()
                item.add(label)
                item.props.sensitive = False
                item.show()
                items.append((99, item))

            items.sort(key=itemgetter(0))
            for priority, item in items:
                self.append(item)

            if items != []:
                item = Gtk.SeparatorMenuItem()
                item.show()
                self.append(item)

            del items

            send_item = create_menuitem(_("Send a _File..."),
                                        get_icon("edit-copy", 16))
            send_item.props.sensitive = False
            self.append(send_item)
            send_item.show()

            browse_item = create_menuitem(_("_Browse Device..."),
                                          get_icon("document-open", 16))
            browse_item.props.sensitive = False
            self.append(browse_item)
            browse_item.show()

            uuids = device.UUIDs
            for uuid in uuids:
                uuid16 = uuid128_to_uuid16(uuid)
                if uuid16 == OBEX_OBJPUSH_SVCLASS_ID:
                    self.Signals.Handle("gobject", send_item, "activate",
                                        lambda x: self.Blueman.send(device))
                    send_item.props.sensitive = True

                if uuid16 == OBEX_FILETRANS_SVCLASS_ID:
                    self.Signals.Handle("gobject", browse_item, "activate",
                                        lambda x: self.Blueman.browse(device))
                    browse_item.props.sensitive = True

            item = Gtk.SeparatorMenuItem()
            item.show()
            self.append(item)

            item = create_menuitem(_("_Pair"), get_icon("dialog-password", 16))
            item.props.tooltip_text = _("Create pairing with the device")
            self.append(item)
            item.show()
            if not device.Paired:
                self.Signals.Handle("gobject", item, "activate",
                                    lambda x: self.Blueman.bond(device))
            else:
                item.props.sensitive = False

            if not device.Trusted:
                item = create_menuitem(_("_Trust"),
                                       get_icon("blueman-trust", 16))
                self.Signals.Handle(
                    "gobject", item, "activate",
                    lambda x: self.Blueman.toggle_trust(device))
                self.append(item)
                item.show()
            else:
                item = create_menuitem(_("_Untrust"),
                                       get_icon("blueman-untrust", 16))
                self.append(item)
                self.Signals.Handle(
                    "gobject", item, "activate",
                    lambda x: self.Blueman.toggle_trust(device))
                item.show()
            item.props.tooltip_text = _("Mark/Unmark this device as trusted")

            item = create_menuitem(_("_Setup..."),
                                   get_icon("document-properties", 16))
            self.append(item)
            self.Signals.Handle("gobject", item, "activate",
                                lambda x: self.Blueman.setup(device))
            item.show()
            item.props.tooltip_text = _(
                "Run the setup assistant for this device")

            def on_rename(_item, device):
                def on_response(dialog, response_id):
                    if response_id == Gtk.ResponseType.ACCEPT:
                        device.set('Alias', alias_entry.get_text())
                    elif response_id == 1:
                        device.set('Alias', '')
                    dialog.destroy()

                builder = Gtk.Builder()
                builder.set_translation_domain("blueman")
                builder.add_from_file(UI_PATH + "/rename-device.ui")
                dialog = builder.get_object("dialog")
                dialog.set_transient_for(self.Blueman.window)
                dialog.props.icon_name = "blueman"
                alias_entry = builder.get_object("alias_entry")
                alias_entry.set_text(device.Alias)
                dialog.connect("response", on_response)
                dialog.present()

            item = Gtk.MenuItem.new_with_label("Rename device...")
            self.Signals.Handle(item, 'activate', on_rename, device)
            self.append(item)
            item.show()

            item = Gtk.SeparatorMenuItem()
            item.show()
            self.append(item)

            item = create_menuitem(_("_Remove..."),
                                   get_icon("edit-delete", 16))
            self.Signals.Handle(item, "activate",
                                lambda x: self.Blueman.remove(device))
            self.append(item)
            item.show()
            item.props.tooltip_text = _(
                "Remove this device from the known devices list")

            item = Gtk.SeparatorMenuItem()
            item.show()
            self.append(item)

            item = create_menuitem(_("_Disconnect"),
                                   get_icon("network-offline", 16))
            item.props.tooltip_text = _("Forcefully disconnect the device")

            self.append(item)
            item.show()

            def on_disconnect(item):
                def finished(*args):
                    self.unset_op(device)

                self.set_op(device, _("Disconnecting..."))
                self.Blueman.disconnect(device,
                                        reply_handler=finished,
                                        error_handler=finished)

            if device.Connected:
                self.Signals.Handle(item, "activate", on_disconnect)

            else:
                item.props.sensitive = False
예제 #26
0
class SourceRedirector:
    instances = []

    def __init__(self, module_id, device_path, pa_utils):
        if module_id in SourceRedirector.instances:
            return
        else:
            SourceRedirector.instances.append(module_id)

        self.module_id = module_id
        self.pa_utils = pa_utils
        self.device = Device(device_path)
        self.signals = SignalTracker()
        self.bus = dbus.SystemBus()
        self.signals.Handle("dbus",
                            self.bus,
                            self.on_source_prop_change,
                            "PropertyChanged",
                            "org.bluez.AudioSource",
                            path=device_path)

        self.pacat = None
        self.parec = None
        self.loopback_id = None

        dprint("Starting source redirector")

        def sources_cb(sources):
            for k, v in sources.iteritems():
                props = v["proplist"]
                if "bluetooth.protocol" in props:
                    if props["bluetooth.protocol"] == "a2dp_source":
                        if v["owner_module"] == self.module_id:
                            dprint("Found source", k)
                            self.start_redirect(k)
                            return
            dprint("Source not found :(")

        self.pa_utils.ListSources(sources_cb)

    def start_redirect(self, source):
        def on_load(res):
            dprint("module-loopback load result", res)
            if res < 0:
                self.parec = Popen(["parec", "-d", str(source)], stdout=PIPE)
                self.pacat = Popen([
                    "pacat", "--client-name=Blueman",
                    "--stream-name=%s" % self.device.Address,
                    "--property=application.icon_name=blueman"
                ],
                                   stdin=self.parec.stdout)
            else:
                self.loopback_id = res

        self.pa_utils.LoadModule("module-loopback", "source=%d" % source,
                                 on_load)

    def on_source_prop_change(self, key, value):
        if key == "State":
            if value == "disconnected":
                if self.pacat:
                    self.pacat.terminate()
                if self.parec:
                    self.parec.terminate()
                if self.loopback_id:
                    self.pa_utils.UnloadModule(
                        self.loopback_id,
                        lambda x: dprint("Loopback module unload result", x))

                self.signals.DisconnectAll()

                SourceRedirector.instances.remove(self.module_id)

                del self.pa_utils

    def __del__(self):
        dprint("Destroying redirector")
예제 #27
0
class ManagerProgressbar(GObject.GObject):
    __gsignals__ = {
        'cancelled': (GObject.SignalFlags.RUN_LAST, None, ()),
    }
    __instances__ = []

    def __init__(self, blueman, cancellable=True, text=_("Connecting")):
        def on_enter(evbox, event):
            c = Gdk.Cursor.new(Gdk.CursorType.HAND2)
            self.window.get_window().set_cursor(c)

        def on_leave(evbox, event):
            self.window.get_window().set_cursor(None)

        def on_clicked(evbox, event):
            self.eventbox.props.sensitive = False
            self.emit("cancelled")

        GObject.GObject.__init__(self)
        self.Blueman = blueman

        self.cancellable = cancellable

        self.hbox = hbox = blueman.Builder.get_object("statusbar1")

        self.progressbar = Gtk.ProgressBar()

        self.signals = SignalTracker()

        self.button = Gtk.Image.new_from_pixbuf(get_icon("process-stop", 16))

        self.eventbox = eventbox = Gtk.EventBox()
        eventbox.add(self.button)
        eventbox.props.tooltip_text = _("Cancel Operation")
        self.signals.Handle(eventbox, "enter-notify-event", on_enter)
        self.signals.Handle(eventbox, "leave-notify-event", on_leave)
        self.signals.Handle(eventbox, "button-press-event", on_clicked)

        self.progressbar.set_size_request(100, 15)
        self.progressbar.set_ellipsize(Pango.EllipsizeMode.END)
        self.progressbar.set_text(text)
        self.progressbar.set_pulse_step(0.05)

        self.window = blueman.Builder.get_object("window")

        hbox.pack_end(eventbox, True, False, 0)
        hbox.pack_end(self.progressbar, False, False, 0)

        if ManagerProgressbar.__instances__ != []:
            dprint("hiding", ManagerProgressbar.__instances__[-1])
            ManagerProgressbar.__instances__[-1].hide()

        self.show()
        if not self.cancellable:
            self.eventbox.props.sensitive = False

        self.gsource = None
        self.finalized = False

        ManagerProgressbar.__instances__.append(self)

    def connect(self, *args):
        self.signals.Handle("gobject", super(ManagerProgressbar, self), *args)

    def show(self):
        if self.Blueman.Config.props.show_statusbar == False:
            self.Blueman.Builder.get_object("statusbar").props.visible = True

        # if self.Blueman.Stats.hbox.size_request()[0] + self.progressbar.size_request()[0] + 16 > self.Blueman.window.get_size()[0]:
        #	self.Blueman.Stats.hbox.hide_all()

        self.progressbar.props.visible = True
        self.eventbox.props.visible = True
        self.button.props.visible = True

    def hide(self):
        self.Blueman.Stats.hbox.show_all()
        self.progressbar.props.visible = False
        self.eventbox.props.visible = False
        self.button.props.visible = False

    def message(self, msg, timeout=1500):
        self.stop()
        self.set_label(msg)
        self.set_cancellable(False)
        GObject.timeout_add(timeout, self.finalize)

    def finalize(self):
        if not self.finalized:
            self.hide()
            self.stop()
            Gdk.Window.set_cursor(self.window.get_window(), None)
            self.hbox.remove(self.eventbox)
            self.hbox.remove(self.progressbar)
            # self.hbox.remove(self.seperator)
            self.finalized = True

            if ManagerProgressbar.__instances__[-1] == self:
                ManagerProgressbar.__instances__.pop()
                #remove all finalized instances
                for inst in reversed(ManagerProgressbar.__instances__):
                    if inst.finalized:
                        ManagerProgressbar.__instances__.pop()
                    else:
                        #show last active progress bar
                        inst.show()
                        break

            if ManagerProgressbar.__instances__ == []:
                if self.Blueman.Config.props.show_statusbar == False:
                    self.Blueman.Builder.get_object(
                        "statusbar").props.visible = False

            self.signals.DisconnectAll()

    def set_cancellable(self, b, hide=False):
        if b:
            self.eventbox.props.visible = True
            self.eventbox.props.sensitive = True
        else:
            if hide:
                self.eventbox.props.visible = False
            else:
                self.eventbox.props.sensitive = False

    def set_label(self, label):
        self.progressbar.props.text = label

    def fraction(self, frac):
        if not self.finalized:
            self.progressbar.set_fraction(frac)

    def started(self):
        return self.gsource != None

    def start(self):
        def pulse():
            self.progressbar.pulse()
            return True

        if not self.gsource:
            self.gsource = GObject.timeout_add(1000 / 24, pulse)

    def stop(self):
        if self.gsource != None:
            GObject.source_remove(self.gsource)
        self.progressbar.set_fraction(0.0)
예제 #28
0
class DiscvManager(AppletPlugin):
    __depends__ = ["Menu"]
    __author__ = "Walmis"
    __icon__ = "edit-find"
    __description__ = _(
        "Provides a menu item for making the default adapter temporarily visible when it is set to hidden by default"
    )

    __gsettings__ = {
        "schema": "org.blueman.plugins.discvmanager",
        "path": None
    }
    __options__ = {
        "time": {
            "type": int,
            "default": 60,
            "name": _("Discoverable timeout"),
            "desc": _("Amount of time in seconds discoverable mode will last"),
            "range": (60, 600)
        }
    }

    def on_load(self, applet):
        self.Signals = SignalTracker()

        self.item = create_menuitem(_("_Make Discoverable"),
                                    get_icon("edit-find", 16))
        self.item_label = self.item.get_child().get_children()[1]
        applet.Plugins.Menu.Register(self, self.item, 20, False)

        self.Applet = applet
        self.adapter = None
        self.time_left = -1

        self.Signals.Handle(self.item, "activate", self.on_set_discoverable)
        self.item.props.tooltip_text = _(
            "Make the default adapter temporarily visible")

        self.timeout = None

    def on_unload(self):
        self.Applet.Plugins.Menu.Unregister(self)
        del self.item

        if self.timeout:
            GObject.source_remove(self.timeout)

        self.Signals.DisconnectAll()

    def on_manager_state_changed(self, state):
        if state:
            self.init_adapter()
            self.update_menuitems()
        else:
            self.Signals.Disconnect(0)

            self.adapter = None
            self.update_menuitems()

    def on_update(self):
        self.time_left -= 1
        self.item_label.set_text_with_mnemonic(
            _("Discoverable... %ss") % self.time_left)
        self.item.props.sensitive = False

        return True

    def on_set_discoverable(self, item):
        if self.adapter:
            self.adapter.set("Discoverable", True)
            self.adapter.set("DiscoverableTimeout", self.get_option("time"))

    def init_adapter(self):
        try:
            self.adapter = self.Applet.Manager.get_adapter()
        except:
            self.adapter = None

    def on_adapter_removed(self, path):
        dprint(path)
        if path == self.adapter.get_object_path():
            self.init_adapter()
            self.update_menuitems()

    def on_adapter_property_changed(self, path, key, value):
        if self.adapter and path == self.adapter.get_object_path():
            dprint("prop", key, value)
            if key == "DiscoverableTimeout":
                if value == 0:  #always visible
                    if self.timeout != None:
                        GObject.source_remove(self.timeout)
                    self.time_left = -1
                    self.timeout = None
                else:
                    if self.time_left > -1:
                        if self.timeout != None:
                            GObject.source_remove(self.timeout)
                    self.time_left = value

                    self.timeout = GObject.timeout_add(1000, self.on_update)
                    return

            elif (key == "Discoverable" and not value) or (key == "Powered"
                                                           and not value):
                dprint("Stop")
                if self.timeout != None:
                    GObject.source_remove(self.timeout)
                self.time_left = -1
                self.timeout = None

            self.update_menuitems()

    def update_menuitems(self):
        try:
            props = self.adapter.get_properties()
        except Exception as e:
            dprint("warning: Adapter is None")
            self.item.props.visible = False
        else:
            if (not props["Discoverable"]
                    or props["DiscoverableTimeout"] > 0) and props["Powered"]:

                self.item.props.visible = True
                self.item_label.set_text_with_mnemonic(_("_Make Discoverable"))
                self.item.props.sensitive = True

            else:
                self.item.props.visible = False
예제 #29
0
class GameControllerWakelock(AppletPlugin):
    __description__ = _(
        "Temporarily suspends the screensaver when a bluetooth game controller is connected."
    )
    __author__ = "bwRavencl"
    __icon__ = "input-gaming"

    def on_load(self, applet):
        self.wake_lock = 0
        self.root_window_id = "0x%x" % Gdk.Screen.get_default(
        ).get_root_window().get_xid()

        self.signals = SignalTracker()
        self.signals.Handle("bluez",
                            bluez.Device(),
                            self.on_device_property_changed,
                            "PropertyChanged",
                            path_keyword="path")

    def on_unload(self):
        if self.wake_lock:
            self.wake_lock = 1
            self.xdg_screensaver("resume")
        self.signals.DisconnectAll()

    def on_device_property_changed(self, key, value, path):
        if key == "Connected":
            props = Device(path).get_properties()
            if not "Class" in props:
                return

            klass = props["Class"] & 0x1fff

            if klass == 0x504 or klass == 0x508:
                if value:
                    self.xdg_screensaver("suspend")
                else:
                    self.xdg_screensaver("resume")

    def xdg_screensaver(self, action):
        if action == "resume":
            if self.wake_lock == 0:
                pass
            elif self.wake_lock > 1:
                self.wake_lock -= 1
                pass
        elif action == "suspend" and self.wake_lock >= 1:
            self.wake_lock += 1
            pass

        command = "xdg-screensaver %s %s" % (action, self.root_window_id)

        try:
            ret = launch(command, sn=False)

            if not ret:
                dprint("%s failed")
                pass

            if action == "suspend":
                self.wake_lock += 1
            elif action == "resume":
                self.wake_lock = 0
        except:
            dprint(traceback.format_exc())
예제 #30
0
class PowerManager(AppletPlugin):
    __depends__ = ["StatusIcon", "Menu"]
    __unloadable__ = True
    __description__ = _("Controls Bluetooth adapter power states")
    __author__ = "Walmis"
    __icon__ = "gnome-power-manager"

    __gsettings__ = {
        "schema": "org.blueman.plugins.powermanager",
        "path": None
    }

    __options__ = {
        "auto-power-on": {
            "type": bool,
            "default": True,
            "name": _("Auto power-on"),
            "desc": _("Automatically power on adapters")
        }
    }

    def on_load(self, applet):
        AppletPlugin.add_method(self.on_power_state_query)
        AppletPlugin.add_method(self.on_power_state_change_requested)
        AppletPlugin.add_method(self.on_power_state_changed)

        self.Applet = applet

        self.item = create_menuitem("Should be overwritten", get_icon("blueman-disabled", 16))
        self.item.get_child().get_children()[1].set_markup_with_mnemonic(_("<b>Bluetooth _Off</b>"))

        self.item.props.tooltip_text = _("Turn off all adapters")

        self.signals = SignalTracker()
        self.signals.Handle('bluez', Bluez.Adapter(), self.adapter_property_changed, "PropertyChanged",
                            path_keyword="path")

        self.signals.Handle(self.item, "activate", lambda x: self.on_bluetooth_toggled())

        self.Applet.Plugins.Menu.Register(self, self.item, 0)

        self.adapter_state = True
        self.current_state = True

        self.request_in_progress = False

        self.STATE_ON = 2
        self.STATE_OFF = 1
        self.STATE_OFF_FORCED = 0

    def on_unload(self):
        self.signals.DisconnectAll()
        self.Applet.Plugins.Menu.Unregister(self)

    @property
    def CurrentState(self):
        return self.current_state

    def on_manager_state_changed(self, state):
        if state:
            def timeout():
                self.adapter_state = self.get_adapter_state()
                if self.get_option("auto-power-on"):
                    self.RequestPowerState(True, force=True)
                else:
                    self.RequestPowerState(self.adapter_state)

            GObject.timeout_add(1000, timeout)

    def get_adapter_state(self):
        adapters = self.Applet.Manager.list_adapters()
        for adapter in adapters:
            props = adapter.get_properties()
            if not props["Powered"]:
                return False
        return bool(adapters)

    def set_adapter_state(self, state):
        try:
            dprint(state)
            adapters = self.Applet.Manager.list_adapters()
            for adapter in adapters:
                adapter.set("Powered", state)

            self.adapter_state = state
        except Exception as e:
            dprint("Exception occurred", e)


    class Callback(object):
        def __init__(self, parent, state):
            self.parent = parent
            self.num_cb = 0
            self.called = 0
            self.state = state
            self.success = False
            self.timer = GObject.timeout_add(5000, self.timeout)

        def __call__(self, result):
            self.called += 1

            if result:
                self.success = True

            self.check()

        def check(self):
            if self.called == self.num_cb:
                dprint("callbacks done")
                self.parent.set_adapter_state(self.state)
                GObject.source_remove(self.timer)
                self.parent.request_in_progress = False

        def timeout(self):
            dprint("Timeout reached while setting power state")
            self.parent.UpdatePowerState()
            self.parent.request_in_progress = False

    def RequestPowerState(self, state, force=False):
        if self.current_state != state or force:
            if not self.request_in_progress:
                self.request_in_progress = True
                dprint("Requesting", state)
                cb = PowerManager.Callback(self, state)

                rets = self.Applet.Plugins.Run("on_power_state_change_requested", self, state, cb)
                cb.num_cb = len(rets)
                cb.check()
                self.UpdatePowerState()
            else:
                dprint("Another request in progress")

    def on_power_state_change_requested(self, pm, state, cb):
        cb(None)

    def on_power_state_query(self, pm):
        if self.adapter_state:
            return self.STATE_ON
        else:
            return self.STATE_OFF

    def on_power_state_changed(self, manager, state):
        pass


    #queries other plugins to determine the current power state
    def UpdatePowerState(self):
        rets = self.Applet.Plugins.Run("on_power_state_query", self)

        off = True in map(lambda x: x < self.STATE_ON, rets)
        foff = self.STATE_OFF_FORCED in rets
        on = self.STATE_ON in rets

        icon, label = self.item.get_child().get_children()

        new_state = True
        if foff or off:

            label.set_markup_with_mnemonic(_("<b>Turn Bluetooth _On</b>"))
            icon.set_from_pixbuf(get_icon("blueman", 16))
            self.item.props.tooltip_text = _("Turn on all adapters")

            if foff:
                self.item.props.sensitive = False
            else:
                self.item.props.sensitive = True

            new_state = False

        elif on and self.current_state != True:

            label.set_markup_with_mnemonic(_("<b>Turn Bluetooth _Off</b>"))
            icon.set_from_pixbuf(get_icon("blueman-disabled", 16))
            self.item.props.tooltip_text = _("Turn off all adapters")
            self.item.props.sensitive = True

            new_state = True

        dprint("off", off, "\nfoff", foff, "\non", on, "\ncurrent state", self.current_state, "\nnew state", new_state)

        if self.current_state != new_state:
            dprint("Signalling", new_state)
            self.current_state = new_state

            self.BluetoothStatusChanged(new_state)
            self.Applet.Plugins.Run("on_power_state_changed", self, new_state)
            self.Applet.Plugins.StatusIcon.IconShouldChange()

    @dbus.service.signal('org.blueman.Applet', signature="b")
    def BluetoothStatusChanged(self, status):
        pass

    @dbus.service.method('org.blueman.Applet', in_signature="b", out_signature="")
    def SetBluetoothStatus(self, status):
        self.RequestPowerState(status)

    @dbus.service.method('org.blueman.Applet', in_signature="", out_signature="b")
    def GetBluetoothStatus(self):
        return self.CurrentState

    def adapter_property_changed(self, key, value, path):
        if key == "Powered":
            if value and not self.CurrentState:
                dprint("adapter powered on while in off state, turning bluetooth on")
                self.RequestPowerState(True)

            self.UpdatePowerState()

    def on_bluetooth_toggled(self):
        self.RequestPowerState(not self.CurrentState)

    def on_status_icon_query_icon(self):
        if not self.GetBluetoothStatus():
            return "blueman-disabled", "blueman-disabled"

    def on_adapter_added(self, path):
        adapter = Bluez.Adapter(path)

        def on_ready():
            if not self.adapter_state:
                adapter.set("Powered", False)
            else:
                adapter.set("Powered", True)

        wait_for_adapter(adapter, on_ready)