]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/container_manager.py
waydroid.market.desktop: update some properties
[waydroid.git] / tools / actions / container_manager.py
1 # Copyright 2021 Erfan Abdi
2 # SPDX-License-Identifier: GPL-3.0-or-later
3 from shutil import which
4 import logging
5 import os
6 import time
7 import glob
8 import signal
9 import sys
10 import uuid
11 import tools.config
12 from tools import helpers
13 from tools import services
14
15
16 def start(args):
17 def make_prop(full_props_path):
18 def add_prop(key, cfg_key):
19 value = session_cfg["session"][cfg_key]
20 if value != "None":
21 value = value.replace("/mnt/", "/mnt_extra/")
22 props.append(key + "=" + value)
23
24 if not os.path.isfile(args.work + "/waydroid_base.prop"):
25 raise RuntimeError("waydroid_base.prop Not found")
26 with open(args.work + "/waydroid_base.prop") as f:
27 props = f.read().splitlines()
28 if not props:
29 raise RuntimeError("waydroid_base.prop is broken!!?")
30
31 add_prop("waydroid.host.user", "user_name")
32 add_prop("waydroid.host.uid", "user_id")
33 add_prop("waydroid.host.gid", "group_id")
34 add_prop("waydroid.xdg_runtime_dir", "xdg_runtime_dir")
35 add_prop("waydroid.pulse_runtime_path", "pulse_runtime_path")
36 add_prop("waydroid.wayland_display", "wayland_display")
37 if which("waydroid-sensord") is None:
38 props.append("waydroid.stub_sensors_hal=1")
39 dpi = session_cfg["session"]["lcd_density"]
40 if dpi != "0":
41 props.append("ro.sf.lcd_density=" + dpi)
42
43 final_props = open(full_props_path, "w")
44 for prop in props:
45 final_props.write(prop + "\n")
46 final_props.close()
47 os.chmod(full_props_path, 0o644)
48
49 def set_permissions(perm_list=None, mode="777"):
50 def chmod(path, mode):
51 if os.path.exists(path):
52 command = ["chmod", mode, "-R", path]
53 tools.helpers.run.user(args, command, check=False)
54
55 # Nodes list
56 if not perm_list:
57 perm_list = [
58 "/dev/ashmem",
59
60 # sw_sync for HWC
61 "/dev/sw_sync",
62 "/sys/kernel/debug/sync/sw_sync",
63
64 # Media
65 "/dev/Vcodec",
66 "/dev/MTK_SMI",
67 "/dev/mdp_sync",
68 "/dev/mtk_cmdq",
69
70 # Graphics
71 "/dev/dri",
72 "/dev/graphics",
73 "/dev/pvr_sync",
74 "/dev/ion",
75 ]
76
77 # Framebuffers
78 perm_list.extend(glob.glob("/dev/fb*"))
79 # Videos
80 perm_list.extend(glob.glob("/dev/video*"))
81
82 for path in perm_list:
83 chmod(path, mode)
84
85 def set_aidl_version():
86 cfg = tools.config.load(args)
87 android_api = 0
88 try:
89 mnt = "/tmp/waydroid-" + str(uuid.uuid1())
90 helpers.mount.mount(args, cfg["waydroid"]["images_path"] + "/system.img", mnt)
91 android_api = int(helpers.props.file_get(args, mnt + "/system/build.prop",
92 "ro.build.version.sdk"))
93 except:
94 logging.error("Failed to parse android version from system.img")
95 finally:
96 helpers.mount.umount_all(args, mnt);
97
98 if android_api < 28:
99 binder_protocol = "aidl"
100 sm_protocol = "aidl"
101 elif android_api < 30:
102 binder_protocol = "aidl2"
103 sm_protocol = "aidl2"
104 elif android_api < 31:
105 binder_protocol = "aidl3"
106 sm_protocol = "aidl3"
107 else:
108 binder_protocol = "aidl3"
109 sm_protocol = "aidl4"
110
111 cfg["waydroid"]["binder_protocol"] = binder_protocol
112 cfg["waydroid"]["service_manager_protocol"] = sm_protocol
113 tools.config.save(args, cfg)
114
115 def signal_handler(sig, frame):
116 services.hardware_manager.stop(args)
117 stop(args)
118 sys.exit(0)
119
120 set_aidl_version()
121
122 status = helpers.lxc.status(args)
123 if status == "STOPPED":
124 # Load binder and ashmem drivers
125 cfg = tools.config.load(args)
126 if cfg["waydroid"]["vendor_type"] == "MAINLINE":
127 if helpers.drivers.probeBinderDriver(args) != 0:
128 logging.error("Failed to load Binder driver")
129 if helpers.drivers.probeAshmemDriver(args) != 0:
130 logging.error("Failed to load Ashmem driver")
131 helpers.drivers.loadBinderNodes(args)
132 set_permissions([
133 "/dev/" + args.BINDER_DRIVER,
134 "/dev/" + args.VNDBINDER_DRIVER,
135 "/dev/" + args.HWBINDER_DRIVER
136 ], "666")
137
138 if os.path.exists(tools.config.session_defaults["config_path"]):
139 session_cfg = tools.config.load_session()
140 if session_cfg["session"]["state"] != "STOPPED":
141 logging.warning("Found session config on state: {}, restart session".format(
142 session_cfg["session"]["state"]))
143 os.remove(tools.config.session_defaults["config_path"])
144 logging.debug("Container manager is waiting for session to load")
145 while not os.path.exists(tools.config.session_defaults["config_path"]):
146 time.sleep(1)
147
148 # Load session configs
149 session_cfg = tools.config.load_session()
150
151 # Generate props
152 make_prop(args.work + "/waydroid.prop")
153
154 # Networking
155 command = [tools.config.tools_src +
156 "/data/scripts/waydroid-net.sh", "start"]
157 tools.helpers.run.user(args, command, check=False)
158
159 # Sensors
160 if which("waydroid-sensord"):
161 tools.helpers.run.user(
162 args, ["waydroid-sensord", "/dev/" + args.HWBINDER_DRIVER], output="background")
163
164 # Mount rootfs
165 helpers.images.mount_rootfs(args, cfg["waydroid"]["images_path"])
166
167 # Mount data
168 helpers.mount.bind(args, session_cfg["session"]["waydroid_data"],
169 tools.config.defaults["data"])
170
171 # Cgroup hacks
172 if which("start"):
173 command = ["start", "cgroup-lite"]
174 tools.helpers.run.user(args, command, check=False)
175 command = ["umount", "-l", "/sys/fs/cgroup/schedtune"]
176 tools.helpers.run.user(args, command, check=False)
177
178 #TODO: remove NFC hacks
179 if which("stop"):
180 command = ["stop", "nfcd"]
181 tools.helpers.run.user(args, command, check=False)
182
183 # Set permissions
184 set_permissions()
185
186 helpers.lxc.start(args)
187 session_cfg["session"]["state"] = helpers.lxc.status(args)
188 timeout = 10
189 while session_cfg["session"]["state"] != "RUNNING" and timeout > 0:
190 session_cfg["session"]["state"] = helpers.lxc.status(args)
191 logging.info(
192 "waiting {} seconds for container to start...".format(timeout))
193 timeout = timeout - 1
194 time.sleep(1)
195 if session_cfg["session"]["state"] != "RUNNING":
196 raise OSError("container failed to start")
197 tools.config.save_session(session_cfg)
198
199 services.hardware_manager.start(args)
200
201 signal.signal(signal.SIGINT, signal_handler)
202 while os.path.exists(tools.config.session_defaults["config_path"]):
203 session_cfg = tools.config.load_session()
204 if session_cfg["session"]["state"] == "STOPPED":
205 services.hardware_manager.stop(args)
206 sys.exit(0)
207 elif session_cfg["session"]["state"] == "UNFREEZE":
208 session_cfg["session"]["state"] = helpers.lxc.status(args)
209 tools.config.save_session(session_cfg)
210 unfreeze(args)
211 time.sleep(1)
212
213 logging.warning("session manager stopped, stopping container and waiting...")
214 stop(args)
215 services.hardware_manager.stop(args)
216 start(args)
217 else:
218 logging.error("WayDroid container is {}".format(status))
219
220 def stop(args):
221 status = helpers.lxc.status(args)
222 if status != "STOPPED":
223 helpers.lxc.stop(args)
224 if os.path.exists(tools.config.session_defaults["config_path"]):
225 session_cfg = tools.config.load_session()
226 session_cfg["session"]["state"] = helpers.lxc.status(args)
227 tools.config.save_session(session_cfg)
228
229 # Networking
230 command = [tools.config.tools_src +
231 "/data/scripts/waydroid-net.sh", "stop"]
232 tools.helpers.run.user(args, command, check=False)
233
234 #TODO: remove NFC hacks
235 if which("start"):
236 command = ["start", "nfcd"]
237 tools.helpers.run.user(args, command, check=False)
238
239 # Sensors
240 if which("waydroid-sensord"):
241 command = ["pidof", "waydroid-sensord"]
242 pid = tools.helpers.run.user(args, command, check=False, output_return=True).strip()
243 if pid:
244 command = ["kill", "-9", pid]
245 tools.helpers.run.user(args, command, check=False)
246
247 # Umount rootfs
248 helpers.images.umount_rootfs(args)
249
250 # Umount data
251 helpers.mount.umount_all(args, tools.config.defaults["data"])
252
253 else:
254 logging.error("WayDroid container is {}".format(status))
255
256 def restart(args):
257 status = helpers.lxc.status(args)
258 if status == "RUNNING":
259 helpers.lxc.stop(args)
260 helpers.lxc.start(args)
261 else:
262 logging.error("WayDroid container is {}".format(status))
263
264 def freeze(args):
265 status = helpers.lxc.status(args)
266 if status == "RUNNING":
267 helpers.lxc.freeze(args)
268 if os.path.exists(tools.config.session_defaults["config_path"]):
269 session_cfg = tools.config.load_session()
270 session_cfg["session"]["state"] = helpers.lxc.status(args)
271 tools.config.save_session(session_cfg)
272 else:
273 logging.error("WayDroid container is {}".format(status))
274
275 def unfreeze(args):
276 status = helpers.lxc.status(args)
277 if status == "FROZEN":
278 helpers.lxc.unfreeze(args)
279 if os.path.exists(tools.config.session_defaults["config_path"]):
280 session_cfg = tools.config.load_session()
281 session_cfg["session"]["state"] = helpers.lxc.status(args)
282 tools.config.save_session(session_cfg)
283 else:
284 logging.error("WayDroid container is {}".format(status))