Refactor: Split into multiple small scripts
This commit is contained in:
parent
4681bb48fe
commit
df46ba8fed
14 changed files with 723 additions and 556 deletions
106
.gitignore
vendored
Normal file
106
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
git
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
*.out
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
.idea/
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
workspace.xml
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
.idea/workspace.xml
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
58
main.py
Normal file
58
main.py
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
import argparse
|
||||||
|
from stuffs.android_id import Android_id
|
||||||
|
from stuffs.gapps import Gapps
|
||||||
|
from stuffs.houdini import Houdini
|
||||||
|
from stuffs.magisk import Magisk
|
||||||
|
from stuffs.ndk import Ndk
|
||||||
|
from stuffs.widevine import Widevine
|
||||||
|
import tools.helper as helper
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
about = """
|
||||||
|
WayDroid Helper script v0.3
|
||||||
|
Does stuff like installing Gapps, Installing NDK Translation and getting Android ID for device registration.
|
||||||
|
Use -h flag for help !
|
||||||
|
"""
|
||||||
|
helper.check_root()
|
||||||
|
parser = argparse.ArgumentParser(description=about, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
|
parser.add_argument('-g', '--install-gapps',
|
||||||
|
dest='gapps',
|
||||||
|
help='Install OpenGapps to waydroid',
|
||||||
|
action='store_true')
|
||||||
|
parser.add_argument('-n', '--install-ndk-translation',
|
||||||
|
dest='ndk',
|
||||||
|
help='Install libndk translation for arm translation',
|
||||||
|
action='store_true')
|
||||||
|
parser.add_argument('-i', '--get-android-id', dest='getid',
|
||||||
|
help='Displays your android id for manual registration',
|
||||||
|
action='store_true')
|
||||||
|
parser.add_argument('-m', '--install-magisk', dest='magisk',
|
||||||
|
help='Attempts to install Magisk ( Bootless )',
|
||||||
|
action='store_true')
|
||||||
|
parser.add_argument('-l', '--install-libhoudini', dest='houdini',
|
||||||
|
help='Install libhoudini for arm translation',
|
||||||
|
action='store_true')
|
||||||
|
parser.add_argument('-w', '--install-windevine', dest='widevine',
|
||||||
|
help='Integrate Widevine DRM (L3)',
|
||||||
|
action='store_true')
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.getid:
|
||||||
|
Android_id().get_id()
|
||||||
|
if args.gapps:
|
||||||
|
Gapps().install()
|
||||||
|
if args.ndk and not args.houdini:
|
||||||
|
arch = helper.host()[0]
|
||||||
|
if arch == "x86" or arch == "x86_64":
|
||||||
|
Ndk().install()
|
||||||
|
if args.houdini and not args.ndk:
|
||||||
|
arch = helper.host()[0]
|
||||||
|
if arch == "x86" or arch == "x86_64":
|
||||||
|
Houdini().install()
|
||||||
|
if args.magisk:
|
||||||
|
Magisk().install()
|
||||||
|
if args.widevine:
|
||||||
|
Widevine().install()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
18
stuffs/android_id.py
Normal file
18
stuffs/android_id.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from tools.helper import run
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
|
||||||
|
class Android_id:
|
||||||
|
def get_id(self):
|
||||||
|
if not os.path.isfile("/var/lib/waydroid/data/data/com.google.android.gsf/databases/gservices.db"):
|
||||||
|
Logger.error("Cannot access gservices.db, make sure gapps is installed and waydroid was started at least once after installation and make sure waydroid is running !")
|
||||||
|
sys.exit(1)
|
||||||
|
sqs = """
|
||||||
|
SELECT * FROM main WHERE name='android_id'
|
||||||
|
"""
|
||||||
|
queryout = run(["sqlite3", "/var/lib/waydroid/data/data/com.google.android.gsf/databases/gservices.db", sqs.strip()])
|
||||||
|
print(queryout.stdout.decode().replace("android_id|", "").strip())
|
||||||
|
print(" ^----- Open https://google.com/android/uncertified/?pli=1")
|
||||||
|
print(" Login with your google id then submit the form with id shown above")
|
||||||
59
stuffs/gapps.py
Normal file
59
stuffs/gapps.py
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from stuffs.general import General
|
||||||
|
from tools.helper import host, run
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
class Gapps(General):
|
||||||
|
partition = "system"
|
||||||
|
dl_links = {
|
||||||
|
"x86_64": ["https://master.dl.sourceforge.net/project/opengapps/x86_64/20220121/open_gapps-x86_64-10.0-pico-20220121.zip?viasf=1", "e8c9a7412f5712eea7948957a62a7d66"],
|
||||||
|
"x86": ["https://udomain.dl.sourceforge.net/project/opengapps/x86/20220122/open_gapps-x86-10.0-pico-20220122.zip", "9e39e45584b7ade4529e6be654af7b81"],
|
||||||
|
"arm64-v8a": ["https://liquidtelecom.dl.sourceforge.net/project/opengapps/arm64/20220122/open_gapps-arm64-10.0-pico-20220122.zip", "8dfa6e76aeb2d1d5aed40b058e8a852c"],
|
||||||
|
"armeabi-v7a": ["https://nav.dl.sourceforge.net/project/opengapps/arm/20220122/open_gapps-arm-10.0-pico-20220122.zip", "a48ccbd25eb0a3c5e30f5db5435f5536"]
|
||||||
|
}
|
||||||
|
arch = host()
|
||||||
|
dl_link = dl_links[arch[0]][0]
|
||||||
|
dl_file_name = "open_gapps.zip"
|
||||||
|
act_md5 = dl_links[arch[0]][1]
|
||||||
|
extract_to = "/tmp/ogapps/extract"
|
||||||
|
non_apks = [
|
||||||
|
"defaultetc-common.tar.lz",
|
||||||
|
"defaultframework-common.tar.lz",
|
||||||
|
"googlepixelconfig-common.tar.lz"
|
||||||
|
]
|
||||||
|
skip = [
|
||||||
|
"setupwizarddefault-x86_64.tar.lz",
|
||||||
|
"setupwizardtablet-x86_64.tar.lz"
|
||||||
|
]
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
Logger.info("Downloading OpenGapps now to {} .....".format(self.download_loc))
|
||||||
|
super().download()
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
if not os.path.exists(self.extract_to):
|
||||||
|
os.makedirs(self.extract_to)
|
||||||
|
if not os.path.exists(os.path.join(self.extract_to, "appunpack")):
|
||||||
|
os.makedirs(os.path.join(self.extract_to, "appunpack"))
|
||||||
|
|
||||||
|
for lz_file in os.listdir(os.path.join(self.extract_to, "Core")):
|
||||||
|
for d in os.listdir(os.path.join(self.extract_to, "appunpack")):
|
||||||
|
shutil.rmtree(os.path.join(self.extract_to, "appunpack", d))
|
||||||
|
if lz_file not in self.skip:
|
||||||
|
if lz_file not in self.non_apks:
|
||||||
|
print(" Processing app package : "+os.path.join(self.extract_to, "Core", lz_file))
|
||||||
|
run(["tar", "--lzip", "-xvf", os.path.join(self.extract_to, "Core", lz_file), "-C", os.path.join(self.extract_to, "appunpack")])
|
||||||
|
app_name = os.listdir(os.path.join(self.extract_to, "appunpack"))[0]
|
||||||
|
xx_dpi = os.listdir(os.path.join(self.extract_to, "appunpack", app_name))[0]
|
||||||
|
app_priv = os.listdir(os.path.join(self.extract_to, "appunpack", app_name, "nodpi"))[0]
|
||||||
|
app_src_dir = os.path.join(self.extract_to, "appunpack", app_name, xx_dpi, app_priv)
|
||||||
|
for app in os.listdir(app_src_dir):
|
||||||
|
shutil.copytree(os.path.join(app_src_dir, app), os.path.join(self.copy_dir, self.partition, "priv-app", app), dirs_exist_ok=True)
|
||||||
|
else:
|
||||||
|
print(" Processing extra package : "+os.path.join(self.extract_to, "Core", lz_file))
|
||||||
|
run(["tar", "--lzip", "-xvf", os.path.join(self.extract_to, "Core", lz_file), "-C", os.path.join(self.extract_to, "appunpack")])
|
||||||
|
app_name = os.listdir(os.path.join(self.extract_to, "appunpack"))[0]
|
||||||
|
common_content_dirs = os.listdir(os.path.join(self.extract_to, "appunpack", app_name, "common"))
|
||||||
|
for ccdir in common_content_dirs:
|
||||||
|
shutil.copytree(os.path.join(self.extract_to, "appunpack", app_name, "common", ccdir), os.path.join(self.copy_dir, self.partition, ccdir), dirs_exist_ok=True)
|
||||||
132
stuffs/general.py
Normal file
132
stuffs/general.py
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import zipfile
|
||||||
|
import hashlib
|
||||||
|
from tools import images
|
||||||
|
from tools.helper import download_file, get_download_dir, run
|
||||||
|
from tools.container import DBusContainerService
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
class General:
|
||||||
|
@property
|
||||||
|
def download_loc(self):
|
||||||
|
return os.path.join(get_download_dir(), self.dl_file_name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def copy_dir(self):
|
||||||
|
if self.use_overlayfs:
|
||||||
|
return "/var/lib/waydroid/overlay"
|
||||||
|
else:
|
||||||
|
return "/tmp/waydroid"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def use_dbus(self):
|
||||||
|
try:
|
||||||
|
DBusContainerService()
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
return
|
||||||
|
|
||||||
|
@property
|
||||||
|
def use_overlayfs(self):
|
||||||
|
return os.path.isdir("/var/lib/waydroid/overlay")
|
||||||
|
# return False
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
loc_md5 = ""
|
||||||
|
if os.path.isfile(self.download_loc):
|
||||||
|
with open(self.download_loc, "rb") as f:
|
||||||
|
bytes = f.read()
|
||||||
|
loc_md5 = hashlib.md5(bytes).hexdigest()
|
||||||
|
while not os.path.isfile(self.download_loc) or loc_md5 != self.act_md5:
|
||||||
|
if os.path.isfile(self.download_loc):
|
||||||
|
os.remove(self.download_loc)
|
||||||
|
Logger.warning(
|
||||||
|
"md5 mismatches, redownloading now ....")
|
||||||
|
loc_md5 = download_file(self.dl_link, self.download_loc)
|
||||||
|
|
||||||
|
def extract(self):
|
||||||
|
Logger.info("Extracting archive...")
|
||||||
|
with zipfile.ZipFile(self.download_loc) as z:
|
||||||
|
z.extractall(self.extract_to)
|
||||||
|
|
||||||
|
def add_props(self):
|
||||||
|
with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "r") as propfile:
|
||||||
|
prop_content = propfile.read()
|
||||||
|
for key in self.apply_props:
|
||||||
|
if key not in prop_content:
|
||||||
|
prop_content = prop_content+"\n{key}={value}".format(key=key, value=self.apply_props[key])
|
||||||
|
else:
|
||||||
|
p = re.compile(r"^{key}=.*$".format(key=key), re.M)
|
||||||
|
prop_content = re.sub(p, "{key}={value}".format(key=key, value=self.apply_props[key]), prop_content)
|
||||||
|
with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "w") as propfile:
|
||||||
|
propfile.write(prop_content)
|
||||||
|
|
||||||
|
def mount(self):
|
||||||
|
img = os.path.join(images.get_image_dir(), self.partition+".img")
|
||||||
|
mount_point = ""
|
||||||
|
if self.partition == "system":
|
||||||
|
mount_point = os.path.join(self.copy_dir)
|
||||||
|
else:
|
||||||
|
mount_point = os.path.join(self.copy_dir, self.partition)
|
||||||
|
Logger.info("Mounting {} to {}".format(img, mount_point))
|
||||||
|
images.mount(img, mount_point)
|
||||||
|
|
||||||
|
def resize(self):
|
||||||
|
img = os.path.join(images.get_image_dir(), self.partition+".img")
|
||||||
|
img_size = int(os.path.getsize(img)/(1024*1024))
|
||||||
|
new_size = "{}M".format(img_size+500)
|
||||||
|
Logger.info("Resizing {} to {}".format(img, new_size))
|
||||||
|
images.resize(img, new_size)
|
||||||
|
|
||||||
|
def umount(self):
|
||||||
|
mount_point = ""
|
||||||
|
if self.partition == "system":
|
||||||
|
mount_point = os.path.join(self.copy_dir)
|
||||||
|
else:
|
||||||
|
mount_point = os.path.join(self.copy_dir, self.partition)
|
||||||
|
Logger.info("Umounting {}".format(mount_point))
|
||||||
|
images.umount(mount_point)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
if self.use_dbus:
|
||||||
|
self.session = DBusContainerService().GetSession()
|
||||||
|
if self.session:
|
||||||
|
DBusContainerService().Stop(False)
|
||||||
|
else:
|
||||||
|
run(["waydroid", "container", "stop"])
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
if self.use_dbus:
|
||||||
|
DBusContainerService().Start(self.session)
|
||||||
|
else:
|
||||||
|
run(["systemctl", "restart", "waydroid-container.service"])
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
if DBusContainerService().GetSession():
|
||||||
|
self.stop()
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def install(self):
|
||||||
|
if self.use_overlayfs:
|
||||||
|
self.download()
|
||||||
|
self.extract()
|
||||||
|
self.copy()
|
||||||
|
if hasattr(self, "apply_props"):
|
||||||
|
self.add_props()
|
||||||
|
self.restart()
|
||||||
|
else:
|
||||||
|
self.stop()
|
||||||
|
self.download()
|
||||||
|
self.extract()
|
||||||
|
self.resize()
|
||||||
|
self.mount()
|
||||||
|
self.copy()
|
||||||
|
if hasattr(self, "apply_props"):
|
||||||
|
self.add_props()
|
||||||
|
self.umount()
|
||||||
|
self.start()
|
||||||
|
Logger.info("Installation finished")
|
||||||
49
stuffs/houdini.py
Normal file
49
stuffs/houdini.py
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
from stuffs.general import General
|
||||||
|
from tools.helper import run
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
|
||||||
|
class Houdini(General):
|
||||||
|
partition = "system"
|
||||||
|
dl_link = "https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/81f2a51ef539a35aead396ab7fce2adf89f46e88.zip"
|
||||||
|
act_md5 = "fbff756612b4144797fbc99eadcb6653"
|
||||||
|
dl_file_name = "libhoudini.zip"
|
||||||
|
extract_to = "/tmp/houdiniunpack"
|
||||||
|
init_rc_component = """
|
||||||
|
on early-init
|
||||||
|
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
|
||||||
|
|
||||||
|
on property:ro.enable.native.bridge.exec=1
|
||||||
|
exec -- /system/bin/sh -c "echo ':arm_exe:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x01\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x02\\\\x00\\\\x28::/system/bin/houdini:P' > /proc/sys/fs/binfmt_misc/register"
|
||||||
|
exec -- /system/bin/sh -c "echo ':arm_dyn:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x01\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x03\\\\x00\\\\x28::/system/bin/houdini:P' >> /proc/sys/fs/binfmt_misc/register"
|
||||||
|
exec -- /system/bin/sh -c "echo ':arm64_exe:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x02\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x02\\\\x00\\\\xb7::/system/bin/houdini64:P' >> /proc/sys/fs/binfmt_misc/register"
|
||||||
|
exec -- /system/bin/sh -c "echo ':arm64_dyn:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x02\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x03\\\\x00\\\\xb7::/system/bin/houdini64:P' >> /proc/sys/fs/binfmt_misc/register"
|
||||||
|
"""
|
||||||
|
apply_props = {
|
||||||
|
"ro.product.cpu.abilist": "x86_64,x86,arm64-v8a,armeabi-v7a,armeabi",
|
||||||
|
"ro.product.cpu.abilist32": "x86,armeabi-v7a,armeabi",
|
||||||
|
"ro.product.cpu.abilist64": "x86_64,arm64-v8a",
|
||||||
|
"ro.dalvik.vm.native.bridge": "libhoudini.so",
|
||||||
|
"ro.enable.native.bridge.exec": "1",
|
||||||
|
"ro.dalvik.vm.isa.arm": "x86",
|
||||||
|
"ro.dalvik.vm.isa.arm64": "x86_64"
|
||||||
|
}
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
Logger.info("Downloading libhoudini to {}now .....".format(self.download_loc))
|
||||||
|
super().download()
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
run(["chmod", "+x", self.extract_to, "-R"])
|
||||||
|
Logger.info("Copying libhoudini library files ...")
|
||||||
|
name = re.findall("([a-zA-Z0-9]+)\.zip", self.dl_link)[0]
|
||||||
|
shutil.copytree(os.path.join(self.extract_to, "vendor_intel_proprietary_houdini-" + name,
|
||||||
|
"prebuilts"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True)
|
||||||
|
init_path = os.path.join(self.copy_dir, self.partition, "etc", "init", "houdini.rc")
|
||||||
|
if not os.path.isfile(init_path):
|
||||||
|
os.makedirs(os.path.dirname(init_path), exist_ok=True)
|
||||||
|
with open(init_path, "w") as initfile:
|
||||||
|
initfile.write(self.init_rc_component)
|
||||||
89
stuffs/magisk.py
Normal file
89
stuffs/magisk.py
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
import gzip
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import re
|
||||||
|
from stuffs.general import General
|
||||||
|
from tools.helper import download_file, host, run
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
class Magisk(General):
|
||||||
|
partition = "system"
|
||||||
|
dl_link = "https://huskydg.github.io/magisk-files/app-release.apk"
|
||||||
|
dl_file_name = "magisk.apk"
|
||||||
|
extract_to = "/tmp/magisk_unpack"
|
||||||
|
magisk_dir = os.path.join(partition, "etc", "init", "magisk")
|
||||||
|
machine = host()
|
||||||
|
oringinal_bootanim = """
|
||||||
|
service bootanim /system/bin/bootanimation
|
||||||
|
class core animation
|
||||||
|
user graphics
|
||||||
|
group graphics audio
|
||||||
|
disabled
|
||||||
|
oneshot
|
||||||
|
ioprio rt 0
|
||||||
|
task_profiles MaxPerformance
|
||||||
|
|
||||||
|
"""
|
||||||
|
bootanim_component = """
|
||||||
|
on post-fs-data
|
||||||
|
start logd
|
||||||
|
exec u:r:su:s0 root root -- /system/etc/init/magisk/magisk{arch} --auto-selinux --setup-sbin /system/etc/init/magisk
|
||||||
|
exec u:r:su:s0 root root -- /system/etc/init/magisk/magiskpolicy --live --magisk "allow * magisk_file lnk_file *"
|
||||||
|
mkdir /sbin/.magisk 700
|
||||||
|
mkdir /sbin/.magisk/mirror 700
|
||||||
|
mkdir /sbin/.magisk/block 700
|
||||||
|
copy /system/etc/init/magisk/config /sbin/.magisk/config
|
||||||
|
rm /dev/.magisk_unblock
|
||||||
|
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --post-fs-data
|
||||||
|
wait /dev/.magisk_unblock 40
|
||||||
|
rm /dev/.magisk_unblock
|
||||||
|
|
||||||
|
on zygote-start
|
||||||
|
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --service
|
||||||
|
|
||||||
|
on property:sys.boot_completed=1
|
||||||
|
mkdir /data/adb/magisk 755
|
||||||
|
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --boot-complete
|
||||||
|
exec -- /system/bin/sh -c "if [ ! -e /data/data/io.github.huskydg.magisk ] ; then pm install /system/etc/init/magisk/magisk.apk ; fi"
|
||||||
|
|
||||||
|
on property:init.svc.zygote=restarting
|
||||||
|
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --zygote-restart
|
||||||
|
|
||||||
|
on property:init.svc.zygote=stopped
|
||||||
|
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --zygote-restart
|
||||||
|
""".format(arch=machine[1])
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
if os.path.isfile(self.download_loc):
|
||||||
|
os.remove(self.download_loc)
|
||||||
|
Logger.info("Downloading latest Magisk-Delta to {} now ...".format(self.download_loc))
|
||||||
|
download_file(self.dl_link, self.download_loc)
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
magisk_absolute_dir = os.path.join(self.copy_dir, self.magisk_dir)
|
||||||
|
if not os.path.exists(magisk_absolute_dir):
|
||||||
|
os.makedirs(magisk_absolute_dir, exist_ok=True)
|
||||||
|
|
||||||
|
if not os.path.exists(os.path.join(self.copy_dir, "sbin")):
|
||||||
|
os.makedirs(os.path.join(self.copy_dir, "sbin"), exist_ok=True)
|
||||||
|
|
||||||
|
Logger.info("Copying magisk libs now ...")
|
||||||
|
|
||||||
|
lib_dir = os.path.join(self.extract_to, "lib", self.machine[0])
|
||||||
|
for parent, dirnames, filenames in os.walk(lib_dir):
|
||||||
|
for filename in filenames:
|
||||||
|
o_path = os.path.join(lib_dir, filename)
|
||||||
|
filename = re.search('lib(.*)\.so', filename)
|
||||||
|
n_path = os.path.join(magisk_absolute_dir, filename.group(1))
|
||||||
|
shutil.copyfile(o_path, n_path)
|
||||||
|
run(["chmod", "+x", n_path])
|
||||||
|
shutil.copyfile(self.download_loc, os.path.join(magisk_absolute_dir,"magisk.apk") )
|
||||||
|
|
||||||
|
# Updating Magisk from Magisk manager will modify bootanim.rc,
|
||||||
|
# So it is necessary to backup the original bootanim.rc.
|
||||||
|
bootanim_path = os.path.join(self.copy_dir, self.partition, "etc", "init", "bootanim.rc")
|
||||||
|
gz_filename = os.path.join(bootanim_path)+".gz"
|
||||||
|
with gzip.open(gz_filename,'wb') as f_gz:
|
||||||
|
f_gz.write(self.oringinal_bootanim.encode('utf-8'))
|
||||||
|
with open(bootanim_path, "w") as initfile:
|
||||||
|
initfile.write(self.oringinal_bootanim+self.bootanim_component)
|
||||||
48
stuffs/ndk.py
Normal file
48
stuffs/ndk.py
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from stuffs.general import General
|
||||||
|
from tools.helper import run
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
class Ndk(General):
|
||||||
|
partition = "system"
|
||||||
|
dl_link = "https://www.dropbox.com/s/eaf4dj3novwiccp/libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3.zip?dl=1"
|
||||||
|
dl_file_name = "libndktranslation.zip"
|
||||||
|
extract_to = "/tmp/libndkunpack"
|
||||||
|
act_md5 = "4456fc1002dc78e544e8d9721bb24398"
|
||||||
|
apply_props = {
|
||||||
|
"ro.product.cpu.abilist": "x86_64,x86,armeabi-v7a,armeabi,arm64-v8a",
|
||||||
|
"ro.product.cpu.abilist32": "x86,armeabi-v7a,armeabi",
|
||||||
|
"ro.product.cpu.abilist64": "x86_64,arm64-v8a",
|
||||||
|
"ro.dalvik.vm.native.bridge": "libndk_translation.so",
|
||||||
|
"ro.enable.native.bridge.exec": "1",
|
||||||
|
# "ro.ndk_translation.version": "0.2.2",
|
||||||
|
"ro.dalvik.vm.isa.arm": "x86",
|
||||||
|
"ro.dalvik.vm.isa.arm64": "x86_64"
|
||||||
|
}
|
||||||
|
init_rc_component = """
|
||||||
|
# Enable native bridge for target executables
|
||||||
|
on early-init
|
||||||
|
mount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
|
||||||
|
|
||||||
|
on property:ro.enable.native.bridge.exec=1
|
||||||
|
copy /system/etc/binfmt_misc/arm_exe /proc/sys/fs/binfmt_misc/register
|
||||||
|
copy /system/etc/binfmt_misc/arm_dyn /proc/sys/fs/binfmt_misc/register
|
||||||
|
copy /system/etc/binfmt_misc/arm64_exe /proc/sys/fs/binfmt_misc/register
|
||||||
|
copy /system/etc/binfmt_misc/arm64_dyn /proc/sys/fs/binfmt_misc/register
|
||||||
|
"""
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
Logger.info("Downloading libndk to {} now .....".format(self.download_loc))
|
||||||
|
super().download()
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
run(["chmod", "+x", self.extract_to, "-R"])
|
||||||
|
Logger.info("Copying libndk library files ...")
|
||||||
|
shutil.copytree(os.path.join(self.extract_to, "libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3", "system"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True)
|
||||||
|
|
||||||
|
init_path = os.path.join(self.copy_dir, self.partition, "etc", "init", "libndk.rc")
|
||||||
|
if not os.path.isfile(init_path):
|
||||||
|
os.makedirs(os.path.dirname(init_path), exist_ok=True)
|
||||||
|
with open(init_path, "w") as initfile:
|
||||||
|
initfile.write(self.init_rc_component)
|
||||||
23
stuffs/widevine.py
Normal file
23
stuffs/widevine.py
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from stuffs.general import General
|
||||||
|
from tools.helper import run
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
|
||||||
|
class Widevine(General):
|
||||||
|
partition = "vendor"
|
||||||
|
dl_link = "https://codeload.github.com/supremegamers/vendor_google_proprietary_widevine-prebuilt/zip/94c9ee172e3d78fecc81863f50a59e3646f7a2bd"
|
||||||
|
dl_file_name = "widevine.zip"
|
||||||
|
extract_to = "/tmp/widevineunpack"
|
||||||
|
act_md5 = "a31f325453c5d239c21ecab8cfdbd878"
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
Logger.info("Downloading widevine to {} now .....".format(self.download_loc))
|
||||||
|
super().download()
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
run(["chmod", "+x", self.extract_to, "-R"])
|
||||||
|
Logger.info("Copying widevine library files ...")
|
||||||
|
shutil.copytree(os.path.join(self.extract_to, "vendor_google_proprietary_widevine-prebuilt-94c9ee172e3d78fecc81863f50a59e3646f7a2bd",
|
||||||
|
"prebuilts"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True)
|
||||||
7
tools/container.py
Normal file
7
tools/container.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import dbus
|
||||||
|
|
||||||
|
def DBusContainerService(object_path="/ContainerManager", intf="id.waydro.ContainerManager"):
|
||||||
|
return dbus.Interface(dbus.SystemBus().get_object("id.waydro.Container", object_path), intf)
|
||||||
|
|
||||||
|
def DBusSessionService(object_path="/SessionManager", intf="id.waydro.SessionManager"):
|
||||||
|
return dbus.Interface(dbus.SessionBus().get_object("id.waydro.Session", object_path), intf)
|
||||||
74
tools/helper.py
Normal file
74
tools/helper.py
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import requests
|
||||||
|
from tools.logger import Logger
|
||||||
|
from tqdm import tqdm
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
def get_download_dir():
|
||||||
|
download_loc = ""
|
||||||
|
if os.environ.get("XDG_CACHE_HOME", None) is None:
|
||||||
|
download_loc = os.path.join('/', "home", os.environ.get("SUDO_USER", os.environ["USER"]), ".cache", "waydroid-script", "downloads")
|
||||||
|
else:
|
||||||
|
download_loc = os.path.join(os.environ["XDG_CACHE_HOME"], "waydroid-script", "downloads")
|
||||||
|
if not os.path.exists(download_loc):
|
||||||
|
os.makedirs(download_loc)
|
||||||
|
return download_loc
|
||||||
|
|
||||||
|
def run(args):
|
||||||
|
result = subprocess.run(args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
# print(result.stdout.decode())
|
||||||
|
if result.stderr:
|
||||||
|
Logger.error(result.stderr.decode("utf-8"))
|
||||||
|
raise subprocess.CalledProcessError(
|
||||||
|
returncode = result.returncode,
|
||||||
|
cmd = result.args,
|
||||||
|
stderr = result.stderr
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def download_file(url, f_name):
|
||||||
|
md5 = ""
|
||||||
|
response = requests.get(url, stream=True)
|
||||||
|
total_size_in_bytes = int(response.headers.get('content-length', 0))
|
||||||
|
block_size = 1024 # 1 Kibibyte
|
||||||
|
progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True)
|
||||||
|
with open(f_name, 'wb') as file:
|
||||||
|
for data in response.iter_content(block_size):
|
||||||
|
progress_bar.update(len(data))
|
||||||
|
file.write(data)
|
||||||
|
progress_bar.close()
|
||||||
|
with open(f_name, "rb") as f:
|
||||||
|
bytes = f.read()
|
||||||
|
md5 = hashlib.md5(bytes).hexdigest()
|
||||||
|
if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes:
|
||||||
|
raise ValueError("Something went wrong while downloading")
|
||||||
|
return md5
|
||||||
|
|
||||||
|
def host():
|
||||||
|
machine = platform.machine()
|
||||||
|
|
||||||
|
mapping = {
|
||||||
|
"i686": ("x86", 32),
|
||||||
|
"x86_64": ("x86_64", 64),
|
||||||
|
"aarch64": ("arm64-v8a", 64),
|
||||||
|
"armv7l": ("armeabi-v7a", 32),
|
||||||
|
"armv8l": ("armeabi-v7a", 32)
|
||||||
|
}
|
||||||
|
if machine in mapping:
|
||||||
|
if mapping[machine] == "x86_64":
|
||||||
|
with open("/proc/cpuinfo") as f:
|
||||||
|
if "sse4_2" not in f.read():
|
||||||
|
Logger.warning("x86_64 CPU does not support SSE4.2, falling back to x86...")
|
||||||
|
return ("x86", 32)
|
||||||
|
return mapping[machine]
|
||||||
|
raise ValueError("platform.machine '" + machine + "'"
|
||||||
|
" architecture is not supported")
|
||||||
|
|
||||||
|
|
||||||
|
def check_root():
|
||||||
|
if os.geteuid() != 0:
|
||||||
|
Logger.error("This script must be run as root. Aborting.")
|
||||||
|
sys.exit(1)
|
||||||
47
tools/images.py
Normal file
47
tools/images.py
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import configparser
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from tools.helper import run
|
||||||
|
from tools.logger import Logger
|
||||||
|
|
||||||
|
def mount(image, mount_point):
|
||||||
|
umount(mount_point, False)
|
||||||
|
if not os.path.exists(mount_point):
|
||||||
|
os.makedirs(mount_point)
|
||||||
|
run(["mount", "-o", "rw", image, mount_point])
|
||||||
|
|
||||||
|
def umount(mount_point, exists=True):
|
||||||
|
if not os.path.exists(mount_point):
|
||||||
|
if not exists:
|
||||||
|
return
|
||||||
|
Logger.error("{} does not exist!".format(mount_point))
|
||||||
|
raise FileNotFoundError()
|
||||||
|
if not run(["mountpoint", mount_point]).returncode:
|
||||||
|
run(["umount", mount_point])
|
||||||
|
else:
|
||||||
|
Logger.warning("{} is not a mount point".format(
|
||||||
|
mount_point))
|
||||||
|
|
||||||
|
def resize(img_file, size):
|
||||||
|
try:
|
||||||
|
run(["e2fsck", "-y", "-f", img_file])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
run(["resize2fs", img_file, size])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_image_dir():
|
||||||
|
# Read waydroid config to get image location
|
||||||
|
cfg = configparser.ConfigParser()
|
||||||
|
cfg_file = os.environ.get("WAYDROID_CONFIG", "/var/lib/waydroid/waydroid.cfg")
|
||||||
|
if not os.path.isfile(cfg_file):
|
||||||
|
Logger.error("Cannot locate waydroid config file, reinit wayland and try again!")
|
||||||
|
sys.exit(1)
|
||||||
|
cfg.read(cfg_file)
|
||||||
|
if "waydroid" not in cfg:
|
||||||
|
Logger.error("ERROR: Required entry in config was not found, Cannot continue!") #magisk
|
||||||
|
sys.exit(1)
|
||||||
|
return cfg["waydroid"]["images_path"]
|
||||||
13
tools/logger.py
Normal file
13
tools/logger.py
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
class Logger:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def error(str):
|
||||||
|
print("\033[31m"+"ERROR: "+str+"\033[0m")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def info(str):
|
||||||
|
print("\033[32m"+"INFO: "+"\033[0m"+str)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def warning(str):
|
||||||
|
print("\033[33m"+"WARN: "+str+"\033[0m")
|
||||||
|
|
@ -1,556 +0,0 @@
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import hashlib
|
|
||||||
import shutil
|
|
||||||
import zipfile
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
import platform
|
|
||||||
from tqdm import tqdm
|
|
||||||
import requests
|
|
||||||
import re
|
|
||||||
import gzip
|
|
||||||
import dbus
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
download_loc = ""
|
|
||||||
if os.environ.get("XDG_CACHE_HOME", None) is None:
|
|
||||||
download_loc = os.path.join('/', "home", os.environ.get("SUDO_USER", os.environ["USER"]), ".cache", "waydroid_script", "downloads")
|
|
||||||
else:
|
|
||||||
download_loc = os.path.join(os.environ["XDG_CACHE_HOME"], "waydroid_script", "downloads")
|
|
||||||
|
|
||||||
print(download_loc)
|
|
||||||
|
|
||||||
if not os.path.exists(download_loc):
|
|
||||||
os.makedirs(download_loc)
|
|
||||||
|
|
||||||
def host():
|
|
||||||
machine = platform.machine()
|
|
||||||
|
|
||||||
mapping = {
|
|
||||||
"i686": ("x86", 32),
|
|
||||||
"x86_64": ("x86_64", 64),
|
|
||||||
"aarch64": ("arm64-v8a", 64),
|
|
||||||
"armv7l": ("armeabi-v7a", 32),
|
|
||||||
"armv8l": ("armeabi-v7a", 32)
|
|
||||||
}
|
|
||||||
if machine in mapping:
|
|
||||||
if mapping[machine] == "x86_64":
|
|
||||||
with open("/proc/cpuinfo") as f:
|
|
||||||
if "sse4_2" not in f.read():
|
|
||||||
print("x86_64 CPU does not support SSE4.2, falling back to x86...")
|
|
||||||
return ("x86", 32)
|
|
||||||
return mapping[machine]
|
|
||||||
raise ValueError("platform.machine '" + machine + "'"
|
|
||||||
" architecture is not supported")
|
|
||||||
|
|
||||||
def download_file(url, f_name):
|
|
||||||
md5 = ""
|
|
||||||
response = requests.get(url, stream=True)
|
|
||||||
total_size_in_bytes = int(response.headers.get('content-length', 0))
|
|
||||||
block_size = 1024 # 1 Kibibyte
|
|
||||||
progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True)
|
|
||||||
with open(f_name, 'wb') as file:
|
|
||||||
for data in response.iter_content(block_size):
|
|
||||||
progress_bar.update(len(data))
|
|
||||||
file.write(data)
|
|
||||||
progress_bar.close()
|
|
||||||
with open(f_name, "rb") as f:
|
|
||||||
bytes = f.read()
|
|
||||||
md5 = hashlib.md5(bytes).hexdigest()
|
|
||||||
if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes:
|
|
||||||
print("==> Something went wrong while downloading")
|
|
||||||
sys.exit(1)
|
|
||||||
return md5
|
|
||||||
|
|
||||||
def check_root():
|
|
||||||
if os.geteuid() != 0:
|
|
||||||
print("This script must be run as root. Aborting.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def DBusContainerService(object_path="/ContainerManager", intf="id.waydro.ContainerManager"):
|
|
||||||
return dbus.Interface(dbus.SystemBus().get_object("id.waydro.Container", object_path), intf)
|
|
||||||
|
|
||||||
def DBusSessionService(object_path="/SessionManager", intf="id.waydro.SessionManager"):
|
|
||||||
return dbus.Interface(dbus.SessionBus().get_object("id.waydro.Session", object_path), intf)
|
|
||||||
|
|
||||||
def restart():
|
|
||||||
waydroid_session = DBusContainerService().GetSession()
|
|
||||||
if DBusContainerService().GetSession():
|
|
||||||
DBusContainerService().Stop()
|
|
||||||
DBusContainerService().Start(waydroid_session)
|
|
||||||
|
|
||||||
def run(args):
|
|
||||||
result = subprocess.run(args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
if result.stderr:
|
|
||||||
print(result.stderr.decode("utf-8"))
|
|
||||||
raise subprocess.CalledProcessError(
|
|
||||||
returncode = result.returncode,
|
|
||||||
cmd = result.args,
|
|
||||||
stderr = result.stderr
|
|
||||||
)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def install_gapps():
|
|
||||||
|
|
||||||
dl_links = {
|
|
||||||
"x86_64": ["https://master.dl.sourceforge.net/project/opengapps/x86_64/20220121/open_gapps-x86_64-10.0-pico-20220121.zip?viasf=1", "e8c9a7412f5712eea7948957a62a7d66"],
|
|
||||||
"x86": ["https://udomain.dl.sourceforge.net/project/opengapps/x86/20220122/open_gapps-x86-10.0-pico-20220122.zip", "9e39e45584b7ade4529e6be654af7b81"],
|
|
||||||
"aarch64": ["https://liquidtelecom.dl.sourceforge.net/project/opengapps/arm64/20220122/open_gapps-arm64-10.0-pico-20220122.zip", "8dfa6e76aeb2d1d5aed40b058e8a852c"],
|
|
||||||
"arm": ["https://nav.dl.sourceforge.net/project/opengapps/arm/20220122/open_gapps-arm-10.0-pico-20220122.zip", "a48ccbd25eb0a3c5e30f5db5435f5536"]
|
|
||||||
}
|
|
||||||
if platform.machine() not in dl_links.keys():
|
|
||||||
print("==> Unsupported architecture '{}' .. ".format(platform.machine()))
|
|
||||||
sys.exit(1)
|
|
||||||
google_apps_dl_link = dl_links[platform.machine()][0]
|
|
||||||
dl_file_name = os.path.join(download_loc, "open_gapps.zip")
|
|
||||||
act_md5 = dl_links[platform.machine()][1]
|
|
||||||
loc_md5 = ""
|
|
||||||
sys_image_mount = "/var/lib/waydroid/overlay"
|
|
||||||
extract_to = "/tmp/ogapps/extract"
|
|
||||||
non_apks = [
|
|
||||||
"defaultetc-common.tar.lz",
|
|
||||||
"defaultframework-common.tar.lz",
|
|
||||||
"googlepixelconfig-common.tar.lz"
|
|
||||||
]
|
|
||||||
skip = [
|
|
||||||
"setupwizarddefault-x86_64.tar.lz",
|
|
||||||
"setupwizardtablet-x86_64.tar.lz"
|
|
||||||
]
|
|
||||||
|
|
||||||
if not os.path.exists(extract_to):
|
|
||||||
os.makedirs(extract_to)
|
|
||||||
if not os.path.exists(os.path.join(extract_to, "appunpack")):
|
|
||||||
os.makedirs(os.path.join(extract_to, "appunpack"))
|
|
||||||
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
with open(dl_file_name,"rb") as f:
|
|
||||||
bytes = f.read()
|
|
||||||
loc_md5 = hashlib.md5(bytes).hexdigest()
|
|
||||||
print("==> Excepted hash: {} | File hash: {}".format(act_md5, loc_md5))
|
|
||||||
|
|
||||||
# Download the file if hash mismatches or if file does not exist
|
|
||||||
while not os.path.isfile(dl_file_name) or loc_md5 != act_md5:
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
os.remove(dl_file_name)
|
|
||||||
print("==> OpenGapps zip not downloaded or hash mismatches, downloading now .....")
|
|
||||||
loc_md5 = download_file(google_apps_dl_link, dl_file_name)
|
|
||||||
|
|
||||||
# Extract opengapps
|
|
||||||
print("==> Extracting opengapps...")
|
|
||||||
with zipfile.ZipFile(dl_file_name) as z:
|
|
||||||
z.extractall(extract_to)
|
|
||||||
|
|
||||||
# Now copy the files
|
|
||||||
for lz_file in os.listdir(os.path.join(extract_to, "Core")):
|
|
||||||
for d in os.listdir(os.path.join(extract_to, "appunpack")):
|
|
||||||
shutil.rmtree(os.path.join(extract_to, "appunpack", d))
|
|
||||||
if lz_file not in skip:
|
|
||||||
if lz_file not in non_apks:
|
|
||||||
print("==> Processing app package : "+os.path.join(extract_to, "Core", lz_file))
|
|
||||||
run(["tar", "--lzip", "-xvf", os.path.join(extract_to, "Core", lz_file), "-C", os.path.join(extract_to, "appunpack")])
|
|
||||||
app_name = os.listdir(os.path.join(extract_to, "appunpack"))[0]
|
|
||||||
xx_dpi = os.listdir(os.path.join(extract_to, "appunpack", app_name))[0]
|
|
||||||
app_priv = os.listdir(os.path.join(extract_to, "appunpack", app_name, "nodpi"))[0]
|
|
||||||
app_src_dir = os.path.join(extract_to, "appunpack", app_name, xx_dpi, app_priv)
|
|
||||||
for app in os.listdir(app_src_dir):
|
|
||||||
shutil.copytree(os.path.join(app_src_dir, app), os.path.join(sys_image_mount, "system", "priv-app", app), dirs_exist_ok=True)
|
|
||||||
else:
|
|
||||||
print("==> Processing extra package : "+os.path.join(extract_to, "Core", lz_file))
|
|
||||||
run(["tar", "--lzip", "-xvf", os.path.join(extract_to, "Core", lz_file), "-C", os.path.join(extract_to, "appunpack")])
|
|
||||||
app_name = os.listdir(os.path.join(extract_to, "appunpack"))[0]
|
|
||||||
common_content_dirs = os.listdir(os.path.join(extract_to, "appunpack", app_name, "common"))
|
|
||||||
for ccdir in common_content_dirs:
|
|
||||||
shutil.copytree(os.path.join(extract_to, "appunpack", app_name, "common", ccdir), os.path.join(sys_image_mount, "system", ccdir), dirs_exist_ok=True)
|
|
||||||
print("==> OpenGapps installation complete try re init /restarting waydroid")
|
|
||||||
print("==> Please note, google apps wont be usable without device registration !, Use --get-android-id for registration instructions")
|
|
||||||
restart()
|
|
||||||
|
|
||||||
|
|
||||||
def get_android_id():
|
|
||||||
try:
|
|
||||||
if not os.path.isfile("/var/lib/waydroid/data/data/com.google.android.gsf/databases/gservices.db"):
|
|
||||||
print("Cannot access gservices.db, make sure gapps is installed and waydroid was started at least once after installation and make sure waydroid is running !")
|
|
||||||
sys.exit(1)
|
|
||||||
sqs = """
|
|
||||||
SELECT * FROM main WHERE name='android_id'
|
|
||||||
"""
|
|
||||||
queryout = run(["sqlite3", "/var/lib/waydroid/data/data/com.google.android.gsf/databases/gservices.db", sqs.strip()])
|
|
||||||
print(queryout.stdout.decode().replace("android_id|", "").strip())
|
|
||||||
print(" ^----- Open https://google.com/android/uncertified/?pli=1")
|
|
||||||
print(" Login with your google id then submit the form with id shown above")
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print("==> Error getting id... '{}' ".format(str(e.output.decode())))
|
|
||||||
|
|
||||||
def install_ndk():
|
|
||||||
# sys_image_mount = "/tmp/waydroidimage"
|
|
||||||
sys_image_mount = "/var/lib/waydroid/overlay"
|
|
||||||
prop_file = "/var/lib/waydroid/waydroid_base.prop"
|
|
||||||
ndk_zip_url = "https://www.dropbox.com/s/eaf4dj3novwiccp/libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3.zip?dl=1"
|
|
||||||
dl_file_name = os.path.join(download_loc, "libndktranslation.zip")
|
|
||||||
extract_to = "/tmp/libndkunpack" #All catalog files will be marked as executable!
|
|
||||||
act_md5 = "4456fc1002dc78e544e8d9721bb24398"
|
|
||||||
loc_md5 = ""
|
|
||||||
apply_props = {
|
|
||||||
"ro.product.cpu.abilist": "x86_64,x86,armeabi-v7a,armeabi,arm64-v8a",
|
|
||||||
"ro.product.cpu.abilist32": "x86,armeabi-v7a,armeabi",
|
|
||||||
"ro.product.cpu.abilist64": "x86_64,arm64-v8a",
|
|
||||||
"ro.dalvik.vm.native.bridge": "libndk_translation.so",
|
|
||||||
"ro.enable.native.bridge.exec": "1",
|
|
||||||
# "ro.ndk_translation.version": "0.2.2",
|
|
||||||
"ro.dalvik.vm.isa.arm": "x86",
|
|
||||||
"ro.dalvik.vm.isa.arm64": "x86_64"
|
|
||||||
}
|
|
||||||
init_rc_component = """
|
|
||||||
on early-init
|
|
||||||
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
|
|
||||||
|
|
||||||
on property:ro.enable.native.bridge.exec=1
|
|
||||||
exec -- /system/bin/sh -c "cat /system/etc/binfmt_misc/arm_exe > /proc/sys/fs/binfmt_misc/register"
|
|
||||||
exec -- /system/bin/sh -c "cat /system/etc/binfmt_misc/arm_dyn >> /proc/sys/fs/binfmt_misc/register"
|
|
||||||
exec -- /system/bin/sh -c "cat /system/etc/binfmt_misc/arm64_exe >> /proc/sys/fs/binfmt_misc/register"
|
|
||||||
exec -- /system/bin/sh -c "cat /system/etc/binfmt_misc/arm64_dyn >> /proc/sys/fs/binfmt_misc/register"
|
|
||||||
"""
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
with open(dl_file_name,"rb") as f:
|
|
||||||
bytes = f.read()
|
|
||||||
loc_md5 = hashlib.md5(bytes).hexdigest()
|
|
||||||
|
|
||||||
# Download the file if hash mismatches or if file does not exist
|
|
||||||
while not os.path.isfile(dl_file_name) or loc_md5 != act_md5:
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
os.remove(dl_file_name)
|
|
||||||
print("==> NDK Translation zip not downloaded or hash mismatches, downloading now .....")
|
|
||||||
loc_md5 = download_file(ndk_zip_url, dl_file_name)
|
|
||||||
|
|
||||||
# Extract ndk files
|
|
||||||
print("==> Extracting archive...")
|
|
||||||
with zipfile.ZipFile(dl_file_name) as z:
|
|
||||||
z.extractall(extract_to)
|
|
||||||
|
|
||||||
#Mark ndk files as executable
|
|
||||||
print("==> Chmodding...")
|
|
||||||
run(["chmod", "+x", extract_to, "-R"])
|
|
||||||
|
|
||||||
# Copy library file
|
|
||||||
print("==> Copying library files ...")
|
|
||||||
shutil.copytree(os.path.join(extract_to, "libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3", "system"), os.path.join(sys_image_mount, "system"), dirs_exist_ok=True)
|
|
||||||
|
|
||||||
# Add entries to build.prop
|
|
||||||
print("==> Adding arch in", prop_file)
|
|
||||||
with open(os.path.join(prop_file), "r") as propfile:
|
|
||||||
prop_content = propfile.read()
|
|
||||||
for key in apply_props:
|
|
||||||
if key not in prop_content:
|
|
||||||
prop_content = prop_content+"\n{key}={value}".format(key=key, value=apply_props[key])
|
|
||||||
else:
|
|
||||||
p = re.compile(r"^{key}=.*$".format(key=key), re.M)
|
|
||||||
prop_content = re.sub(p, "{key}={value}".format(key=key, value=apply_props[key]), prop_content)
|
|
||||||
with open(os.path.join(prop_file), "w") as propfile:
|
|
||||||
propfile.write(prop_content)
|
|
||||||
|
|
||||||
# Add entry to init.rc
|
|
||||||
print("==> Adding entry to init.rc")
|
|
||||||
# Check if init.rc is located in Android 11's path
|
|
||||||
init_path = os.path.join(sys_image_mount, "system", "etc", "init", "houdini.rc")
|
|
||||||
if not os.path.isfile(init_path):
|
|
||||||
os.makedirs(os.path.dirname(init_path), exist_ok=True)
|
|
||||||
f = open(init_path, "x")
|
|
||||||
with open(init_path, "r") as initfile:
|
|
||||||
initcontent = initfile.read()
|
|
||||||
if init_rc_component not in initcontent:
|
|
||||||
initcontent=initcontent+init_rc_component
|
|
||||||
with open(init_path, "w") as initfile:
|
|
||||||
initfile.write(initcontent)
|
|
||||||
|
|
||||||
print("==> libndk translation installed ! Restarting waydroid service to apply changes !")
|
|
||||||
restart()
|
|
||||||
|
|
||||||
|
|
||||||
def install_houdini():
|
|
||||||
sys_image_mount = "/var/lib/waydroid/overlay"
|
|
||||||
prop_file = "/var/lib/waydroid/waydroid_base.prop"
|
|
||||||
houdini_zip_url = "https://www.dropbox.com/s/v7g0fluc7e8tod8/libhoudini.zip?dl=1"
|
|
||||||
dl_file_name = os.path.join(download_loc, "libhoudini.zip")
|
|
||||||
extract_to = "/tmp/houdiniunpack" #All catalog files will be marked as executable!
|
|
||||||
act_md5 = "838097117cec7762e958d7cbc209415e"
|
|
||||||
loc_md5 = ""
|
|
||||||
|
|
||||||
apply_props = {
|
|
||||||
"ro.product.cpu.abilist": "x86_64,x86,arm64-v8a,armeabi-v7a,armeabi",
|
|
||||||
"ro.product.cpu.abilist32": "x86,armeabi-v7a,armeabi",
|
|
||||||
"ro.product.cpu.abilist64": "x86_64,arm64-v8a",
|
|
||||||
"ro.dalvik.vm.native.bridge": "libhoudini.so",
|
|
||||||
"ro.enable.native.bridge.exec": "1",
|
|
||||||
"ro.dalvik.vm.isa.arm": "x86",
|
|
||||||
"ro.dalvik.vm.isa.arm64": "x86_64"
|
|
||||||
}
|
|
||||||
init_rc_component = """
|
|
||||||
on early-init
|
|
||||||
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
|
|
||||||
|
|
||||||
on property:ro.enable.native.bridge.exec=1
|
|
||||||
exec -- /system/bin/sh -c "echo ':arm_exe:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x01\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x02\\\\x00\\\\x28::/system/bin/houdini:P' > /proc/sys/fs/binfmt_misc/register"
|
|
||||||
exec -- /system/bin/sh -c "echo ':arm_dyn:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x01\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x03\\\\x00\\\\x28::/system/bin/houdini:P' >> /proc/sys/fs/binfmt_misc/register"
|
|
||||||
exec -- /system/bin/sh -c "echo ':arm64_exe:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x02\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x02\\\\x00\\\\xb7::/system/bin/houdini64:P' >> /proc/sys/fs/binfmt_misc/register"
|
|
||||||
exec -- /system/bin/sh -c "echo ':arm64_dyn:M::\\\\x7f\\\\x45\\\\x4c\\\\x46\\\\x02\\\\x01\\\\x01\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x03\\\\x00\\\\xb7::/system/bin/houdini64:P' >> /proc/sys/fs/binfmt_misc/register"
|
|
||||||
"""
|
|
||||||
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
with open(dl_file_name,"rb") as f:
|
|
||||||
bytes = f.read()
|
|
||||||
loc_md5 = hashlib.md5(bytes).hexdigest()
|
|
||||||
|
|
||||||
# Download the file if hash mismatches or if file does not exist
|
|
||||||
while not os.path.isfile(dl_file_name) or loc_md5 != act_md5:
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
os.remove(dl_file_name)
|
|
||||||
print("==> libhoudini zip not downloaded or hash mismatches, downloading now .....")
|
|
||||||
loc_md5 = download_file(houdini_zip_url, dl_file_name)
|
|
||||||
|
|
||||||
# Extract ndk files
|
|
||||||
print("==> Extracting archive...")
|
|
||||||
with zipfile.ZipFile(dl_file_name) as z:
|
|
||||||
z.extractall(extract_to)
|
|
||||||
|
|
||||||
# Mark libhoudini files as executable
|
|
||||||
print("==> Chmodding...")
|
|
||||||
run(["chmod", "+x", extract_to, "-R"])
|
|
||||||
|
|
||||||
# Copy library file
|
|
||||||
print("==> Copying library files ...")
|
|
||||||
shutil.copytree(os.path.join(extract_to, "system"), os.path.join(sys_image_mount, "system"), dirs_exist_ok=True)
|
|
||||||
|
|
||||||
# Add entries to build.prop
|
|
||||||
print("==> Adding arch in", prop_file)
|
|
||||||
with open(os.path.join(prop_file), "r") as propfile:
|
|
||||||
prop_content = propfile.read()
|
|
||||||
for key in apply_props:
|
|
||||||
if key not in prop_content:
|
|
||||||
prop_content = prop_content+"\n{key}={value}".format(key=key, value=apply_props[key])
|
|
||||||
else:
|
|
||||||
p = re.compile(r"^{key}=.*$".format(key=key), re.M)
|
|
||||||
prop_content = re.sub(p, "{key}={value}".format(key=key, value=apply_props[key]), prop_content)
|
|
||||||
with open(os.path.join(prop_file), "w") as propfile:
|
|
||||||
propfile.write(prop_content)
|
|
||||||
|
|
||||||
# Add entry to init.rc
|
|
||||||
print("==> Adding entry to init.rc")
|
|
||||||
# Check if init.rc is located in Android 11's path
|
|
||||||
init_path = os.path.join(sys_image_mount, "system", "etc", "init", "houdini.rc")
|
|
||||||
if not os.path.isfile(init_path):
|
|
||||||
os.makedirs(os.path.dirname(init_path), exist_ok=True)
|
|
||||||
f = open(init_path, "x")
|
|
||||||
with open(init_path, "r") as initfile:
|
|
||||||
initcontent = initfile.read()
|
|
||||||
if init_rc_component not in initcontent:
|
|
||||||
initcontent=initcontent+init_rc_component
|
|
||||||
with open(init_path, "w") as initfile:
|
|
||||||
initfile.write(initcontent)
|
|
||||||
|
|
||||||
print("==> libhoudini translation installed ! Restarting waydroid container to apply changes !")
|
|
||||||
restart()
|
|
||||||
|
|
||||||
def install_magisk():
|
|
||||||
dl_link = "https://huskydg.github.io/magisk-files/app-release.apk"
|
|
||||||
dl_file_name = os.path.join(download_loc, "magisk.apk")
|
|
||||||
extract_to = "/tmp/magisk_unpack"
|
|
||||||
# sys_overlay_dir = "/var/lib/waydroid/overlay_rw/system"
|
|
||||||
sys_overlay_dir = "/var/lib/waydroid/overlay"
|
|
||||||
merge_dir = "/var/lib/waydroid/rootfs"
|
|
||||||
magisk_dir = os.path.join(sys_overlay_dir, "system", "etc", "init", "magisk")
|
|
||||||
sys_overlay_rw = "/var/lib/waydroid/overlay_rw"
|
|
||||||
|
|
||||||
machine = host()
|
|
||||||
init_rc_component = """
|
|
||||||
on post-fs-data
|
|
||||||
start logd
|
|
||||||
exec u:r:su:s0 root root -- /system/etc/init/magisk/magisk{arch} --auto-selinux --setup-sbin /system/etc/init/magisk
|
|
||||||
exec u:r:su:s0 root root -- /system/etc/init/magisk/magiskpolicy --live --magisk "allow * magisk_file lnk_file *"
|
|
||||||
mkdir /sbin/.magisk 700
|
|
||||||
mkdir /sbin/.magisk/mirror 700
|
|
||||||
mkdir /sbin/.magisk/block 700
|
|
||||||
copy /system/etc/init/magisk/config /sbin/.magisk/config
|
|
||||||
rm /dev/.magisk_unblock
|
|
||||||
start 7zKkuZ1ZhD
|
|
||||||
wait /dev/.magisk_unblock 40
|
|
||||||
rm /dev/.magisk_unblock
|
|
||||||
|
|
||||||
service 7zKkuZ1ZhD /sbin/magisk --auto-selinux --post-fs-data
|
|
||||||
user root
|
|
||||||
seclabel u:r:su:s0
|
|
||||||
oneshot
|
|
||||||
|
|
||||||
service wHgGlkRCtMoIQw /sbin/magisk --auto-selinux --service
|
|
||||||
class late_start
|
|
||||||
user root
|
|
||||||
seclabel u:r:su:s0
|
|
||||||
oneshot
|
|
||||||
|
|
||||||
on property:sys.boot_completed=1
|
|
||||||
mkdir /data/adb/magisk 755
|
|
||||||
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --boot-complete
|
|
||||||
exec -- /system/bin/sh -c "if [ ! -e /data/data/io.github.huskydg.magisk ] ; then pm install /system/etc/init/magisk/magisk.apk ; fi"
|
|
||||||
|
|
||||||
on property:init.svc.zygote=restarting
|
|
||||||
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --zygote-restart
|
|
||||||
|
|
||||||
on property:init.svc.zygote=stopped
|
|
||||||
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --zygote-restart
|
|
||||||
""".format(arch=machine[1])
|
|
||||||
|
|
||||||
if not DBusContainerService().GetSession():
|
|
||||||
print("Please make sure waydroid container is running!")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Clear overlay_rw
|
|
||||||
print("==> Deleting residual files...")
|
|
||||||
old_bootanim_rc = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "bootanim.rc")
|
|
||||||
old_bootanim_rc_gz = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "bootanim.rc.gz")
|
|
||||||
old_magisk = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "magisk")
|
|
||||||
|
|
||||||
if os.path.exists(old_bootanim_rc):
|
|
||||||
os.remove(old_bootanim_rc)
|
|
||||||
if os.path.exists(old_bootanim_rc_gz):
|
|
||||||
os.remove(old_bootanim_rc_gz)
|
|
||||||
if os.path.exists(old_magisk):
|
|
||||||
if os.path.isdir(old_magisk):
|
|
||||||
shutil.rmtree(old_magisk)
|
|
||||||
else:
|
|
||||||
os.remove(old_magisk)
|
|
||||||
|
|
||||||
# Download magisk
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
os.remove(dl_file_name)
|
|
||||||
print("==> Downloading latest Magisk-Delta now .....")
|
|
||||||
download_file(dl_link, dl_file_name)
|
|
||||||
|
|
||||||
# Extract magisk files
|
|
||||||
print("==> Extracting archive...")
|
|
||||||
with zipfile.ZipFile(dl_file_name) as z:
|
|
||||||
z.extractall(extract_to)
|
|
||||||
|
|
||||||
if not os.path.exists(magisk_dir):
|
|
||||||
os.makedirs(magisk_dir, exist_ok=True)
|
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(sys_overlay_dir, "sbin")):
|
|
||||||
os.makedirs(os.path.join(sys_overlay_dir, "sbin"), exist_ok=True)
|
|
||||||
|
|
||||||
# Now setup and install magisk binary and app
|
|
||||||
print("==> Installing magisk now ...")
|
|
||||||
|
|
||||||
lib_dir = os.path.join(extract_to, "lib", machine[0])
|
|
||||||
for parent, dirnames, filenames in os.walk(lib_dir):
|
|
||||||
for filename in filenames:
|
|
||||||
o_path = os.path.join(lib_dir, filename)
|
|
||||||
filename = re.search('lib(.*)\.so', filename)
|
|
||||||
n_path = os.path.join(magisk_dir, filename.group(1))
|
|
||||||
shutil.copyfile(o_path, n_path)
|
|
||||||
run(["chmod", "+x", n_path])
|
|
||||||
shutil.copyfile(dl_file_name, os.path.join(magisk_dir,"magisk.apk") )
|
|
||||||
|
|
||||||
# Updating Magisk from Magisk manager will modify bootanim.rc,
|
|
||||||
# So it is necessary to backup the original bootanim.rc.
|
|
||||||
print("==> Adding entry to bootanim.rc")
|
|
||||||
|
|
||||||
bootanim = os.path.join(sys_overlay_dir, "system", "etc", "init", "bootanim.rc")
|
|
||||||
original_bootanim = os.path.join(merge_dir, "system", "etc", "init", "bootanim.rc")
|
|
||||||
|
|
||||||
if not os.path.isfile(bootanim):
|
|
||||||
os.makedirs(os.path.dirname(bootanim), exist_ok=True)
|
|
||||||
gz_filename = bootanim+".gz"
|
|
||||||
with open(original_bootanim,'rb') as f_ungz:
|
|
||||||
with gzip.open(gz_filename,'wb') as f_gz:
|
|
||||||
f_gz.writelines(f_ungz)
|
|
||||||
with open(original_bootanim, "r") as initfile:
|
|
||||||
initcontent = initfile.read()
|
|
||||||
if init_rc_component not in initcontent:
|
|
||||||
initcontent=initcontent+init_rc_component
|
|
||||||
with open(bootanim, "w") as initfile:
|
|
||||||
initfile.write(initcontent)
|
|
||||||
|
|
||||||
print("==> Magisk was installed ! Restarting waydroid container to apply changes !")
|
|
||||||
restart()
|
|
||||||
|
|
||||||
def install_widevine():
|
|
||||||
vendor_image_mount = "/var/lib/waydroid/overlay/vendor"
|
|
||||||
widevine_zip_url = "https://codeload.github.com/supremegamers/vendor_google_proprietary_widevine-prebuilt/zip/94c9ee172e3d78fecc81863f50a59e3646f7a2bd"
|
|
||||||
dl_file_name = os.path.join(download_loc, "widevine.zip")
|
|
||||||
extract_to = "/tmp/widevineunpack" #All catalog files will be marked as executable!
|
|
||||||
act_md5 = "a31f325453c5d239c21ecab8cfdbd878"
|
|
||||||
loc_md5 = ""
|
|
||||||
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
with open(dl_file_name,"rb") as f:
|
|
||||||
bytes = f.read()
|
|
||||||
loc_md5 = hashlib.md5(bytes).hexdigest()
|
|
||||||
|
|
||||||
# Download the file if hash mismatches or if file does not exist
|
|
||||||
while not os.path.isfile(dl_file_name) or loc_md5 != act_md5:
|
|
||||||
if os.path.isfile(dl_file_name):
|
|
||||||
os.remove(dl_file_name)
|
|
||||||
print("==> windevine zip not downloaded or hash mismatches, downloading now .....")
|
|
||||||
loc_md5 = download_file(widevine_zip_url, dl_file_name)
|
|
||||||
|
|
||||||
# Extract widevine files
|
|
||||||
print("==> Extracting archive...")
|
|
||||||
with zipfile.ZipFile(dl_file_name) as z:
|
|
||||||
z.extractall(extract_to)
|
|
||||||
|
|
||||||
#Mark widevine files as executable
|
|
||||||
print("==> Chmodding...")
|
|
||||||
run(["chmod", "+x", extract_to, "-R"])
|
|
||||||
|
|
||||||
# Copy library file
|
|
||||||
print("==> Copying library files ...")
|
|
||||||
shutil.copytree(os.path.join(extract_to, "vendor_google_proprietary_widevine-prebuilt-94c9ee172e3d78fecc81863f50a59e3646f7a2bd",
|
|
||||||
"prebuilts"), vendor_image_mount, dirs_exist_ok=True)
|
|
||||||
|
|
||||||
print("==> Widevine installed ! Restarting waydroid container to apply changes !")
|
|
||||||
restart()
|
|
||||||
|
|
||||||
def main():
|
|
||||||
about = """
|
|
||||||
WayDroid Helper script v0.3
|
|
||||||
Does stuff like installing Gapps, Installing NDK Translation and getting Android ID for device registration.
|
|
||||||
Use -h flag for help !
|
|
||||||
"""
|
|
||||||
check_root()
|
|
||||||
parser = argparse.ArgumentParser(description=about, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
||||||
parser.add_argument('-g', '--install-gapps',
|
|
||||||
dest='install',
|
|
||||||
help='Install OpenGapps to waydroid',
|
|
||||||
action='store_true')
|
|
||||||
parser.add_argument('-n', '--install-ndk-translation',
|
|
||||||
dest='installndk',
|
|
||||||
help='Install experimental libndk translation files',
|
|
||||||
action='store_true')
|
|
||||||
parser.add_argument('-i', '--get-android-id', dest='getid',
|
|
||||||
help='Displays your android id for manual registration',
|
|
||||||
action='store_true')
|
|
||||||
parser.add_argument('-m', '--install-magisk', dest='magisk',
|
|
||||||
help='Attempts to install Magisk ( Bootless )',
|
|
||||||
action='store_true')
|
|
||||||
parser.add_argument('-l', '--install-libhoudini', dest='houdini',
|
|
||||||
help='Install libhoudini for arm translation',
|
|
||||||
action='store_true')
|
|
||||||
parser.add_argument('-w', '--install-windevine', dest='widevine',
|
|
||||||
help='Integrate Widevine DRM (L3)',
|
|
||||||
action='store_true')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
if args.install:
|
|
||||||
install_gapps()
|
|
||||||
elif args.installndk:
|
|
||||||
install_ndk()
|
|
||||||
elif args.getid:
|
|
||||||
get_android_id()
|
|
||||||
elif args.magisk:
|
|
||||||
install_magisk()
|
|
||||||
elif args.houdini:
|
|
||||||
install_houdini()
|
|
||||||
elif args.widevine:
|
|
||||||
install_widevine()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Loading…
Reference in a new issue