aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2020-04-06 13:57:01 +0200
committerGuido Günther <agx@sigxcpu.org>2020-04-06 15:15:06 +0200
commitb217aadd22699efef2470775cd99050e72679047 (patch)
tree84929e041344df4c695578fee87af00c29ef792c
parent5c744b758f8fbe9bd44018b314b72ece9ebec3c1 (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.py76
-rwxr-xr-xsrc/prepaid-manager-applet.py36
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"""