]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/interfaces/IPlatform.py
arch: Fallback to arm on weird arm64 kernels with 32-bit userspace
[waydroid.git] / tools / interfaces / IPlatform.py
1 import gbinder
2 import logging
3 import time
4 from tools import helpers
5 from gi.repository import GLib
6 import signal
7
8
9 INTERFACE = "lineageos.waydroid.IPlatform"
10 SERVICE_NAME = "waydroidplatform"
11
12 TRANSACTION_getprop = 1
13 TRANSACTION_setprop = 2
14 TRANSACTION_getAppsInfo = 3
15 TRANSACTION_getAppInfo = 4
16 TRANSACTION_installApp = 5
17 TRANSACTION_removeApp = 6
18 TRANSACTION_launchApp = 7
19 TRANSACTION_getAppName = 8
20 TRANSACTION_settingsPutString = 9
21 TRANSACTION_settingsGetString = 10
22 TRANSACTION_settingsPutInt = 11
23 TRANSACTION_settingsGetInt = 12
24 TRANSACTION_launchIntent = 13
25
26 class IPlatform:
27 def __init__(self, remote):
28 self.client = gbinder.Client(remote, INTERFACE)
29
30 def getprop(self, arg1, arg2):
31 request = self.client.new_request()
32 request.append_string16(arg1)
33 request.append_string16(arg2)
34 reply, status = self.client.transact_sync_reply(
35 TRANSACTION_getprop, request)
36
37 if status:
38 logging.error("Sending reply failed")
39 else:
40 reader = reply.init_reader()
41 status, exception = reader.read_int32()
42 if exception == 0:
43 rep1 = reader.read_string16()
44 return rep1
45 else:
46 logging.error("Failed with code: {}".format(exception))
47
48 return None
49
50 def setprop(self, arg1, arg2):
51 request = self.client.new_request()
52 request.append_string16(arg1)
53 request.append_string16(arg2)
54 reply, status = self.client.transact_sync_reply(
55 TRANSACTION_setprop, request)
56
57 if status:
58 logging.error("Sending reply failed")
59 else:
60 reader = reply.init_reader()
61 status, exception = reader.read_int32()
62 if exception == 0:
63 return
64 else:
65 logging.error("Failed with code: {}".format(exception))
66
67 return
68
69 def getAppsInfo(self):
70 request = self.client.new_request()
71 reply, status = self.client.transact_sync_reply(
72 TRANSACTION_getAppsInfo, request)
73
74 if status:
75 logging.error("Sending reply failed")
76 else:
77 reader = reply.init_reader()
78 apps_list = []
79 status, exception = reader.read_int32()
80 if exception == 0:
81 status, apps = reader.read_int32()
82 for j in range(apps):
83 status, has_value = reader.read_int32()
84 if has_value == 1:
85 appinfo = {
86 "name": reader.read_string16(),
87 "packageName": reader.read_string16(),
88 "action": reader.read_string16(),
89 "launchIntent": reader.read_string16(),
90 "componentPackageName": reader.read_string16(),
91 "componentClassName": reader.read_string16(),
92 "categories": []
93 }
94 status, categories = reader.read_int32()
95 for i in range(categories):
96 appinfo["categories"].append(reader.read_string16())
97 apps_list.append(appinfo)
98 else:
99 logging.error("Failed with code: {}".format(exception))
100
101 return apps_list
102
103 def getAppInfo(self, arg1):
104 request = self.client.new_request()
105 request.append_string16(arg1)
106 reply, status = self.client.transact_sync_reply(
107 TRANSACTION_getAppInfo, request)
108
109 if status:
110 logging.error("Sending reply failed")
111 else:
112 reader = reply.init_reader()
113 status, exception = reader.read_int32()
114 if exception == 0:
115 status, has_value = reader.read_int32()
116 if has_value == 1:
117 appinfo = {
118 "name": reader.read_string16(),
119 "packageName": reader.read_string16(),
120 "action": reader.read_string16(),
121 "launchIntent": reader.read_string16(),
122 "componentPackageName": reader.read_string16(),
123 "componentClassName": reader.read_string16(),
124 "categories": []
125 }
126 status, categories = reader.read_int32()
127 for i in range(categories):
128 appinfo["categories"].append(reader.read_string16())
129
130 return appinfo
131 else:
132 logging.error("Failed with code: {}".format(exception))
133
134 return None
135
136 def installApp(self, arg1):
137 request = self.client.new_request()
138 request.append_string16(arg1)
139 reply, status = self.client.transact_sync_reply(
140 TRANSACTION_installApp, request)
141
142 if status:
143 logging.error("Sending reply failed")
144 else:
145 reader = reply.init_reader()
146 status, exception = reader.read_int32()
147 if exception == 0:
148 status, ret = reader.read_int32()
149 return ret
150 else:
151 logging.error("Failed with code: {}".format(exception))
152
153 return None
154
155 def removeApp(self, arg1):
156 request = self.client.new_request()
157 request.append_string16(arg1)
158 reply, status = self.client.transact_sync_reply(
159 TRANSACTION_removeApp, request)
160
161 if status:
162 logging.error("Sending reply failed")
163 else:
164 reader = reply.init_reader()
165 status, exception = reader.read_int32()
166 if exception == 0:
167 status, ret = reader.read_int32()
168 return ret
169 else:
170 logging.error("Failed with code: {}".format(exception))
171
172 return None
173
174 def launchApp(self, arg1):
175 request = self.client.new_request()
176 request.append_string16(arg1)
177 reply, status = self.client.transact_sync_reply(
178 TRANSACTION_launchApp, request)
179
180 if status:
181 logging.error("Sending reply failed")
182 else:
183 reader = reply.init_reader()
184 status, exception = reader.read_int32()
185 if exception != 0:
186 logging.error("Failed with code: {}".format(exception))
187
188 def launchIntent(self, arg1, arg2):
189 request = self.client.new_request()
190 request.append_string16(arg1)
191 request.append_string16(arg2)
192 reply, status = self.client.transact_sync_reply(
193 TRANSACTION_launchIntent, request)
194
195 if status:
196 logging.error("Sending reply failed")
197 else:
198 reader = reply.init_reader()
199 status, exception = reader.read_int32()
200 if exception == 0:
201 rep1 = reader.read_string16()
202 return rep1
203 else:
204 logging.error("Failed with code: {}".format(exception))
205 return None
206
207 def getAppName(self, arg1):
208 request = self.client.new_request()
209 request.append_string16(arg1)
210 reply, status = self.client.transact_sync_reply(
211 TRANSACTION_getAppName, request)
212
213 if status:
214 logging.error("Sending reply failed")
215 else:
216 reader = reply.init_reader()
217 status, exception = reader.read_int32()
218 if exception == 0:
219 rep1 = reader.read_string16()
220 return rep1
221 else:
222 logging.error("Failed with code: {}".format(exception))
223
224 return None
225
226 def settingsPutString(self, arg1, arg2, arg3):
227 request = self.client.new_request()
228 request.append_int32(arg1)
229 request.append_string16(arg2)
230 request.append_string16(arg3)
231 reply, status = self.client.transact_sync_reply(
232 TRANSACTION_settingsPutString, request)
233
234 if status:
235 logging.error("Sending reply failed")
236 else:
237 reader = reply.init_reader()
238 status, exception = reader.read_int32()
239 if exception != 0:
240 logging.error("Failed with code: {}".format(exception))
241
242 def settingsGetString(self, arg1, arg2):
243 request = self.client.new_request()
244 request.append_int32(arg1)
245 request.append_string16(arg2)
246 reply, status = self.client.transact_sync_reply(
247 TRANSACTION_settingsGetString, request)
248
249 if status:
250 logging.error("Sending reply failed")
251 else:
252 reader = reply.init_reader()
253 status, exception = reader.read_int32()
254 if exception == 0:
255 rep1 = reader.read_string16()
256 return rep1
257 else:
258 logging.error("Failed with code: {}".format(exception))
259
260 return None
261
262 def settingsPutInt(self, arg1, arg2, arg3):
263 request = self.client.new_request()
264 request.append_int32(arg1)
265 request.append_string16(arg2)
266 request.append_int32(arg3)
267 reply, status = self.client.transact_sync_reply(
268 TRANSACTION_settingsPutInt, request)
269
270 if status:
271 logging.error("Sending reply failed")
272 else:
273 reader = reply.init_reader()
274 status, exception = reader.read_int32()
275 if exception != 0:
276 logging.error("Failed with code: {}".format(exception))
277
278 def settingsGetInt(self, arg1, arg2):
279 request = self.client.new_request()
280 request.append_int32(arg1)
281 request.append_string16(arg2)
282 reply, status = self.client.transact_sync_reply(
283 TRANSACTION_settingsGetString, request)
284
285 if status:
286 logging.error("Sending reply failed")
287 else:
288 reader = reply.init_reader()
289 status, exception = reader.read_int32()
290 if exception == 0:
291 status, rep1 = reader.read_int32()
292 return rep1
293 else:
294 logging.error("Failed with code: {}".format(exception))
295
296 return None
297
298 def get_service(args):
299 helpers.drivers.loadBinderNodes(args)
300 try:
301 serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER, args.SERVICE_MANAGER_PROTOCOL, args.BINDER_PROTOCOL)
302 except TypeError:
303 serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER)
304
305 if not serviceManager.is_present():
306 logging.info("Waiting for binder Service Manager...")
307 if not wait_for_manager(serviceManager):
308 logging.error("Service Manager never appeared")
309 return None
310
311 tries = 1000
312
313 remote, status = serviceManager.get_service_sync(SERVICE_NAME)
314 while(not remote):
315 if tries > 0:
316 logging.warning(
317 "Failed to get service {}, trying again...".format(SERVICE_NAME))
318 time.sleep(1)
319 remote, status = serviceManager.get_service_sync(SERVICE_NAME)
320 tries = tries - 1
321 else:
322 return None
323
324 return IPlatform(remote)
325
326 # Like ServiceManager.wait() but can be interrupted
327 def wait_for_manager(sm):
328 mainloop = GLib.MainLoop()
329 hndl = sm.add_presence_handler(lambda: mainloop.quit() if sm.is_present() else None)
330 GLib.timeout_add_seconds(60, lambda: mainloop.quit())
331 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, lambda _: mainloop.quit(), None)
332 mainloop.run()
333 sm.remove_handler(hndl)
334 if not sm.is_present():
335 return False
336 return True