]> glassweightruler.freedombox.rocks Git - waydroid.git/commitdiff
Add first-launch command
authorAlessandro Astone <ales.astone@gmail.com>
Sun, 8 May 2022 15:58:17 +0000 (17:58 +0200)
committerAlessandro Astone <ales.astone@gmail.com>
Sun, 17 Jul 2022 23:34:12 +0000 (01:34 +0200)
Add a graphical init to be run as root, which we can use in
first-launch through pkexec

data/Waydroid.desktop
debian/control
debian/waydroid.install
polkit/org.waydro.id.policy [new file with mode: 0644]
tools/__init__.py
tools/actions/initializer.py
tools/helpers/arguments.py

index df05c5ff658c50b571dc4d9df02b8288a4696ea6..4a4521dba44460f05e789de192be74020d0ca1b1 100644 (file)
@@ -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
index 02798885e29b980d0b7234bc8fa7e28970275021..63ddbc6c60f8950c649a3efd366c1b7c6ba98218 100644 (file)
@@ -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.
index c15d09eb55406d92a1077eff0b533e58a6d66566..3285363a16474bc741803f2b144059afa233a9cc 100644 (file)
@@ -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 (file)
index 0000000..f8cd1bc
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+<policyconfig>
+    <action id="org.waydro.id.policy">
+    <description>Waydroid</description>
+    <message>Authentication is required to initialize Waydroid</message>
+    <icon_name>system-software-install</icon_name>
+    <defaults>
+        <allow_any>auth_admin</allow_any>
+        <allow_inactive>auth_admin</allow_inactive>
+        <allow_active>auth_admin</allow_active>
+    </defaults>
+    <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/waydroid</annotate>
+    <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
+    </action>
+</policyconfig>
index 2443e6ebb5d6a7a5c2f580bdbca6288094fe5896..df427524901becd9d281269006948f4df45611e6 100644 (file)
@@ -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":
index 158f6bc607499f845713b90912f65ebbe6010f8e..89bbf576b149287f7ebf00a85cc28b0c651c6b82 100644 (file)
@@ -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("<Key>", 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)
index 79ab8533fd107a80b3ab9ce5c1be5b54af93cb6d..953c1b5c9e6a8f42a893d4162a03d1cdb02ef1f1 100644 (file)
@@ -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)