From: Alessandro Astone Date: Sun, 8 May 2022 15:58:17 +0000 (+0200) Subject: Add first-launch command X-Git-Tag: 1.3.0~13 X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/waydroid.git/commitdiff_plain/a2804841ed52f812b1d666cb3df01239ee906f5f Add first-launch command Add a graphical init to be run as root, which we can use in first-launch through pkexec --- diff --git a/data/Waydroid.desktop b/data/Waydroid.desktop index df05c5f..4a4521d 100644 --- a/data/Waydroid.desktop +++ b/data/Waydroid.desktop @@ -1,5 +1,5 @@ [Desktop Entry] Type=Application Name=Waydroid -Exec=waydroid show-full-ui +Exec=waydroid first-launch Icon=/usr/lib/waydroid/data/AppIcon.png diff --git a/debian/control b/debian/control index 0279888..63ddbc6 100644 --- a/debian/control +++ b/debian/control @@ -15,7 +15,8 @@ Depends: ${misc:Depends}, ${python3:Depends}, lxc, python3-gbinder, - python3-gi + python3-gi, + python3-tk Description: Android™ application support waydroid allows running a separate Android™ environment confined to a LXC container. diff --git a/debian/waydroid.install b/debian/waydroid.install index c15d09e..3285363 100644 --- a/debian/waydroid.install +++ b/debian/waydroid.install @@ -2,3 +2,4 @@ waydroid.py /usr/lib/waydroid tools /usr/lib/waydroid data /usr/lib/waydroid gbinder/anbox.conf /etc/gbinder.d +polkit/org.waydro.id.policy /usr/share/polkit-1/actions diff --git a/polkit/org.waydro.id.policy b/polkit/org.waydro.id.policy new file mode 100644 index 0000000..f8cd1bc --- /dev/null +++ b/polkit/org.waydro.id.policy @@ -0,0 +1,18 @@ + + + + + Waydroid + Authentication is required to initialize Waydroid + system-software-install + + auth_admin + auth_admin + auth_admin + + /usr/bin/waydroid + true + + diff --git a/tools/__init__.py b/tools/__init__.py index 2443e6e..df42752 100644 --- a/tools/__init__.py +++ b/tools/__init__.py @@ -5,6 +5,7 @@ import sys import logging import os import traceback +import subprocess from . import actions from . import config @@ -32,7 +33,7 @@ def main(): args.timeout = 1800 if not actions.initializer.is_initialized(args): - if args.action and (args.action != "init" and args.action != "log"): + if args.action and (args.action not in ("init", "first-launch", "log")): if not args.wait_for_init: print('ERROR: WayDroid is not initialized, run "waydroid init"') return 0 @@ -116,6 +117,10 @@ def main(): helpers.lxc.logcat(args) elif args.action == "show-full-ui": actions.app_manager.showFullUI(args) + elif args.action == "first-launch": + subprocess.run(["pkexec", sys.argv[0], "init", "--gui"]) + if actions.initializer.is_initialized(args): + actions.app_manager.showFullUI(args) elif args.action == "status": actions.status.print_status(args) elif args.action == "log": diff --git a/tools/actions/initializer.py b/tools/actions/initializer.py index 158f6bc..89bbf57 100644 --- a/tools/actions/initializer.py +++ b/tools/actions/initializer.py @@ -5,6 +5,16 @@ import os from tools import helpers import tools.config +from tkinter import * +from tkinter import ttk + +import sys +import threading +class Daemon(threading.Thread): + def __init__(self): + super().__init__() + self.daemon = True + def is_initialized(args): return os.path.isfile(args.config) and os.path.isdir(tools.config.defaults["rootfs"]) @@ -87,7 +97,7 @@ def setup_config(args): cfg["waydroid"]["hwbinder"] = args.HWBINDER_DRIVER tools.config.save(args, cfg) -def init(args): +def do_init(args): if not is_initialized(args) or args.force: setup_config(args) status = "STOPPED" @@ -112,3 +122,87 @@ def init(args): helpers.ipc.notify(channel="init", msg="done") else: logging.info("Already initialized") + +def init(args): + if args.gui: + gui_init(args) + else: + do_init(args) + +def gui_init(args): + if is_initialized(args) and not args.force: + return + + root = Tk() + root.title("Initialize Waydroid") + root.iconphoto(True, PhotoImage(file="/usr/lib/waydroid/data/AppIcon.png")) + frm = ttk.Frame(root, padding=10) + frm.grid() + + systemChannel = StringVar(frm, args.system_channel or tools.config.channels_defaults["system_channel"]) + ttk.Label(frm, text="System OTA").grid(row=0, column=0) + ttk.Entry(frm, textvariable=systemChannel).grid(row=0, column=1, ipadx=20) + + vendorChannel = StringVar(frm, args.vendor_channel or tools.config.channels_defaults["vendor_channel"]) + ttk.Label(frm, text="Vendor OTA").grid(row=1, column=0) + ttk.Entry(frm, textvariable=vendorChannel).grid(row=1, column=1, ipadx=20) + + systemType = StringVar(frm) + systemTypes = ["VANILLA", "GAPPS"] + ttk.Label(frm, text="Android Type").grid(row=2, column=0) + ttk.OptionMenu(frm, systemType, args.system_type or systemTypes[0], *systemTypes).grid(row=2, column=1) + + done = ttk.Button(frm, text="Done", command=root.destroy) + + logBox = Text(frm, borderwidth=3, relief="sunken", height=5) + logBox.bind("", lambda e: "break") + + class StdoutRedirect(logging.StreamHandler): + def write(self, s): + if s.startswith('\r'): + logBox.delete("end-1l", "end") + logBox.insert(END, '\n') + s = s[1:] + + logBox.insert(END, s) + logBox.see(END) + def flush(self): + pass + def emit(self, record): + if record.levelno >= logging.INFO: + self.write(self.format(record) + self.terminator) + + out = StdoutRedirect() + sys.stdout = sys.stderr = out + logging.getLogger().addHandler(out) + + def runInit(): + download["state"] = DISABLED + logBox.grid(row=4, columnspan=2) + + args.system_channel = systemChannel.get() + args.vendor_channel = vendorChannel.get() + args.system_type = systemType.get() + + class Runner(Daemon): + def run(self): + try: + do_init(args) + if is_initialized(args): + done.grid(row=5, columnspan=2) + print("Done") + else: + download["state"] = NORMAL + except Exception as e: + print("ERROR: " + str(e)) + download["state"] = NORMAL + + Runner().start() + + download = ttk.Button(frm, text="Download", command=runInit) + download.grid(row=3, columnspan=2) + root.mainloop() + + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ + logging.getLogger().removeHandler(out) diff --git a/tools/helpers/arguments.py b/tools/helpers/arguments.py index 79ab853..953c1b5 100644 --- a/tools/helpers/arguments.py +++ b/tools/helpers/arguments.py @@ -33,6 +33,8 @@ def arguments_init(subparser): help="rom type (options: \"lineage\", \"bliss\" or OTA channel URL; default is LineageOS)") ret.add_argument("-s", "--system_type", help="system type (options: VANILLA, FOSS or GAPPS; default is VANILLA)") + ret.add_argument("-g", "--gui", action="store_true", + help="run as a graphical interface") return ret def arguments_status(subparser): @@ -104,6 +106,10 @@ def arguments_fullUI(subparser): ret = subparser.add_parser("show-full-ui", help="show android full screen in window") return ret +def arguments_firstLaunch(subparser): + ret = subparser.add_parser("first-launch", help="initialize waydroid and start it") + return ret + def arguments_shell(subparser): ret = subparser.add_parser("shell", help="run remote shell command") ret.add_argument('COMMAND', nargs='?', help="command to run") @@ -147,6 +153,7 @@ def arguments(): arguments_app(sub) arguments_prop(sub) arguments_fullUI(sub) + arguments_firstLaunch(sub) arguments_shell(sub) arguments_logcat(sub)