]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/container_manager.py
Default nvidia to swiftshader
[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 android_api = int(helpers.props.file_get(args,
90 tools.config.defaults["rootfs"] + "/system/build.prop",
91 "ro.build.version.sdk"))
92 except:
93 logging.error("Failed to parse android version from system.img")
94
95 if android_api < 28:
96 binder_protocol = "aidl"
97 sm_protocol = "aidl"
98 elif android_api < 30:
99 binder_protocol = "aidl2"
100 sm_protocol = "aidl2"
101 elif android_api < 31:
102 binder_protocol = "aidl3"
103 sm_protocol = "aidl3"
104 else:
105 binder_protocol = "aidl3"
106 sm_protocol = "aidl4"
107
108 cfg["waydroid"]["binder_protocol"] = binder_protocol
109 cfg["waydroid"]["service_manager_protocol"] = sm_protocol
110 tools.config.save(args, cfg)
111
112 def signal_handler(sig, frame):
113 services.hardware_manager.stop(args)
114 stop(args)
115 sys.exit(0)
116
117 status = helpers.lxc.status(args)
118 if status == "STOPPED":
119 # Load binder and ashmem drivers
120 cfg = tools.config.load(args)
121 if cfg["waydroid"]["vendor_type"] == "MAINLINE":
122 if helpers.drivers.probeBinderDriver(args) != 0:
123 logging.error("Failed to load Binder driver")
124 if helpers.drivers.probeAshmemDriver(args) != 0:
125 logging.error("Failed to load Ashmem driver")
126 helpers.drivers.loadBinderNodes(args)
127 set_permissions([
128 "/dev/" + args.BINDER_DRIVER,
129 "/dev/" + args.VNDBINDER_DRIVER,
130 "/dev/" + args.HWBINDER_DRIVER
131 ], "666")
132
133 if os.path.exists(tools.config.session_defaults["config_path"]):
134 session_cfg = tools.config.load_session()
135 if session_cfg["session"]["state"] != "STOPPED":
136 logging.warning("Found session config on state: {}, restart session".format(
137 session_cfg["session"]["state"]))
138 os.remove(tools.config.session_defaults["config_path"])
139 logging.debug("Container manager is waiting for session to load")
140 while not os.path.exists(tools.config.session_defaults["config_path"]):
141 time.sleep(1)
142
143 # Load session configs
144 session_cfg = tools.config.load_session()
145
146 # Generate props
147 make_prop(args.work + "/waydroid.prop")
148
149 # Networking
150 command = [tools.config.tools_src +
151 "/data/scripts/waydroid-net.sh", "start"]
152 tools.helpers.run.user(args, command, check=False)
153
154 # Sensors
155 if which("waydroid-sensord"):
156 tools.helpers.run.user(
157 args, ["waydroid-sensord", "/dev/" + args.HWBINDER_DRIVER], output="background")
158
159 # Mount rootfs
160 helpers.images.mount_rootfs(args, cfg["waydroid"]["images_path"])
161
162 set_aidl_version()
163
164 # Mount data
165 helpers.mount.bind(args, session_cfg["session"]["waydroid_data"],
166 tools.config.defaults["data"])
167
168 # Cgroup hacks
169 if which("start"):
170 command = ["start", "cgroup-lite"]
171 tools.helpers.run.user(args, command, check=False)
172 command = ["umount", "-l", "/sys/fs/cgroup/schedtune"]
173 tools.helpers.run.user(args, command, check=False)
174
175 #TODO: remove NFC hacks
176 if which("stop"):
177 command = ["stop", "nfcd"]
178 tools.helpers.run.user(args, command, check=False)
179
180 # Set permissions
181 set_permissions()
182
183 helpers.lxc.start(args)
184 session_cfg["session"]["state"] = helpers.lxc.status(args)
185 timeout = 10
186 while session_cfg["session"]["state"] != "RUNNING" and timeout > 0:
187 session_cfg["session"]["state"] = helpers.lxc.status(args)
188 logging.info(
189 "waiting {} seconds for container to start...".format(timeout))
190 timeout = timeout - 1
191 time.sleep(1)
192 if session_cfg["session"]["state"] != "RUNNING":
193 raise OSError("container failed to start")
194 tools.config.save_session(session_cfg)
195
196 services.hardware_manager.start(args)
197
198 signal.signal(signal.SIGINT, signal_handler)
199 while os.path.exists(tools.config.session_defaults["config_path"]):
200 session_cfg = tools.config.load_session()
201 if session_cfg["session"]["state"] == "STOPPED":
202 services.hardware_manager.stop(args)
203 sys.exit(0)
204 elif session_cfg["session"]["state"] == "UNFREEZE":
205 session_cfg["session"]["state"] = helpers.lxc.status(args)
206 tools.config.save_session(session_cfg)
207 unfreeze(args)
208 time.sleep(1)
209
210 logging.warning("session manager stopped, stopping container and waiting...")
211 stop(args)
212 services.hardware_manager.stop(args)
213 start(args)
214 else:
215 logging.error("WayDroid container is {}".format(status))
216
217 def stop(args):
218 status = helpers.lxc.status(args)
219 if status != "STOPPED":
220 helpers.lxc.stop(args)
221 if os.path.exists(tools.config.session_defaults["config_path"]):
222 session_cfg = tools.config.load_session()
223 session_cfg["session"]["state"] = helpers.lxc.status(args)
224 tools.config.save_session(session_cfg)
225
226 # Networking
227 command = [tools.config.tools_src +
228 "/data/scripts/waydroid-net.sh", "stop"]
229 tools.helpers.run.user(args, command, check=False)
230
231 #TODO: remove NFC hacks
232 if which("start"):
233 command = ["start", "nfcd"]
234 tools.helpers.run.user(args, command, check=False)
235
236 # Sensors
237 if which("waydroid-sensord"):
238 command = ["pidof", "waydroid-sensord"]
239 pid = tools.helpers.run.user(args, command, check=False, output_return=True).strip()
240 if pid:
241 command = ["kill", "-9", pid]
242 tools.helpers.run.user(args, command, check=False)
243
244 # Umount rootfs
245 helpers.images.umount_rootfs(args)
246
247 # Umount data
248 helpers.mount.umount_all(args, tools.config.defaults["data"])
249
250 else:
251 logging.error("WayDroid container is {}".format(status))
252
253 def restart(args):
254 status = helpers.lxc.status(args)
255 if status == "RUNNING":
256 helpers.lxc.stop(args)
257 helpers.lxc.start(args)
258 else:
259 logging.error("WayDroid container is {}".format(status))
260
261 def freeze(args):
262 status = helpers.lxc.status(args)
263 if status == "RUNNING":
264 helpers.lxc.freeze(args)
265 if os.path.exists(tools.config.session_defaults["config_path"]):
266 session_cfg = tools.config.load_session()
267 session_cfg["session"]["state"] = helpers.lxc.status(args)
268 tools.config.save_session(session_cfg)
269 else:
270 logging.error("WayDroid container is {}".format(status))
271
272 def unfreeze(args):
273 status = helpers.lxc.status(args)
274 if status == "FROZEN":
275 helpers.lxc.unfreeze(args)
276 if os.path.exists(tools.config.session_defaults["config_path"]):
277 session_cfg = tools.config.load_session()
278 session_cfg["session"]["state"] = helpers.lxc.status(args)
279 tools.config.save_session(session_cfg)
280 else:
281 logging.error("WayDroid container is {}".format(status))