]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/helpers/drivers.py
user_manager: Fix app removal
[waydroid.git] / tools / helpers / drivers.py
1 # Copyright 2021 Erfan Abdi
2 # SPDX-License-Identifier: GPL-3.0-or-later
3 import logging
4 import os
5 import glob
6 import fcntl
7 import struct
8 import tools.config
9 import tools.helpers.run
10
11
12 BINDER_DRIVERS = [
13 "anbox-binder",
14 "puddlejumper",
15 "bonder",
16 "binder"
17 ]
18 VNDBINDER_DRIVERS = [
19 "anbox-vndbinder",
20 "vndpuddlejumper",
21 "vndbonder",
22 "vndbinder"
23 ]
24 HWBINDER_DRIVERS = [
25 "anbox-hwbinder",
26 "hwpuddlejumper",
27 "hwbonder",
28 "hwbinder"
29 ]
30
31
32 def isBinderfsLoaded(args):
33 with open("/proc/filesystems", "r") as handle:
34 for line in handle:
35 words = line.split()
36 if len(words) >= 2 and words[1] == "binder":
37 return True
38
39 return False
40
41 def allocBinderNodes(args, binder_dev_nodes):
42 NRBITS = 8
43 TYPEBITS = 8
44 SIZEBITS = 14
45 NRSHIFT = 0
46 TYPESHIFT = NRSHIFT + NRBITS
47 SIZESHIFT = TYPESHIFT + TYPEBITS
48 DIRSHIFT = SIZESHIFT + SIZEBITS
49 WRITE = 0x1
50 READ = 0x2
51
52 def IOC(direction, _type, nr, size):
53 return (direction << DIRSHIFT) | (_type << TYPESHIFT) | (nr << NRSHIFT) | (size << SIZESHIFT)
54
55 def IOWR(_type, nr, size):
56 return IOC(READ|WRITE, _type, nr, size)
57
58 BINDER_CTL_ADD = IOWR(98, 1, 264)
59 binderctrlfd = open('/dev/binderfs/binder-control','rb')
60
61 for node in binder_dev_nodes:
62 node_struct = struct.pack(
63 '256sII', bytes(node, 'utf-8'), 0, 0)
64 try:
65 fcntl.ioctl(binderctrlfd.fileno(), BINDER_CTL_ADD, node_struct)
66 except FileExistsError:
67 pass
68
69 def probeBinderDriver(args):
70 binder_dev_nodes = []
71 has_binder = False
72 has_vndbinder = False
73 has_hwbinder = False
74 for node in BINDER_DRIVERS:
75 if os.path.exists("/dev/" + node):
76 has_binder = True
77 if not has_binder:
78 binder_dev_nodes.append(BINDER_DRIVERS[0])
79 for node in VNDBINDER_DRIVERS:
80 if os.path.exists("/dev/" + node):
81 has_vndbinder = True
82 if not has_vndbinder:
83 binder_dev_nodes.append(VNDBINDER_DRIVERS[0])
84 for node in HWBINDER_DRIVERS:
85 if os.path.exists("/dev/" + node):
86 has_hwbinder = True
87 if not has_hwbinder:
88 binder_dev_nodes.append(HWBINDER_DRIVERS[0])
89
90 if len(binder_dev_nodes) > 0:
91 if not isBinderfsLoaded(args):
92 devices = ','.join(binder_dev_nodes)
93 command = ["modprobe", "binder_linux",
94 "devices=\"{}\"".format(devices)]
95 output = tools.helpers.run.user(args, command, check=False, output_return=True)
96 if output:
97 logging.error("Failed to load binder driver")
98 logging.error(output.strip())
99
100 if isBinderfsLoaded(args):
101 command = ["mkdir", "-p", "/dev/binderfs"]
102 tools.helpers.run.user(args, command, check=False)
103 command = ["mount", "-t", "binder", "binder", "/dev/binderfs"]
104 tools.helpers.run.user(args, command, check=False)
105 allocBinderNodes(args, binder_dev_nodes)
106 command = ["ln", "-s"]
107 command.extend(glob.glob("/dev/binderfs/*"))
108 command.append("/dev/")
109 tools.helpers.run.user(args, command, check=False)
110
111 return 0
112
113 def probeAshmemDriver(args):
114 if not os.path.exists("/dev/ashmem"):
115 command = ["modprobe", "-q", "ashmem_linux"]
116 tools.helpers.run.user(args, command, check=False)
117
118 if not os.path.exists("/dev/ashmem"):
119 return -1
120
121 return 0
122
123 def setupBinderNodes(args):
124 has_binder = False
125 has_vndbinder = False
126 has_hwbinder = False
127 if args.vendor_type == "MAINLINE":
128 probeBinderDriver(args)
129 for node in BINDER_DRIVERS:
130 if os.path.exists("/dev/" + node):
131 has_binder = True
132 args.BINDER_DRIVER = node
133 if not has_binder:
134 raise OSError('Binder node "binder" for waydroid not found')
135
136 for node in VNDBINDER_DRIVERS:
137 if os.path.exists("/dev/" + node):
138 has_vndbinder = True
139 args.VNDBINDER_DRIVER = node
140 if not has_vndbinder:
141 raise OSError('Binder node "vndbinder" for waydroid not found')
142
143 for node in HWBINDER_DRIVERS:
144 if os.path.exists("/dev/" + node):
145 has_hwbinder = True
146 args.HWBINDER_DRIVER = node
147 if not has_hwbinder:
148 raise OSError('Binder node "hwbinder" for waydroid not found')
149 else:
150 for node in BINDER_DRIVERS[:-1]:
151 if os.path.exists("/dev/" + node):
152 has_binder = True
153 args.BINDER_DRIVER = node
154 if not has_binder:
155 raise OSError('Binder node "binder" for waydroid not found')
156
157 for node in VNDBINDER_DRIVERS[:-1]:
158 if os.path.exists("/dev/" + node):
159 has_vndbinder = True
160 args.VNDBINDER_DRIVER = node
161 if not has_vndbinder:
162 raise OSError('Binder node "vndbinder" for waydroid not found')
163
164 for node in HWBINDER_DRIVERS[:-1]:
165 if os.path.exists("/dev/" + node):
166 has_hwbinder = True
167 args.HWBINDER_DRIVER = node
168 if not has_hwbinder:
169 raise OSError('Binder node "hwbinder" for waydroid not found')
170
171 def loadBinderNodes(args):
172 cfg = tools.config.load(args)
173 args.BINDER_DRIVER = cfg["waydroid"]["binder"]
174 args.VNDBINDER_DRIVER = cfg["waydroid"]["vndbinder"]
175 args.HWBINDER_DRIVER = cfg["waydroid"]["hwbinder"]
176 # These might not be in cfg on package upgrade
177 args.BINDER_PROTOCOL = cfg["waydroid"].get("binder_protocol")
178 args.SERVICE_MANAGER_PROTOCOL = cfg["waydroid"].get("service_manager_protocol")