X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/waydroid.git/blobdiff_plain/55e0266795bc09436ea45c3ead59d2925762d5c2..ff4cf1c83f09e639504209dec68855cdf3c69bce:/tools/actions/initializer.py diff --git a/tools/actions/initializer.py b/tools/actions/initializer.py index e74a2b7..5238b3c 100644 --- a/tools/actions/initializer.py +++ b/tools/actions/initializer.py @@ -10,6 +10,10 @@ import threading import multiprocessing import select import queue +import time +import dbus +import dbus.service +from gi.repository import GLib def is_initialized(args): return os.path.isfile(args.config) and os.path.isdir(tools.config.defaults["rootfs"]) @@ -29,13 +33,16 @@ def setup_config(args): args.arch = helpers.arch.host() cfg["waydroid"]["arch"] = args.arch - preinstalled_images = tools.config.defaults["preinstalled_images_path"] + preinstalled_images_paths = tools.config.defaults["preinstalled_images_paths"] if not args.images_path: - if os.path.isdir(preinstalled_images): - if os.path.isfile(preinstalled_images + "/system.img") and os.path.isfile(preinstalled_images + "/vendor.img"): - args.images_path = preinstalled_images - else: - logging.error("Missing system or vendor on preinstalled images dir, fallback to default") + for preinstalled_images in preinstalled_images_paths: + if os.path.isdir(preinstalled_images): + if os.path.isfile(preinstalled_images + "/system.img") and os.path.isfile(preinstalled_images + "/vendor.img"): + args.images_path = preinstalled_images + break + else: + logging.warning("Found directory {} but missing system or vendor image, ignoring...".format(preinstalled_images)) + if not args.images_path: args.images_path = tools.config.defaults["images_path"] cfg["waydroid"]["images_path"] = args.images_path @@ -54,7 +61,7 @@ def setup_config(args): "/waydroid_" + args.arch + "/" + args.system_type + ".json" system_request = helpers.http.retrieve(args.system_ota) if system_request[0] != 200: - if args.images_path != preinstalled_images: + if args.images_path not in preinstalled_images_paths: raise ValueError( "Failed to get system OTA channel: {}, error: {}".format(args.system_ota, system_request[0])) else: @@ -72,7 +79,7 @@ def setup_config(args): break if not args.vendor_type: - if args.images_path != preinstalled_images: + if args.images_path not in preinstalled_images_paths: raise ValueError( "Failed to get vendor OTA channel: {}".format(vendor_ota)) else: @@ -95,6 +102,11 @@ def setup_config(args): def init(args): if not is_initialized(args) or args.force: + initializer_service = None + try: + initializer_service = tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer") + except dbus.DBusException: + pass setup_config(args) status = "STOPPED" if os.path.exists(tools.config.defaults["lxc"] + "/waydroid"): @@ -103,7 +115,7 @@ def init(args): logging.info("Stopping container") helpers.lxc.stop(args) helpers.images.umount_rootfs(args) - if args.images_path != tools.config.defaults["preinstalled_images_path"]: + if args.images_path not in tools.config.defaults["preinstalled_images_paths"]: helpers.images.get(args) if not os.path.isdir(tools.config.defaults["rootfs"]): os.mkdir(tools.config.defaults["rootfs"]) @@ -115,24 +127,39 @@ def init(args): helpers.images.mount_rootfs(args, args.images_path) helpers.lxc.start(args) - helpers.ipc.notify(channel="init", msg="done") + if "running_init_in_service" not in args or not args.running_init_in_service: + try: + if initializer_service: + initializer_service.Done() + except dbus.DBusException: + pass else: logging.info("Already initialized") def wait_for_init(args): - helpers.ipc.create_channel("init") helpers.ipc.create_channel("remote_init_output") - while True: - print('WayDroid waiting for initialization...') - msg = helpers.ipc.read_one(channel="init") - if msg == "done": - if is_initialized(args): - break - else: - continue - if msg.startswith("cmd"): - remote_init_server(args, msg) - continue + + mainloop = GLib.MainLoop() + dbus_obj = DbusInitializer(mainloop, dbus.SystemBus(), '/Initializer', args) + mainloop.run() + + # After init + dbus_obj.remove_from_connection() + +class DbusInitializer(dbus.service.Object): + def __init__(self, looper, bus, object_path, args): + self.args = args + self.looper = looper + dbus.service.Object.__init__(self, bus, object_path) + + @dbus.service.method("id.waydro.Initializer", in_signature='a{ss}', out_signature='') + def Init(self, params): + threading.Thread(target=remote_init_server, args=(self.args, params)).start() + + @dbus.service.method("id.waydro.Initializer", in_signature='', out_signature='') + def Done(self): + if is_initialized(self.args): + self.looper.quit() def background_remote_init_process(args): with helpers.ipc.open_channel("remote_init_output", "wb") as channel_out: @@ -182,14 +209,14 @@ def background_remote_init_process(args): sys.stderr = sys.__stderr__ logging.getLogger().removeHandler(out) -def remote_init_server(args, cmd): - params = cmd.split('\f')[1:] +def remote_init_server(args, params): args.force = True args.images_path = "" args.rom_type = "" - args.system_channel = params[0] - args.vendor_channel = params[1] - args.system_type = params[2] + args.system_channel = params["system_channel"] + args.vendor_channel = params["vendor_channel"] + args.system_type = params["system_type"] + args.running_init_in_service = True p = multiprocessing.Process(target=background_remote_init_process, args=(args,)) p.daemon = True @@ -200,15 +227,23 @@ def remote_init_client(args): # Local imports cause Gtk is intrusive import gi gi.require_version("Gtk", "3.0") - from gi.repository import Gtk, GLib + from gi.repository import Gtk + + bus = dbus.SystemBus() if is_initialized(args): - helpers.ipc.notify(channel="init", msg="done") + try: + tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer").Done() + except dbus.DBusException: + pass return def notify_and_quit(caller): if is_initialized(args): - helpers.ipc.notify(channel="init", msg="done") + try: + tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer").Done() + except dbus.DBusException: + pass GLib.idle_add(Gtk.main_quit) class WaydroidInitWindow(Gtk.Window): @@ -297,14 +332,17 @@ def remote_init_client(args): if self.open_channel is not None: self.open_channel.close() - # Wait for other end to re-open - tmp = helpers.ipc.open_channel("init", "w", buffering=1) - tmp.close() + # Wait for other end to reset + time.sleep(1) draw("Waiting for waydroid container service...\n") try: - helpers.ipc.notify_blocking(channel="init", msg="{}\f{}\f{}\f{}".format( - "cmd", self.sysOta.get_text(), self.vndOta.get_text(), self.sysType.get_active_text())) + params = { + "system_channel": self.sysOta.get_text(), + "vendor_channel": self.vndOta.get_text(), + "system_type": self.sysType.get_active_text() + } + tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer").Init(params) except: draw("The waydroid container service is not listening\n") GLib.idle_add(self.downloadBtn.set_sensitive, True) @@ -337,6 +375,7 @@ def remote_init_client(args): draw("Done\n") + GLib.set_prgname("Waydroid") win = WaydroidInitWindow() win.connect("destroy", notify_and_quit)