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