diff options
author | Guido Günther <agx@sigxcpu.org> | 2020-04-06 13:57:01 +0200 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2020-04-06 15:15:06 +0200 |
commit | b217aadd22699efef2470775cd99050e72679047 (patch) | |
tree | 84929e041344df4c695578fee87af00c29ef792c | |
parent | 5c744b758f8fbe9bd44018b314b72ece9ebec3c1 (diff) |
Make intial setup async
This avoids stalling the UI. We mark async dbus calls
with a 'dbus_' prefix from now on.
-rw-r--r-- | src/ppm/modemproxy.py | 76 | ||||
-rwxr-xr-x | src/prepaid-manager-applet.py | 36 |
2 files changed, 83 insertions, 29 deletions
diff --git a/src/ppm/modemproxy.py b/src/ppm/modemproxy.py index 192c621..189836b 100644 --- a/src/ppm/modemproxy.py +++ b/src/ppm/modemproxy.py @@ -18,6 +18,7 @@ from gi.repository import GObject from gi.repository import GLib from gi.repository import Gio +import logging class ModemError(Exception): def __init__(self, msg): @@ -59,8 +60,19 @@ class ModemManagerProxy(GObject.GObject): # Emitted when a request has finished 'request-finished': (GObject.SignalFlags.RUN_FIRST, None, [object]), + # Emitted when modem search completed + 'got-modems': (GObject.SignalFlags.RUN_FIRST, None, + [object]), } + def on_new_object_manager_done(self, obj, res): + try: + proxy = Gio.DBusProxy.new_for_bus_finish(res) + except GLib.Error: + logging.exception("Connecting to MM failed") + else: + self.object_manager = proxy + def __init__(self): GObject.GObject.__init__(self) self.bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None) @@ -71,15 +83,22 @@ class ModemManagerProxy(GObject.GObject): self.obj = None self.objs = None + self.object_manager = None + Gio.DBusProxy.new_for_bus(Gio.BusType.SYSTEM, + self.MM_DBUS_FLAGS, + None, + self.MM_DBUS_SERVICE, + self.MM_DBUS_OBJECT_MODEM_MANAGER, + self.DBUS_INTERFACE_OBJECT_MANAGER, + None, + self.on_new_object_manager_done) + self._modems = [] + + def ready(self): + return True if self.object_manager else False + def get_objects(self): - mm = Gio.DBusProxy.new_sync(self.bus, - self.MM_DBUS_FLAGS, - None, - self.MM_DBUS_SERVICE, - self.MM_DBUS_OBJECT_MODEM_MANAGER, - self.DBUS_INTERFACE_OBJECT_MANAGER, - None) - self.objs = mm.GetManagedObjects() + self.objs = self.object_manager.GetManagedObjects() def objects(self): if self.objs is None: @@ -120,6 +139,10 @@ class ModemManagerProxy(GObject.GObject): else: return False + @property + def modems(self): + return self._modems + @mm_request_done def handle_dbus_reply(self, obj, result, user_data): try: @@ -131,13 +154,36 @@ class ModemManagerProxy(GObject.GObject): me = ModemError("%s failed: %s" % (self.request, err)) self.error_func(me) - def get_modems(self): - modems = [] - self.get_objects() - for path, obj in self.objects().items(): - if self.MM_DBUS_INTERFACE_MODEM in obj: - modems.append(path) - return modems + def on_get_managed_objects_finished(self, proxy, res, user_data): + self._modems = [] + + try: + objs = proxy.call_finish(res) + except Exception as err: + logging.error("Failed to get managed modems: %s", err) + objs = [] + return + + for obj in objs: + for path, ifaces in obj.items(): + if self.MM_DBUS_INTERFACE_MODEM in ifaces: + self._modems.append(path) + logging.debug("Found modems: %s", self.modems) + self.emit('got-modems', self) + + def dbus_find_modems(self): + """ + Async method to find modems + + Result will be in modems property + """ + self.object_manager.call("GetManagedObjects", + None, + Gio.DBusCallFlags.NO_AUTO_START, + self.MM_DBUS_TIMEOUT, + None, + self.on_get_managed_objects_finished, + None) def get_imsi(self): card = Gio.DBusProxy.new_sync(self.bus, diff --git a/src/prepaid-manager-applet.py b/src/prepaid-manager-applet.py index 5d9b08d..9c44f29 100755 --- a/src/prepaid-manager-applet.py +++ b/src/prepaid-manager-applet.py @@ -70,10 +70,12 @@ class PPMController(Gtk.Application): def _connect_mm_signals(self): self.mm.connect('request-started', self.on_mm_request_started) self.mm.connect('request-finished', self.on_mm_request_finished) + self.mm.connect('got-modems', self.on_mm_got_modems) def __init__(self): Gtk.Application.__init__(self, application_id=ppm.app_id) self.mm = None + self.mm_tries = 0 self.imsi = None self.provider = None self.account = None @@ -202,29 +204,35 @@ class PPMController(Gtk.Application): # Everything worked out, disable the timer. return False - def setup(self): - logging.debug("Setting up") - - self.mm = ModemManagerProxy() - self._connect_mm_signals() - - try: - modems = self.mm.get_modems() - except ModemError as e: - logging.error("%s" % e.msg) - modems = None - if modems: - modem = modems[0] # FIXME: handle multiple modems + def on_mm_got_modems(self, obj, mm_proxy): + if mm_proxy.modems: + modem = mm_proxy.modems[0] # FIXME: handle multiple modems logging.debug("Using modem %s" % modem) self.mm.set_modem(modem) GLib.timeout_add(500, self.init_account_and_provider) else: self.view.show_no_modem_found() + + def setup(self): + logging.debug("Setting up") + # Wait for MM Proxy to become ready: + if not self.mm.ready(): + self.mm_tries += 1 + logging.debug("Not yet ready, rescheduling") + return True + if self.mm_tries > 5: + self.view.show_no_modem_found() + return False + + self.mm.dbus_find_modems() return False def schedule_setup(self): """Schedule another run of setup""" - GLib.timeout_add(1, self.setup) + + self.mm = ModemManagerProxy() + self._connect_mm_signals() + GLib.timeout_add(500, self.setup) def enable_modem(self): """Enable the modem""" |