]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/helpers/images.py
Fix prop set command
[waydroid.git] / tools / helpers / images.py
1 # Copyright 2021 Erfan Abdi
2 # SPDX-License-Identifier: GPL-3.0-or-later
3 import logging
4 import zipfile
5 import json
6 import hashlib
7 import os
8 import tools.config
9 from tools import helpers
10 from shutil import which
11
12 def sha256sum(filename):
13 h = hashlib.sha256()
14 b = bytearray(128*1024)
15 mv = memoryview(b)
16 with open(filename, 'rb', buffering=0) as f:
17 for n in iter(lambda: f.readinto(mv), 0):
18 h.update(mv[:n])
19 return h.hexdigest()
20
21
22 def get(args):
23 cfg = tools.config.load(args)
24 system_ota = cfg["waydroid"]["system_ota"]
25 system_request = helpers.http.retrieve(system_ota)
26 if system_request[0] != 200:
27 raise ValueError(
28 "Failed to get system OTA channel: {}, error: {}".format(args.system_ota, system_request[0]))
29 system_responses = json.loads(system_request[1].decode('utf8'))["response"]
30 if len(system_responses) < 1:
31 raise ValueError("No images found on system channel")
32
33 for system_response in system_responses:
34 if system_response['datetime'] > int(cfg["waydroid"]["system_datetime"]):
35 images_zip = helpers.http.download(
36 args, system_response['url'], system_response['filename'], cache=False)
37 logging.info("Validating system image")
38 if sha256sum(images_zip) != system_response['id']:
39 try:
40 os.remove(images_zip)
41 except:
42 pass
43 raise ValueError("Downloaded system image hash doesn't match, expected: {}".format(
44 system_response['id']))
45 logging.info("Extracting to " + args.images_path)
46 with zipfile.ZipFile(images_zip, 'r') as zip_ref:
47 zip_ref.extractall(args.images_path)
48 cfg["waydroid"]["system_datetime"] = str(system_response['datetime'])
49 tools.config.save(args, cfg)
50 os.remove(images_zip)
51 break
52
53 vendor_ota = cfg["waydroid"]["vendor_ota"]
54 vendor_request = helpers.http.retrieve(vendor_ota)
55 if vendor_request[0] != 200:
56 raise ValueError(
57 "Failed to get vendor OTA channel: {}, error: {}".format(vendor_ota, vendor_request[0]))
58 vendor_responses = json.loads(vendor_request[1].decode('utf8'))["response"]
59 if len(vendor_responses) < 1:
60 raise ValueError("No images found on vendor channel")
61
62 for vendor_response in vendor_responses:
63 if vendor_response['datetime'] > int(cfg["waydroid"]["vendor_datetime"]):
64 images_zip = helpers.http.download(
65 args, vendor_response['url'], vendor_response['filename'], cache=False)
66 logging.info("Validating vendor image")
67 if sha256sum(images_zip) != vendor_response['id']:
68 try:
69 os.remove(images_zip)
70 except:
71 pass
72 raise ValueError("Downloaded vendor image hash doesn't match, expected: {}".format(
73 vendor_response['id']))
74 logging.info("Extracting to " + args.images_path)
75 with zipfile.ZipFile(images_zip, 'r') as zip_ref:
76 zip_ref.extractall(args.images_path)
77 cfg["waydroid"]["vendor_datetime"] = str(vendor_response['datetime'])
78 tools.config.save(args, cfg)
79 os.remove(images_zip)
80 break
81
82 def replace(args, system_zip, system_time, vendor_zip, vendor_time):
83 cfg = tools.config.load(args)
84 args.images_path = cfg["waydroid"]["images_path"]
85 if os.path.exists(system_zip):
86 with zipfile.ZipFile(system_zip, 'r') as zip_ref:
87 zip_ref.extractall(args.images_path)
88 cfg["waydroid"]["system_datetime"] = str(system_time)
89 tools.config.save(args, cfg)
90 if os.path.exists(vendor_zip):
91 with zipfile.ZipFile(vendor_zip, 'r') as zip_ref:
92 zip_ref.extractall(args.images_path)
93 cfg["waydroid"]["vendor_datetime"] = str(vendor_time)
94 tools.config.save(args, cfg)
95
96 def make_prop(args, cfg, full_props_path):
97 if not os.path.isfile(args.work + "/waydroid_base.prop"):
98 raise RuntimeError("waydroid_base.prop Not found")
99 with open(args.work + "/waydroid_base.prop") as f:
100 props = f.read().splitlines()
101 if not props:
102 raise RuntimeError("waydroid_base.prop is broken!!?")
103
104 def add_prop(key, cfg_key):
105 value = cfg[cfg_key]
106 if value != "None":
107 value = value.replace("/mnt/", "/mnt_extra/")
108 props.append(key + "=" + value)
109
110 add_prop("waydroid.host.user", "user_name")
111 add_prop("waydroid.host.uid", "user_id")
112 add_prop("waydroid.host.gid", "group_id")
113 add_prop("waydroid.xdg_runtime_dir", "xdg_runtime_dir")
114 add_prop("waydroid.pulse_runtime_path", "pulse_runtime_path")
115 add_prop("waydroid.wayland_display", "wayland_display")
116 if which("waydroid-sensord") is None:
117 props.append("waydroid.stub_sensors_hal=1")
118 dpi = cfg["lcd_density"]
119 if dpi != "0":
120 props.append("ro.sf.lcd_density=" + dpi)
121
122 final_props = open(full_props_path, "w")
123 for prop in props:
124 final_props.write(prop + "\n")
125 final_props.close()
126 os.chmod(full_props_path, 0o644)
127
128 def mount_rootfs(args, images_dir, session):
129 helpers.mount.mount(args, images_dir + "/system.img",
130 tools.config.defaults["rootfs"], umount=True)
131 helpers.mount.mount(args, images_dir + "/vendor.img",
132 tools.config.defaults["rootfs"] + "/vendor")
133 for egl_path in ["/vendor/lib/egl", "/vendor/lib64/egl"]:
134 if os.path.isdir(egl_path):
135 helpers.mount.bind(
136 args, egl_path, tools.config.defaults["rootfs"] + egl_path)
137 if helpers.mount.ismount("/odm"):
138 helpers.mount.bind(
139 args, "/odm", tools.config.defaults["rootfs"] + "/odm_extra")
140 else:
141 if os.path.isdir("/vendor/odm"):
142 helpers.mount.bind(
143 args, "/vendor/odm", tools.config.defaults["rootfs"] + "/odm_extra")
144
145 make_prop(args, session, args.work + "/waydroid.prop")
146 helpers.mount.bind_file(args, args.work + "/waydroid.prop",
147 tools.config.defaults["rootfs"] + "/vendor/waydroid.prop")
148
149 def umount_rootfs(args):
150 helpers.mount.umount_all(args, tools.config.defaults["rootfs"])