]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/services/user_manager.py
user_manager: Do not crash when install applications during boot
[waydroid.git] / tools / services / user_manager.py
1 # Copyright 2021 Erfan Abdi
2 # SPDX-License-Identifier: GPL-3.0-or-later
3 import logging
4 import os
5 import threading
6 import tools.config
7 from tools.interfaces import IUserMonitor
8 from tools.interfaces import IPlatform
9
10 stopping = False
11
12 def start(args, session, unlocked_cb=None):
13 waydroid_data = session["waydroid_data"]
14 apps_dir = session["xdg_data_home"] + "/applications/"
15
16 def makeDesktopFile(appInfo):
17 if appInfo is None:
18 return -1
19
20 showApp = False
21 for cat in appInfo["categories"]:
22 if cat.strip() == "android.intent.category.LAUNCHER":
23 showApp = True
24 if not showApp:
25 return -1
26
27 packageName = appInfo["packageName"]
28
29 desktop_file_path = apps_dir + "/waydroid." + packageName + ".desktop"
30 if not os.path.exists(desktop_file_path):
31 lines = ["[Desktop Entry]", "Type=Application"]
32 lines.append("Name=" + appInfo["name"])
33 lines.append("Exec=waydroid app launch " + packageName)
34 lines.append("Icon=" + waydroid_data + "/icons/" + packageName + ".png")
35 lines.append("Categories=X-WayDroid-App;")
36 lines.append("X-Purism-FormFactor=Workstation;Mobile;")
37 lines.append("Actions=app_settings;")
38 lines.append("[Desktop Action app_settings]")
39 lines.append("Name=App Settings")
40 lines.append("Exec=waydroid app intent android.settings.APPLICATION_DETAILS_SETTINGS package:" + packageName)
41 desktop_file = open(desktop_file_path, "w")
42 for line in lines:
43 desktop_file.write(line + "\n")
44 desktop_file.close()
45 os.chmod(desktop_file_path, 0o644)
46 return 0
47
48 def makeWaydroidDesktopFile(hide):
49 desktop_file_path = apps_dir + "/Waydroid.desktop"
50 if os.path.isfile(desktop_file_path):
51 os.remove(desktop_file_path)
52 lines = ["[Desktop Entry]", "Type=Application"]
53 lines.append("Name=Waydroid")
54 lines.append("Exec=waydroid show-full-ui")
55 lines.append("Categories=X-WayDroid-App;")
56 lines.append("X-Purism-FormFactor=Workstation;Mobile;")
57 if hide:
58 lines.append("NoDisplay=true")
59 lines.append("Icon=waydroid")
60 desktop_file = open(desktop_file_path, "w")
61 for line in lines:
62 desktop_file.write(line + "\n")
63 desktop_file.close()
64 os.chmod(desktop_file_path, 0o644)
65
66 def userUnlocked(uid):
67 logging.info("Android with user {} is ready".format(uid))
68
69 platformService = IPlatform.get_service(args)
70 if platformService:
71 if not os.path.exists(apps_dir):
72 os.mkdir(apps_dir)
73 os.chmod(apps_dir, 0o700)
74 appsList = platformService.getAppsInfo()
75 for app in appsList:
76 makeDesktopFile(app)
77 multiwin = platformService.getprop("persist.waydroid.multi_windows", "false")
78 if multiwin == "false":
79 makeWaydroidDesktopFile(False)
80 else:
81 makeWaydroidDesktopFile(True)
82 if unlocked_cb:
83 unlocked_cb()
84
85 def packageStateChanged(mode, packageName, uid):
86 platformService = IPlatform.get_service(args)
87 if platformService:
88 appInfo = platformService.getAppInfo(packageName)
89 desktop_file_path = apps_dir + "/waydroid." + packageName + ".desktop"
90 if mode == 0:
91 # Package added
92 makeDesktopFile(appInfo)
93 elif mode == 1:
94 if os.path.isfile(desktop_file_path):
95 os.remove(desktop_file_path)
96 else:
97 if os.path.isfile(desktop_file_path):
98 if makeDesktopFile(appInfo) == -1:
99 os.remove(desktop_file_path)
100
101 def service_thread():
102 while not stopping:
103 IUserMonitor.add_service(args, userUnlocked, packageStateChanged)
104
105 global stopping
106 stopping = False
107 args.user_manager = threading.Thread(target=service_thread)
108 args.user_manager.start()
109
110 def stop(args):
111 global stopping
112 stopping = True
113 try:
114 if args.userMonitorLoop:
115 args.userMonitorLoop.quit()
116 except AttributeError:
117 logging.debug("UserMonitor service is not even started")