linuxOS_AP05/debian/test/usr/bin/blueman-assistant
2025-09-26 09:40:02 +08:00

312 lines
12 KiB
Python
Executable File

#! /usr/bin/python3
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from __future__ import unicode_literals
PAGE_INTRO = 0
PAGE_DEVLIST = 1
PAGE_PASSKEY = 2
PAGE_PAIRING = 3
PAGE_CONNECT = 4
PAGE_CONNECTING = 5
PAGE_FINISH = 6
pages = {}
import os
import sys
import random
import signal
import dbus.glib
from optparse import OptionParser
#support running uninstalled
_dirname = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if os.path.exists(os.path.join(_dirname, "CHANGELOG.md")):
sys.path.insert(0, _dirname)
from blueman.Constants import *
from blueman.Functions import *
from blueman.gui.DeviceSelectorWidget import DeviceSelectorWidget
from blueman.main.applet.BluezAgent import TempAgent
from blueman.bluez.Manager import Manager
from blueman.bluez.BlueZInterface import BlueZInterface
from blueman.main.FakeDevice import FakeDevice
from blueman.main.Device import Device
from blueman.main.AppletService import AppletService
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
# Workaround introspection bug, gnome bug 622084
signal.signal(signal.SIGINT, signal.SIG_DFL)
class Assistant:
def __init__(self):
setup_icon_path()
usage = "Usage: %prog [options]"
parser = OptionParser(usage)
parser.add_option("-d", "--device", dest="device",
action="store", help=_("Start configuration assistant for this device"), metavar="ADDRESS")
(options, args) = parser.parse_args()
check_bluetooth_status(_("Bluetooth needs to be turned on for the Bluetooth assistant to work"), lambda: exit())
self.options = options
self.Device = None
self.Adapter = None
self.pair = True
self.service = None
self.Builder = Gtk.Builder()
self.Builder.set_translation_domain("blueman")
self.Builder.add_from_file(UI_PATH + "/assistant.ui")
self.assistant = self.Builder.get_object("assistant")
self.assistant.set_title(_("Bluetooth Assistant"))
self.applet = AppletService()
self.assistant.connect("prepare", self.on_prepare)
self.assistant.connect("close", self.on_close)
self.assistant.connect("cancel", self.on_close)
pages[PAGE_INTRO] = self.Builder.get_object("l_page0")
self.assistant.set_page_header_image(pages[PAGE_INTRO], get_icon("blueman", 32))
self.assistant.set_page_complete(pages[PAGE_INTRO], True)
pages[PAGE_DEVLIST] = self.Builder.get_object("a_page1")
self.assistant.set_page_header_image(pages[PAGE_DEVLIST], get_icon("blueman", 32))
pages[PAGE_PASSKEY] = self.Builder.get_object("a_page2")
self.assistant.set_page_header_image(pages[PAGE_PASSKEY], get_icon("dialog-password", 32))
pages[PAGE_PAIRING] = self.Builder.get_object("l_page3")
self.assistant.set_page_header_image(pages[PAGE_PAIRING], get_icon("dialog-password", 32))
pages[PAGE_CONNECT] = self.Builder.get_object("a_page4")
self.assistant.set_page_header_image(pages[PAGE_CONNECT], get_icon("network-transmit-recieve", 32))
pages[PAGE_CONNECTING] = self.Builder.get_object("l_page5")
self.assistant.set_page_header_image(pages[PAGE_CONNECTING], get_icon("network-transmit-recieve", 32))
pages[PAGE_FINISH] = self.Builder.get_object("l_page6")
self.assistant.set_page_header_image(pages[PAGE_FINISH], get_icon("help-about", 32))
self.svc_vbox = self.Builder.get_object("svcs")
self.Builder.get_object("r_dontp").connect("toggled", self.on_pairing_method_changed, False)
self.Builder.get_object("r_pair").connect("toggled", self.on_pairing_method_changed, True)
self.dev_widget = DeviceSelectorWidget()
self.dev_widget.List.connect("device-selected", self.on_device_selected)
self.dev_widget.List.connect("row-activated", self.on_row_activated)
self.assistant.set_forward_page_func(self.next_page_fn, None)
pages[PAGE_DEVLIST].add(self.dev_widget)
self.dev_widget.show()
if not self.dev_widget.List.IsValidAdapter():
d = Gtk.MessageDialog(type=Gtk.MessageType.ERROR, )
d.props.text = _("No adapters found")
d.props.icon_name = "blueman"
d.props.title = "Blueman Assistant"
d.add_button("window-close", Gtk.ResponseType.CANCEL)
d.run()
exit(1)
self.assistant.show()
if options.device != None:
m = Manager()
try:
adapter = m.get_adapter()
except:
print("Error: No Adapters present")
exit(1)
try:
d = adapter.find_device(options.device)
self.Device = Device(d)
self.Adapter = adapter
if self.Device.Paired:
self.assistant.set_current_page(PAGE_CONNECT)
else:
self.assistant.set_current_page(PAGE_PASSKEY)
except:
info = {}
info["Address"] = options.device
info["Name"] = info["Address"].replace(":", "-")
info["Alias"] = info["Name"]
info["Fake"] = True
self.Device = FakeDevice(info)
self.Adapter = adapter
self.assistant.set_current_page(PAGE_PASSKEY)
else:
self.dev_widget.List.DiscoverDevices()
Gtk.main()
def on_row_activated(self, treeview, path, view_column, *args):
self.assistant.set_current_page(self.next_page_fn(self.assistant.get_current_page(), None))
def next_page_fn(self, page, data):
if page == PAGE_INTRO:
return PAGE_DEVLIST
elif page == PAGE_DEVLIST:
if self.Device:
if self.Device.Fake or not self.Device.Paired:
return PAGE_PASSKEY
else:
return PAGE_CONNECT
else:
return PAGE_PASSKEY
elif page == PAGE_PASSKEY:
if self.Device and not self.Device.Fake and not self.Device.Paired and not self.pair:
return PAGE_CONNECT
#self.assistant.set_page_complete(pages[PAGE_PASSKEY], True)
return PAGE_PAIRING
elif page == PAGE_PAIRING:
if len(self.Device.get_services()) == 0:
return PAGE_FINISH
return PAGE_CONNECT
elif page == PAGE_CONNECT:
if self.service:
return PAGE_CONNECTING
else:
return PAGE_FINISH
elif page == PAGE_CONNECTING:
return PAGE_FINISH
elif page == PAGE_FINISH:
return PAGE_FINISH + 1
return page
def on_pairing_method_changed(self, radio_button, pair):
if radio_button.props.active:
self.assistant.set_page_complete(pages[PAGE_PASSKEY], True)
self.pair = pair
def on_device_selected(self, list, device, iter):
if not device:
self.assistant.set_page_complete(pages[PAGE_DEVLIST], False)
self.Device = None
self.Adapter = list.Adapter
else:
self.assistant.set_page_complete(pages[PAGE_DEVLIST], True)
self.Device = device
self.Adapter = list.Adapter
def on_close(self, assistant):
Gtk.main_quit()
def on_service_toggled(self, rb, service):
if rb.props.active:
self.service = service
self.assistant.set_page_complete(pages[PAGE_CONNECT], True)
def on_prepare(self, assistant, page):
num = assistant.get_current_page()
if num == PAGE_PASSKEY:
self.assistant.set_page_complete(pages[PAGE_PASSKEY], True)
elif num == PAGE_PAIRING:
if self.Device.Fake and not self.pair:
pages[PAGE_PAIRING].set_markup(_("<b>Adding Device...</b>"))
self.assistant.set_page_title(pages[PAGE_PAIRING], _("Adding"))
else:
pages[PAGE_PAIRING].set_markup(_("<b>Pairing in progress...</b>"))
if BlueZInterface.get_interface_version()[0] < 5:
def ok(dev):
self.Device = Device(dev)
self.assistant.set_current_page(PAGE_CONNECT)
def err(err):
print(err)
pages[PAGE_FINISH].set_markup(_("<b>Failed to add device</b>"))
self.assistant.set_page_header_image(pages[PAGE_FINISH], get_icon("help-about", 32))
self.assistant.set_current_page(PAGE_FINISH)
if self.pair:
agent_path = "/org/blueman/agent/temp/" + self.Device.Address.replace(":", "")
agent = TempAgent(self.applet.Plugins.StatusIcon, agent_path, Gtk.get_current_event_time())
self.Adapter.create_paired_device(self.Device.Address, agent_path, "", reply_handler=ok,
error_handler=err)
else:
self.Adapter.create_device(self.Device.Address, reply_handler=ok, error_handler=err)
else:
if self.pair:
def ok():
self.Device = Device(device)
self.assistant.set_current_page(PAGE_CONNECT)
def err(err):
print(err)
pages[PAGE_FINISH].set_markup(_("<b>Failed to add device</b>"))
self.assistant.set_page_header_image(pages[PAGE_FINISH], get_icon("help-about", 32))
self.assistant.set_current_page(PAGE_FINISH)
device = self.Adapter.find_device(self.Device.Address)
device.pair(reply_handler=ok, error_handler=err)
elif num == PAGE_CONNECT:
self.svc_vbox.foreach(lambda x, y: self.svc_vbox.remove(x), None)
print(self.Device.get_services())
rbs = []
for service in self.Device.get_services():
rbs.append(Gtk.RadioButton(service.name))
rbs[-1].connect("toggled", self.on_service_toggled, service)
self.svc_vbox.pack_start(rbs[-1], False, False, 0)
if len(rbs) > 1:
rbs[-1].join_group(rbs[0])
rbs.append(Gtk.RadioButton(_("Don't connect")))
rbs[-1].join_group(rbs[0])
rbs[-1].connect("toggled", self.on_service_toggled, None)
self.svc_vbox.pack_start(rbs[-1], False, False, 8)
self.svc_vbox.show_all()
rbs[0].emit("toggled")
if len(self.svc_vbox.get_children()) == 1:
self.assistant.set_current_page(self.next_page_fn(self.assistant.get_current_page(), None))
elif num == PAGE_CONNECTING:
print("connect")
def success(*args):
pages[PAGE_FINISH].set_markup(_("<b>Device added and connected successfuly</b>"))
self.assistant.set_page_complete(pages[PAGE_CONNECTING], True)
self.assistant.set_page_header_image(pages[PAGE_FINISH], get_icon("help-about", 32))
self.assistant.set_current_page(PAGE_FINISH)
def fail(*args):
pages[PAGE_FINISH].set_markup(_("<b>Device added successfuly, but failed to connect</b>"))
self.assistant.set_page_complete(pages[PAGE_CONNECTING], True)
self.assistant.set_page_header_image(pages[PAGE_FINISH], get_icon("dialog-warning", 32))
self.assistant.set_current_page(PAGE_FINISH)
self.applet.connect_service(self.service.device.get_object_path(), self.service.uuid,
reply_handler=success, error_handler=fail)
set_proc_title()
Assistant()