]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/container_manager.py
version: Don't fail when uname contains only two numbers
[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 import dbus
15 import dbus.service
16 import dbus.exceptions
17 from gi.repository import GLib
18
19 class DbusContainerManager(dbus.service.Object):
20 def __init__(self, looper, bus, object_path, args):
21 self.args = args
22 self.looper = looper
23 dbus.service.Object.__init__(self, bus, object_path)
24
25 @dbus.service.method("id.waydro.ContainerManager", in_signature='a{ss}', out_signature='')
26 def Start(self, session):
27 do_start(self.args, session)
28
29 @dbus.service.method("id.waydro.ContainerManager", in_signature='b', out_signature='')
30 def Stop(self, quit_session):
31 stop(self.args, quit_session)
32
33 @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='')
34 def Freeze(self):
35 freeze(self.args)
36
37 @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='')
38 def Unfreeze(self):
39 unfreeze(self.args)
40
41 @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='a{ss}')
42 def GetSession(self):
43 try:
44 session = self.args.session
45 session["state"] = helpers.lxc.status(self.args)
46 return session
47 except AttributeError:
48 return {}
49
50 def service(args, looper):
51 dbus_obj = DbusContainerManager(looper, dbus.SystemBus(), '/ContainerManager', args)
52 looper.run()
53
54 def set_permissions(args, perm_list=None, mode="777"):
55 def chmod(path, mode):
56 if os.path.exists(path):
57 command = ["chmod", mode, "-R", path]
58 tools.helpers.run.user(args, command, check=False)
59
60 # Nodes list
61 if not perm_list:
62 perm_list = [
63 "/dev/ashmem",
64
65 # sw_sync for HWC
66 "/dev/sw_sync",
67 "/sys/kernel/debug/sync/sw_sync",
68
69 # Media
70 "/dev/Vcodec",
71 "/dev/MTK_SMI",
72 "/dev/mdp_sync",
73 "/dev/mtk_cmdq",
74
75 # Graphics
76 "/dev/dri",
77 "/dev/graphics",
78 "/dev/pvr_sync",
79 "/dev/ion",
80 ]
81
82 # Framebuffers
83 perm_list.extend(glob.glob("/dev/fb*"))
84 # Videos
85 perm_list.extend(glob.glob("/dev/video*"))
86
87 for path in perm_list:
88 chmod(path, mode)
89
90 def start(args):
91 try:
92 name = dbus.service.BusName("id.waydro.Container", dbus.SystemBus(), do_not_queue=True)
93 except dbus.exceptions.NameExistsException:
94 logging.error("Container service is already running")
95 return
96
97 status = helpers.lxc.status(args)
98 if status == "STOPPED":
99 # Load binder and ashmem drivers
100 cfg = tools.config.load(args)
101 if cfg["waydroid"]["vendor_type"] == "MAINLINE":
102 if helpers.drivers.probeBinderDriver(args) != 0:
103 logging.error("Failed to load Binder driver")
104 helpers.drivers.probeAshmemDriver(args)
105 helpers.drivers.loadBinderNodes(args)
106 set_permissions(args, [
107 "/dev/" + args.BINDER_DRIVER,
108 "/dev/" + args.VNDBINDER_DRIVER,
109 "/dev/" + args.HWBINDER_DRIVER
110 ], "666")
111
112 mainloop = GLib.MainLoop()
113
114 def sigint_handler(data):
115 stop(args)
116 mainloop.quit()
117
118 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, sigint_handler, None)
119 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGTERM, sigint_handler, None)
120 service(args, mainloop)
121 else:
122 logging.error("WayDroid container is {}".format(status))
123
124 def do_start(args, session):
125 if "session" in args:
126 raise RuntimeError("Already tracking a session")
127
128 # Networking
129 command = [tools.config.tools_src +
130 "/data/scripts/waydroid-net.sh", "start"]
131 tools.helpers.run.user(args, command)
132
133 # Sensors
134 if which("waydroid-sensord"):
135 tools.helpers.run.user(
136 args, ["waydroid-sensord", "/dev/" + args.HWBINDER_DRIVER], output="background")
137
138 # Mount rootfs
139 cfg = tools.config.load(args)
140 helpers.images.mount_rootfs(args, cfg["waydroid"]["images_path"], session)
141
142 helpers.protocol.set_aidl_version(args)
143
144 # Mount data
145 helpers.mount.bind(args, session["waydroid_data"],
146 tools.config.defaults["data"])
147
148 # Cgroup hacks
149 if which("start"):
150 command = ["start", "cgroup-lite"]
151 tools.helpers.run.user(args, command, check=False)
152 if os.path.ismount("/sys/fs/cgroup/schedtune"):
153 command = ["umount", "-l", "/sys/fs/cgroup/schedtune"]
154 tools.helpers.run.user(args, command, check=False)
155
156 #TODO: remove NFC hacks
157 if which("stop"):
158 command = ["stop", "nfcd"]
159 tools.helpers.run.user(args, command, check=False)
160
161 # Set permissions
162 set_permissions(args)
163
164 helpers.lxc.start(args)
165 services.hardware_manager.start(args)
166
167 args.session = session
168
169 def stop(args, quit_session=True):
170 try:
171 services.hardware_manager.stop(args)
172 status = helpers.lxc.status(args)
173 if status != "STOPPED":
174 helpers.lxc.stop(args)
175 while helpers.lxc.status(args) != "STOPPED":
176 pass
177
178 # Networking
179 command = [tools.config.tools_src +
180 "/data/scripts/waydroid-net.sh", "stop"]
181 tools.helpers.run.user(args, command, check=False)
182
183 #TODO: remove NFC hacks
184 if which("start"):
185 command = ["start", "nfcd"]
186 tools.helpers.run.user(args, command, check=False)
187
188 # Sensors
189 if which("waydroid-sensord"):
190 command = ["pidof", "waydroid-sensord"]
191 pid = tools.helpers.run.user(args, command, check=False, output_return=True).strip()
192 if pid:
193 command = ["kill", "-9", pid]
194 tools.helpers.run.user(args, command, check=False)
195
196 # Umount rootfs
197 helpers.images.umount_rootfs(args)
198
199 # Umount data
200 helpers.mount.umount_all(args, tools.config.defaults["data"])
201
202 if "session" in args:
203 if quit_session:
204 try:
205 os.kill(int(args.session["pid"]), signal.SIGUSR1)
206 except:
207 pass
208 del args.session
209 except:
210 pass
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 while helpers.lxc.status(args) == "RUNNING":
225 pass
226 else:
227 logging.error("WayDroid container is {}".format(status))
228
229 def unfreeze(args):
230 status = helpers.lxc.status(args)
231 if status == "FROZEN":
232 helpers.lxc.unfreeze(args)
233 while helpers.lxc.status(args) == "FROZEN":
234 pass