]> glassweightruler.freedombox.rocks Git - waydroid.git/commitdiff
interfaces: Fix ServiceManager race condition in clients
authorAlessandro Astone <ales.astone@gmail.com>
Tue, 24 Jan 2023 22:12:53 +0000 (23:12 +0100)
committerAlessandro Astone <ales.astone@gmail.com>
Tue, 24 Jan 2023 22:13:26 +0000 (23:13 +0100)
tools/interfaces/IPlatform.py
tools/interfaces/IStatusBarService.py

index a5d6d08a602c7566182815eb1b417a3e8efc2dfb..12d1e1da2e11a5d5137933e441d037eeb5680944 100644 (file)
@@ -2,6 +2,8 @@ import gbinder
 import logging
 import time
 from tools import helpers
 import logging
 import time
 from tools import helpers
+from gi.repository import GLib
+import signal
 
 
 INTERFACE = "lineageos.waydroid.IPlatform"
 
 
 INTERFACE = "lineageos.waydroid.IPlatform"
@@ -299,6 +301,13 @@ def get_service(args):
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER, args.SERVICE_MANAGER_PROTOCOL, args.BINDER_PROTOCOL)
     except TypeError:
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER)
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER, args.SERVICE_MANAGER_PROTOCOL, args.BINDER_PROTOCOL)
     except TypeError:
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER)
+
+    if not serviceManager.is_present():
+        logging.info("Waiting for binder Service Manager...")
+        if not wait_for_manager(serviceManager):
+            logging.error("Service Manager never appeared")
+            return None
+
     tries = 1000
 
     remote, status = serviceManager.get_service_sync(SERVICE_NAME)
     tries = 1000
 
     remote, status = serviceManager.get_service_sync(SERVICE_NAME)
@@ -313,3 +322,14 @@ def get_service(args):
             return None
 
     return IPlatform(remote)
             return None
 
     return IPlatform(remote)
+
+# Like ServiceManager.wait() but can be interrupted
+def wait_for_manager(sm):
+    mainloop = GLib.MainLoop()
+    sm.add_presence_handler(lambda: mainloop.quit() if sm.is_present() else None)
+    GLib.timeout_add_seconds(60, lambda: mainloop.quit())
+    GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, lambda _: mainloop.quit(), None)
+    mainloop.run()
+    if not sm.is_present():
+        return False
+    return True
index fa5f6f5ea7824fe0abe4eff16aed58e42fbff594..af572dd37d9a394170b2c3ad71f4bcbc047fb210 100644 (file)
@@ -2,6 +2,8 @@ import gbinder
 import logging
 import time
 from tools import helpers
 import logging
 import time
 from tools import helpers
+from gi.repository import GLib
+import signal
 
 
 INTERFACE = "com.android.internal.statusbar.IStatusBarService"
 
 
 INTERFACE = "com.android.internal.statusbar.IStatusBarService"
@@ -46,6 +48,13 @@ def get_service(args):
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER, args.SERVICE_MANAGER_PROTOCOL, args.BINDER_PROTOCOL)
     except TypeError:
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER)
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER, args.SERVICE_MANAGER_PROTOCOL, args.BINDER_PROTOCOL)
     except TypeError:
         serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER)
+
+    if not serviceManager.is_present():
+        logging.info("Waiting for binder Service Manager...")
+        if not wait_for_manager(serviceManager):
+            logging.error("Service Manager never appeared")
+            return None
+
     tries = 1000
 
     remote, status = serviceManager.get_service_sync(SERVICE_NAME)
     tries = 1000
 
     remote, status = serviceManager.get_service_sync(SERVICE_NAME)
@@ -60,3 +69,14 @@ def get_service(args):
             return None
 
     return IStatusBarService(remote)
             return None
 
     return IStatusBarService(remote)
+
+# Like ServiceManager.wait() but can be interrupted
+def wait_for_manager(sm):
+    mainloop = GLib.MainLoop()
+    sm.add_presence_handler(lambda: mainloop.quit() if sm.is_present() else None)
+    GLib.timeout_add_seconds(60, lambda: mainloop.quit())
+    GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, lambda _: mainloop.quit(), None)
+    mainloop.run()
+    if not sm.is_present():
+        return False
+    return True