Example #1
0
    def bond(device: Device) -> None:
        def error_handler(e: Exception) -> None:
            logging.exception(e)
            message = f"Pairing failed for:\n{device['Alias']} ({device['Address']})"
            Notification('Bluetooth', message, icon_name="blueman").show()

        device.pair(error_handler=error_handler)
Example #2
0
    def _disconnect_service(
        self, object_path: str, uuid: str, port: int, ok: Callable[[], None],
        err: Callable[
            [Union[BluezDBusException, "NMConnectionError", GLib.Error,
                   str]], None]
    ) -> None:
        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(obj_path=object_path)
            device.disconnect(reply_handler=ok, error_handler=err)
        else:
            service = get_service(Device(obj_path=object_path), uuid)
            assert service is not None

            if any(
                    plugin.service_disconnect_handler(service, ok, err)
                    for plugin in self.parent.Plugins.get_loaded_plugins(
                        ServiceConnectHandler)):
                pass
            elif isinstance(service, SerialService):
                service.disconnect(port, reply_handler=ok, error_handler=err)

                for plugin in self.parent.Plugins.get_loaded_plugins(
                        RFCOMMConnectedListener):
                    plugin.on_rfcomm_disconnect(port)

                logging.info("Disconnecting rfcomm device")
            elif isinstance(service, NetworkService):
                service.disconnect(reply_handler=ok, error_handler=err)
Example #3
0
    def _disconnect_service(
        self, object_path: str, uuid: str, port: int, ok: Callable[[], None],
        err: Callable[
            [Union[BluezDBusException, NMConnectionError, GLib.Error,
                   str]], None]
    ) -> None:
        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(obj_path=object_path)
            device.disconnect(reply_handler=ok, error_handler=err)
        else:

            def cb(_inst, ret):
                if ret:
                    raise StopException

            service = get_service(Device(obj_path=object_path), uuid)
            assert service is not None

            if isinstance(
                    service, SerialService
            ) and 'NMDUNSupport' in self.parent.Plugins.get_loaded():
                self.parent.Plugins.run_ex("service_disconnect_handler", cb,
                                           service, ok, err)
            elif isinstance(
                    service, SerialService
            ) and 'PPPSupport' in self.parent.Plugins.get_loaded():
                service.disconnect(port, reply_handler=ok, error_handler=err)

                self.parent.Plugins.run("on_rfcomm_disconnect", port)

                logging.info("Disconnecting rfcomm device")
            else:
                if not self.parent.Plugins.run_ex("service_disconnect_handler", cb, service, ok, err) \
                        and isinstance(service, NetworkService):
                    service.disconnect(reply_handler=ok, error_handler=err)
Example #4
0
    def connect_service(self, object_path, uuid, ok, err):
        try:
            self.parent.Plugins.RecentConns
        except KeyError:
            logging.warning("RecentConns plugin is unavailable")
        else:
            self.parent.Plugins.RecentConns.notify(object_path, uuid)

        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(object_path)
            device.connect(reply_handler=ok, error_handler=err)
        else:
            service = get_service(Device(object_path), uuid)

            if service.group == 'serial':
                def reply(rfcomm):
                    self.parent.Plugins.run("on_rfcomm_connected", service, rfcomm)
                    ok(rfcomm)

                rets = self.parent.Plugins.run("rfcomm_connect_handler", service, reply, err)
                if True in rets:
                    pass
                else:
                    logging.info("No handler registered")
                    err(dbus.DBusException(
                        "Service not supported\nPossibly the plugin that handles this service is not loaded"))
            else:
                def cb(_inst, ret):
                    if ret:
                        raise StopException

                if not self.parent.Plugins.run_ex("service_connect_handler", cb, service, ok, err):
                    service.connect(reply_handler=ok, error_handler=err)
Example #5
0
    def connect_service(self, object_path: str, uuid: str, ok: Callable[[], None],
                        err: Callable[[Union[BluezDBusException, NMConnectionError,
                                             RFCOMMError, GLib.Error, str]], None]) -> None:
        try:
            self.parent.Plugins.RecentConns
        except KeyError:
            logging.warning("RecentConns plugin is unavailable")
        else:
            self.parent.Plugins.RecentConns.notify(object_path, uuid)

        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(obj_path=object_path)
            device.connect(reply_handler=ok, error_handler=err)
        else:
            service = get_service(Device(obj_path=object_path), uuid)
            assert service is not None

            if any(plugin.service_connect_handler(service, ok, err)
                   for plugin in self.parent.Plugins.get_loaded_plugins(ServiceConnectHandler)):
                pass
            elif isinstance(service, SerialService):
                def reply(rfcomm: str) -> None:
                    assert isinstance(service, SerialService)  # https://github.com/python/mypy/issues/2608
                    for plugin in self.parent.Plugins.get_loaded_plugins(RFCOMMConnectedListener):
                        plugin.on_rfcomm_connected(service, rfcomm)
                    ok()

                if not any(plugin.rfcomm_connect_handler(service, reply, err)
                           for plugin in self.parent.Plugins.get_loaded_plugins(RFCOMMConnectHandler)):
                    service.connect(reply_handler=lambda port: ok(), error_handler=err)
            elif isinstance(service, NetworkService):
                service.connect(reply_handler=lambda interface: ok(), error_handler=err)
            else:
                logging.info("No handler registered")
                err("Service not supported\nPossibly the plugin that handles this service is not loaded")
Example #6
0
    def connect_service(self, object_path, uuid, ok, err):
        try:
            self.Applet.Plugins.RecentConns
        except KeyError:
            logging.warning("RecentConns plugin is unavailable")
        else:
            self.Applet.Plugins.RecentConns.notify(object_path, uuid)

        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(object_path)
            device.connect(reply_handler=ok, error_handler=err)
        else:
            service = get_service(Device(object_path), uuid)

            if service.group == 'serial':
                def reply(rfcomm):
                    self.Applet.Plugins.Run("on_rfcomm_connected", service, rfcomm)
                    ok(rfcomm)

                rets = self.Applet.Plugins.Run("rfcomm_connect_handler", service, reply, err)
                if True in rets:
                    pass
                else:
                    logging.info("No handler registered")
                    err(dbus.DBusException(
                        "Service not supported\nPossibly the plugin that handles this service is not loaded"))
            else:
                def cb(_inst, ret):
                    if ret:
                        raise StopException

                if not self.Applet.Plugins.RunEx("service_connect_handler", cb, service, ok, err):
                    service.connect(reply_handler=ok, error_handler=err)
Example #7
0
    def _disconnect_service(self, object_path, uuid, port, ok, err):
        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(object_path)
            device.disconnect(reply_handler=ok, error_handler=err)
        else:

            def cb(_inst, ret):
                if ret:
                    raise StopException

            service = get_service(Device(object_path), uuid)

            if service.group == 'serial' and 'NMDUNSupport' in self.parent.Plugins.get_loaded(
            ):
                self.parent.Plugins.run_ex("service_disconnect_handler", cb,
                                           service, ok, err)
            elif service.group == 'serial' and 'PPPSupport' in self.parent.Plugins.get_loaded(
            ):
                service.disconnect(port, reply_handler=ok, error_handler=err)

                self.parent.Plugins.run("on_rfcomm_disconnect", port)

                logging.info("Disconnecting rfcomm device")
            else:
                if not self.parent.Plugins.run_ex("service_disconnect_handler",
                                                  cb, service, ok, err):
                    service.disconnect(reply_handler=ok, error_handler=err)
Example #8
0
    def _on_display_pin_code(self, device: str, pin_code: str) -> None:
        logging.info(f'DisplayPinCode ({device}, {pin_code})')
        dev = Device(obj_path=device)
        self._devhandlerids[device] = dev.connect_signal("property-changed", self._on_device_property_changed)

        notify_message = _("Pairing PIN code for") + f" {self.get_device_string(device)}: {pin_code}"
        self._notification = Notification("Bluetooth", notify_message, 0, icon_name="blueman")
        self._notification.show()
Example #9
0
    def _on_display_pin_code(self, device, pin_code):
        logging.info('DisplayPinCode (%s, %s)' % (device, pin_code))
        dev = Device(obj_path=device)
        self._devhandlerids[device] = dev.connect_signal("property-changed", self._on_device_property_changed)

        notify_message = _("Pairing PIN code for") + " %s: %s" % (self.get_device_string(device), pin_code)
        self.n = Notification("Bluetooth", notify_message, 0, icon_name="blueman")
        self.n.show()
Example #10
0
        def on_auth_action(action):
            logging.info(action)

            if action == "always":
                device = Device(obj_path=n._device)
                device.set("Trusted", True)
            if action == "always" or action == "accept":
                ok()
            else:
                err(BluezErrorRejected("Rejected"))
Example #11
0
    def _on_display_passkey(self, device: str, passkey: int, entered: int) -> None:
        logging.info(f"DisplayPasskey ({device}, {passkey:d} {entered:d})")
        dev = Device(obj_path=device)
        self._devhandlerids[device] = dev.connect_signal("property-changed", self._on_device_property_changed)

        key = f"{passkey:06}"
        notify_message = _("Pairing passkey for") + f" {self.get_device_string(device)}: " \
                                                    f"{key[:entered]}<b>{key[entered]}</b>{key[entered+1:]}"
        self._close()
        self._notification = Notification("Bluetooth", notify_message, 0, icon_name="blueman")
        self._notification.show()
Example #12
0
 def list_devices(self):
     if self.__class__.get_interface_version()[0] < 5:
         devices = self.get_interface().ListDevices()
         return [Device(device) for device in devices]
     else:
         objects = self.manager_interface.GetManagedObjects()
         devices = []
         for path, interfaces in objects.items():
             if 'org.bluez.Device1' in interfaces:
                 devices.append(path)
         return [Device(device) for device in devices]
Example #13
0
    def connect_service(
        self, object_path: str, uuid: str, ok: Callable[[], None],
        err: Callable[[
            Union[BluezDBusException, NMConnectionError, RFCOMMError,
                  GLib.Error, str]
        ], None]
    ) -> None:
        try:
            self.parent.Plugins.RecentConns
        except KeyError:
            logging.warning("RecentConns plugin is unavailable")
        else:
            self.parent.Plugins.RecentConns.notify(object_path, uuid)

        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(obj_path=object_path)
            device.connect(reply_handler=ok, error_handler=err)
        else:

            def cb(_inst, ret):
                if ret:
                    raise StopException

            service = get_service(Device(obj_path=object_path), uuid)
            assert service is not None

            if isinstance(
                    service, SerialService
            ) and 'NMDUNSupport' in self.parent.Plugins.get_loaded():
                self.parent.Plugins.run_ex("service_connect_handler", cb,
                                           service, ok, err)
            elif isinstance(
                    service, SerialService
            ) and 'PPPSupport' in self.parent.Plugins.get_loaded():

                def reply(rfcomm):
                    self.parent.Plugins.run("on_rfcomm_connected", service,
                                            rfcomm)
                    ok()

                rets = self.parent.Plugins.run("rfcomm_connect_handler",
                                               service, reply, err)
                if True in rets:
                    pass
                else:
                    logging.info("No handler registered")
                    err("Service not supported\nPossibly the plugin that handles this service is not loaded"
                        )
            else:
                if not self.parent.Plugins.run_ex("service_connect_handler", cb, service, ok, err) \
                        and isinstance(service, (SerialService, NetworkService)):
                    service.connect(reply_handler=lambda *args: ok(),
                                    error_handler=err)
Example #14
0
    def _on_display_passkey(self, device, passkey, _entered):
        logging.info('DisplayPasskey (%s, %d)' % (device, passkey))
        dev = Device(device)
        dev.connect_signal("property-changed",
                           self._on_device_property_changed)

        notify_message = _("Pairing passkey for") + " %s: %s" % (
            self.get_device_string(device), passkey)
        self.n = Notification("Bluetooth",
                              notify_message,
                              0,
                              icon_name="blueman")
        self.n.show()
Example #15
0
    def _on_display_passkey(self, device, passkey, _entered):
        logging.info(f"DisplayPasskey ({device}, {passkey:d})")
        dev = Device(obj_path=device)
        self._devhandlerids[device] = dev.connect_signal(
            "property-changed", self._on_device_property_changed)

        notify_message = _("Pairing passkey for"
                           ) + f" {self.get_device_string(device)}: {passkey}"
        self.n = Notification("Bluetooth",
                              notify_message,
                              0,
                              icon_name="blueman")
        self.n.show()
Example #16
0
    def create_paired_device(self,
                             address,
                             agent_path,
                             capability,
                             error_handler=None,
                             reply_handler=None,
                             timeout=120):
        # BlueZ 4 only!
        def reply_handler_wrapper(obj_path):
            if not callable(reply_handler):
                return
            reply_handler(Device(obj_path))

        def error_handler_wrapper(exception):
            exception = parse_dbus_error(exception)
            if not callable(error_handler):
                raise exception
            error_handler(exception)

        if reply_handler is None and error_handler is None:
            obj_path = self.get_interface().CreatePairedDevice(
                address, agent_path, capability)
            return Device(obj_path)
        else:
            self.get_interface().CreatePairedDevice(
                address,
                agent_path,
                capability,
                reply_handler=reply_handler_wrapper,
                error_handler=error_handler_wrapper,
                timeout=timeout)
Example #17
0
    def notify(self, object_path: str, uuid: str) -> None:
        device = Device(obj_path=object_path)
        logging.info(f"{device} {uuid}")
        try:
            adapter = self.parent.Manager.get_adapter(device['Adapter'])
        except DBusNoSuchAdapterError:
            logging.warning("adapter not found")
            return

        item: "Item" = {
            "adapter": adapter["Address"],
            "address": device['Address'],
            "alias": device['Alias'],
            "icon": device['Icon'],
            "name": ServiceUUID(uuid).name,
            "uuid": uuid,
            "time": time.time(),
            "device": object_path,
            "mitem": None
        }

        for i in self.items:
            if i["adapter"] == item["adapter"] and \
                    i["address"] == item["address"] and \
                    i["uuid"] == item["uuid"]:
                i["time"] = item["time"]

                i["device"] = item["device"]
                self.initialize()
                return

        self.items.append(item)
        self.initialize()

        self._store_state()
Example #18
0
    def notify(self, object_path, uuid):
        device = Device(obj_path=object_path)
        logging.info(f"{device} {uuid}")
        item = {}
        try:
            adapter = self.parent.Manager.get_adapter(device['Adapter'])
        except DBusNoSuchAdapterError:
            logging.warning("adapter not found")
            return

        item["adapter"] = adapter["Address"]
        item["address"] = device['Address']
        item["alias"] = device['Alias']
        item["icon"] = device['Icon']
        item["name"] = ServiceUUID(uuid).name
        item["uuid"] = uuid
        item["time"] = time.time()
        item["device"] = object_path
        item["mitem"] = None  # menu item object

        for i in self.items:
            if i["adapter"] == item["adapter"] and \
                    i["address"] == item["address"] and \
                    i["uuid"] == item["uuid"]:
                i["time"] = item["time"]

                i["device"] = item["device"]
                self.initialize()
                return

        self.items.append(item)
        self.initialize()

        self.store_state()
Example #19
0
    def notify(self, object_path, uuid):
        device = Device(object_path)
        logging.info("%s %s" % (device, uuid))
        item = {}
        try:
            adapter = Adapter(device['Adapter'])
        except:
            logging.warning("adapter not found")
            return

        item["adapter"] = adapter["Address"]
        item["address"] = device['Address']
        item["alias"] = device['Alias']
        item["icon"] = device['Icon']
        item["name"] = ServiceUUID(uuid).name
        item["uuid"] = uuid
        item["time"] = time.time()
        item["device"] = object_path
        item["mitem"] = None  #menu item object

        for i in self.items:
            if i["adapter"] == item["adapter"] and \
                            i["address"] == item["address"] and \
                            i["uuid"] == item["uuid"]:
                i["time"] = item["time"]

                i["device"] = item["device"]
                self.initialize()
                return

        self.items.append(item)
        self.initialize()

        self.store_state()
Example #20
0
    def disconnect_service(self,
                           device: Device,
                           uuid: str = GENERIC_CONNECT,
                           port: int = 0) -> None:
        def ok(_obj: AppletService, _result: None, _user_date: None) -> None:
            logging.info("disconnect success")
            self.generate()

        def err(_obj: Optional[AppletService], result: GLib.Error,
                _user_date: None) -> None:
            logging.warning(f"disconnect failed {result}")
            msg, tb = e_(result.message)
            MessageArea.show_message(_("Disconnection Failed: ") + msg, tb)
            self.generate()

        if self._appl is None:
            err(None, GLib.Error('Applet DBus Service not available'), None)
            return

        self._appl.DisconnectService('(osd)',
                                     device.get_object_path(),
                                     uuid,
                                     port,
                                     result_handler=ok,
                                     error_handler=err,
                                     timeout=GLib.MAXINT)
Example #21
0
 def list_devices(self):
     objects = self.manager_interface.GetManagedObjects()
     devices = []
     for path, interfaces in objects.items():
         if 'org.bluez.Device1' in interfaces:
             devices.append(path)
     return [Device(device) for device in devices]
Example #22
0
    def __init__(self, instance):
        GObject.GObject.__init__(self)

        self.Properties = {}
        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.Valid = True

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

        w = weakref.ref(self)
        self._obj_path = self.Device.get_object_path()
        self.Device.connect_signal('property-changed',
                                   lambda _device, key, value: w() and w().property_changed(key, value))
        self._any_adapter = Adapter()
        self._any_adapter.connect_signal('device-removed',
                                         lambda _adapter, path: w() and w().on_device_removed(path))
Example #23
0
    def notify(self, object_path: str, uuid: str) -> None:
        device = Device(obj_path=object_path)
        logging.info(f"{device} {uuid}")
        try:
            adapter = self.parent.Manager.get_adapter(device['Adapter'])
        except DBusNoSuchAdapterError:
            logging.warning("adapter not found")
            return

        item = {
            "adapter": adapter["Address"],
            "address": device['Address'],
            "alias": device['Alias'],
            "icon": device['Icon'],
            "name": ServiceUUID(uuid).name,
            "uuid": uuid,
            "time": str(time.time()),
        }

        stored_items = self.get_option("recent-connections")

        for i in stored_items:
            if i["adapter"] == item["adapter"] and \
                    i["address"] == item["address"] and \
                    i["uuid"] == item["uuid"]:
                i["time"] = item["time"]
                i["device"] = object_path
                break
        else:
            stored_items.append(item)

        self.set_option("recent-connections", stored_items)

        self._rebuild()
Example #24
0
    def __on_manager_signal(self, manager, path, signal_name):
        if signal_name == 'adapter-removed':
            self.emit("adapter-removed", path)
            if path == self.__adapter_path:
                self.clear()
                self.Adapter = None
                self.set_adapter()

        if signal_name == 'adapter-added':
            if self.Adapter is None:
                self.set_adapter(path)

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

        if signal_name == 'device-created':
            tree_iter = self.find_device_by_path(path)
            if tree_iter is None:
                dev = Device(obj_path=path)
                self.device_add_event(dev)

        if signal_name == 'device-removed':
            tree_iter = self.find_device_by_path(path)
            if tree_iter:
                row = self.get(tree_iter, "device")
                dev = row["device"]

                self.device_remove_event(dev)
Example #25
0
 def on_device_property_changed(self, path: str, key: str,
                                value: Any) -> None:
     if key == "ServicesResolved" and value:
         device = Device(obj_path=path)
         if self.applicable(device):
             text = "%d%%" % BluezBattery(obj_path=path)["Percentage"]
             Notification(device["Alias"], text, icon_name="battery").show()
Example #26
0
 def set_op(self, device: Device, message: str) -> None:
     ManagerDeviceMenu.__ops__[device.get_object_path()] = message
     for inst in ManagerDeviceMenu.__instances__:
         logging.info(f"op: regenerating instance {inst}")
         if inst.SelectedDevice == self.SelectedDevice and not (
                 inst.is_popup and not inst.props.visible):
             inst.generate()
Example #27
0
    def generic_connect(self, _item: Optional[Gtk.MenuItem], device: Device,
                        connect: bool) -> None:
        def fail(_obj: AppletService, result: GLib.Error,
                 _user_data: None) -> None:
            logging.info(f"fail: {result}")
            prog.message(_("Failed"))
            self.unset_op(device)
            self._handle_error_message(result.message)

        def success(_obj: AppletService, _result: None,
                    _user_data: None) -> None:
            logging.info("success")
            prog.message(_("Success!"))
            MessageArea.close()
            self.unset_op(device)

        assert self._appl

        if connect:
            self.set_op(self.SelectedDevice, _("Connecting…"))
            self._appl.ConnectService("(os)",
                                      device.get_object_path(),
                                      '00000000-0000-0000-0000-000000000000',
                                      result_handler=success,
                                      error_handler=fail,
                                      timeout=GLib.MAXINT)
        else:
            self.set_op(self.SelectedDevice, _("Disconnecting…"))
            self._appl.DisconnectService(
                "(osd)",
                device.get_object_path(),
                '00000000-0000-0000-0000-000000000000',
                0,
                result_handler=success,
                error_handler=fail,
                timeout=GLib.MAXINT)

        prog = ManagerProgressbar(self.Blueman)

        def abort() -> None:
            assert self._appl is not None  # https://github.com/python/mypy/issues/2608
            self._appl.DisconnectService(
                "(osd)", device.get_object_path(),
                '00000000-0000-0000-0000-000000000000', 0)

        prog.connect("cancelled", lambda x: abort())
        prog.start()
Example #28
0
    def on_device_property_changed(self, path: str, key: str, value: Any) -> None:
        if key == "Connected":
            device = Device(obj_path=path)
            if value and "Battery" in self.parent.Plugins.get_loaded() and Battery.applicable(device):
                return

            Notification(device["Alias"], _("Connected") if value else _("Disconnected"),
                         icon_name=device["Icon"]).show()
Example #29
0
 def list_devices(self):
     objects = self._call('GetManagedObjects', interface=self.manager_interface)
     devices = []
     for path, interfaces in objects.items():
         if 'org.bluez.Device1' in interfaces:
             if path.startswith(self.get_object_path()):
                 devices.append(path)
     return [Device(device) for device in devices]
    def on_device_property_changed(self, path, key, value):
        if key == "Connected":
            klass = Device(path)["Class"] & 0x1fff

            if klass == 0x504 or klass == 0x508:
                if value:
                    self.xdg_screensaver("suspend")
                else:
                    self.xdg_screensaver("resume")
Example #31
0
    def DisconnectDevice(self, obj_path, ok, err):
        dev = Device(BluezDevice(obj_path))

        self.Applet.Plugins.Run("on_device_disconnect", dev)

        def on_timeout():
            dev.Device.disconnect(reply_handler=ok, error_handler=err)

        GLib.timeout_add(1000, on_timeout)
Example #32
0
    def disconnect_service(self, object_path, uuid, port, ok, err):
        if uuid == '00000000-0000-0000-0000-000000000000':
            device = Device(object_path)
            device.disconnect(reply_handler=ok, error_handler=err)
        else:
            service = get_service(Device(object_path), uuid)

            if service.group == 'serial':
                service.disconnect(port)

                self.Applet.Plugins.Run("on_rfcomm_disconnect", port)

                logging.info("Disonnecting rfcomm device")
            else:

                def cb(_inst, ret):
                    if ret:
                        raise StopException

                if not self.Applet.Plugins.RunEx("service_disconnect_handler", cb, service, ok, err):
                    service.disconnect(reply_handler=ok, error_handler=err)
Example #33
0
    def __init__(self, blueman):
        GObject.GObject.__init__(self)
        self.Blueman = blueman
        self.SelectedDevice = None

        self.is_popup = False

        self._device_property_changed_signal = self.Blueman.List.connect("device-property-changed",
                                                                         self.on_device_property_changed)
        self._selection_done_signal = None

        ManagerDeviceMenu.__instances__.append(self)

        self._any_network = Network()
        self._any_network.connect_signal('property-changed', self._on_service_property_changed)

        self._any_device = Device()
        self._any_device.connect_signal('property-changed', self._on_service_property_changed)

        self.Generate()
Example #34
0
    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")
Example #35
0
class ManagerDeviceMenu(Gtk.Menu):
    __ops__ = {}
    __instances__ = []

    def __init__(self, blueman):
        Gtk.Menu.__init__(self)
        self.set_name("ManagerDeviceMenu")
        self.Blueman = blueman
        self.SelectedDevice = None

        self.is_popup = False

        self._device_property_changed_signal = self.Blueman.List.connect("device-property-changed",
                                                                         self.on_device_property_changed)
        self._selection_done_signal = None

        ManagerDeviceMenu.__instances__.append(self)

        self._any_network = Network()
        self._any_network.connect_signal('property-changed', self._on_service_property_changed)

        self._any_device = Device()
        self._any_device.connect_signal('property-changed', self._on_service_property_changed)

        self.Generate()

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

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

        if not self._device_property_changed_signal:
            self._device_property_changed_signal = self.Blueman.List.connect("device-property-changed",
                                                                             self.on_device_property_changed)


        if not self._selection_done_signal:
            def disconnectall(x):
                self.disconnect(self._device_property_changed_signal)
                self.disconnect(self._selection_done_signal)

            self._selection_done_signal = self.connect("selection-done", disconnectall)

        self.Generate()

        Gtk.Menu.popup(self, *args)

    def clear(self):
        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 _on_service_property_changed(self, _service, key, _value, _path):
        if key == "Connected":
            self.Generate()

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

        def success(*args2):
            dprint("success", " ".join(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 == "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))

        dprint(device.Alias)

        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()

        uuids = device.UUIDs
        for uuid in uuids:
            uuid16 = uuid128_to_uuid16(uuid)
            if uuid16 == OBEX_OBJPUSH_SVCLASS_ID:
                send_item.connect("activate", lambda x: self.Blueman.send(device))
                send_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:
            item.connect("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))
            item.connect("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)
            item.connect("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)
        item.connect("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")
            bind_textdomain_codeset("blueman", "UTF-8")
            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...")
        item.connect('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))
        item.connect("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:
            item.connect("activate", on_disconnect)

        else:
            item.props.sensitive = False
Example #36
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.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.Valid = True

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

        w = weakref.ref(self)
        self._obj_path = self.Device.get_object_path()
        self.Device.connect_signal('property-changed',
                                   lambda _device, key, value: w() and w().property_changed(key, value))
        self._any_adapter = Adapter()
        self._any_adapter.connect_signal('device-removed',
                                         lambda _adapter, path: w() and w().on_device_removed(path))

    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):
        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):
        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

    #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
Example #37
0
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