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