diff --git a/README.md b/README.md index eb4cf88..fcc2a7f 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,15 @@ Script to add gapps and other stuff to waydroid ! # Installation/Usage -"lzip" and "sqlite" is required for this script to work, install it using your distribution's package manager: +"lzip" is required for this script to work, install it using your distribution's package manager: ## Arch, Manjaro and EndeavourOS based distributions: - sudo pacman -S lzip sqlite + sudo pacman -S lzip ## Debian and Ubuntu based distributions: - sudo apt install lzip sqlite + sudo apt install lzip ## RHEL, Fedora and Rocky based distributions: - sudo dnf install lzip sqlite + sudo dnf install lzip ## openSUSE based distributions: - sudo zypper install lzip sqlite + sudo zypper install lzip Then run: git clone https://github.com/casualsnek/waydroid_script @@ -50,7 +50,7 @@ Magisk will be installed on next boot ! Zygisk and modules like LSPosed should work now. -Please use `Direct Install into system partition` to update Magisk in Magisk manager. +If you want to update Magisk, Please use `Direct Install into system partition` or run this sript again. This script only focuses on Magisk installation, if you need more management, please check https://github.com/nitanmarcel/waydroid-magisk @@ -176,4 +176,4 @@ Check [waydroid-magisk](https://github.com/nitanmarcel/waydroid-magisk) - [microG Project](https://microg.org) - [Open GApps](https://opengapps.org) - [Smart Dock](https://github.com/axel358/smartdock) -- [wd-scripts](https://github.com/electrikjesus/wd-scripts/) \ No newline at end of file +- [wd-scripts](https://github.com/electrikjesus/wd-scripts/) diff --git a/bin/arm64-v8a/resetprop b/bin/arm64-v8a/resetprop new file mode 100755 index 0000000..b667d2e Binary files /dev/null and b/bin/arm64-v8a/resetprop differ diff --git a/bin/x86_64/resetprop b/bin/x86_64/resetprop new file mode 100755 index 0000000..0997f25 Binary files /dev/null and b/bin/x86_64/resetprop differ diff --git a/main.py b/main.py index f34788c..d9f96c8 100755 --- a/main.py +++ b/main.py @@ -13,52 +13,54 @@ from stuffs.nodataperm import Nodataperm from stuffs.smartdock import Smartdock from stuffs.widevine import Widevine import tools.helper as helper -def install(*args): - if "gapps" in args: - Gapps().install() - if "libndk" in args and "houdini" not in args: +def install(args): + app = args.app + if "gapps" in app: + Gapps(args.android_version).install() + if "libndk" in app and "houdini" not in app: arch = helper.host()[0] if arch == "x86_64": - Ndk().install() + Ndk(args.android_version).install() else: Logger.warn("libndk is not supported on your CPU") - if "libhoudini" in args and "ndk" not in args: + if "libhoudini" in app and "ndk" not in app: arch = helper.host()[0] if arch == "x86_64": - Houdini().install() + Houdini(args.android_version).install() else: Logger.warn("libhoudini is not supported on your CPU") - if "magisk" in args: + if "magisk" in app: Magisk().install() - if "widevine" in args: - Widevine().install() - if "smartdock" in args: + if "widevine" in app: + Widevine(args.android_version).install() + if "smartdock" in app: Smartdock().install() - if "nodataperm" in args: + if "nodataperm" in app: Nodataperm().install() - if "microg" in args: + if "microg" in app: MicroG().install() - if "hidestatus" in args: + if "hidestatus" in app: HideStatusBar().install() -def uninstall(*args): - if "gapps" in args: - Gapps().uninstall() - if "libndk" in args: - Ndk().uninstall() - if "libhoudini" in args: - Houdini().uninstall() - if "magisk" in args: +def uninstall(args): + app = args.app + if "gapps" in app: + Gapps(args.android_version).uninstall() + if "libndk" in app: + Ndk(args.android_version).uninstall() + if "libhoudini" in app: + Houdini(args.android_version).uninstall() + if "magisk" in app: Magisk().uninstall() - if "widevine" in args: - Widevine().uninstall() - if "smartdock" in args: + if "widevine" in app: + Widevine(args.android_version).uninstall() + if "smartdock" in app: Smartdock().uninstall() - if "nodataperm" in args: + if "nodataperm" in app: Nodataperm().uninstall() - if "microg" in args: + if "microg" in app: MicroG().uninstall() - if "hidestatus" in args: + if "hidestatus" in app: HideStatusBar().uninstall() def main(): @@ -71,7 +73,11 @@ def main(): parser = argparse.ArgumentParser(prog=about) parser.set_defaults(app="") - + parser.add_argument('-a', '--android-version', + dest='android_version', + help='Specify the Android version', + default="11", + choices=["11","13"]) subparsers = parser.add_subparsers(title="subcommands", help="operations") google_id_parser=subparsers.add_parser('google', @@ -104,9 +110,8 @@ smartdock: A desktop mode launcher for Android uninstall_parser.add_argument(**arg_template) args = parser.parse_args() - if args.app: - args.func(*args.app) + args.func(args) else: args.func() diff --git a/stuffs/gapps.py b/stuffs/gapps.py index 6bb2aa4..486d13b 100644 --- a/stuffs/gapps.py +++ b/stuffs/gapps.py @@ -3,61 +3,108 @@ import shutil from stuffs.general import General from tools.helper import host, run + class Gapps(General): partition = "system" dl_links = { + "11": { "x86_64": ["https://sourceforge.net/projects/opengapps/files/x86_64/20220503/open_gapps-x86_64-11.0-pico-20220503.zip", "5a6d242be34ad1acf92899c7732afa1b"], "x86": ["https://sourceforge.net/projects/opengapps/files/x86/20220503/open_gapps-x86-11.0-pico-20220503.zip", "efda4943076016d00b40e0874b12ddd3"], "arm64-v8a": ["https://sourceforge.net/projects/opengapps/files/arm64/20220503/open_gapps-arm64-11.0-pico-20220503.zip", "7790055d34bbfc6fe610b0cd263a7add"], "armeabi-v7a": ["https://sourceforge.net/projects/opengapps/files/arm/20220215/open_gapps-arm-11.0-pico-20220215.zip", "8719519fa32ae83a62621c6056d32814"] + }, + "13": { + "x86_64": ["https://github.com/Howard20181/MindTheGappsBuilder/releases/download/20230323/MindTheGapps-13.0.0-x86_64-20230323.zip", "aba427be1ddd0963121c87a4eda80299"], + "x86": ["https://github.com/Howard20181/MindTheGappsBuilder/releases/download/20230323/MindTheGapps-13.0.0-x86-20230323.zip", "f02d2f1a3f0a084f13ab4c1b58ad7554"], + "arm64-v8a": ["https://github.com/Howard20181/MindTheGappsBuilder/releases/download/20230323/MindTheGapps-13.0.0-arm64-20230323.zip", "18484a5622eeccffcea2b43205655d8a"], + "armeabi-v7a": ["https://github.com/Howard20181/MindTheGappsBuilder/releases/download/20230323/MindTheGapps-13.0.0-arm-20230323.zip", "e4c00a7eb1e4dfca0fc6a3e447710264"] } + } + android_version = ... 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" + dl_link = ... + act_md5 = ... + dl_file_name = "gapps.zip" + extract_to = "/tmp/gapps/extract" non_apks = [ "defaultetc-common.tar.lz", "defaultframework-common.tar.lz", "googlepixelconfig-common.tar.lz", "vending-common.tar.lz" - ] + ] skip = [ "setupwizarddefault-x86_64.tar.lz", "setupwizardtablet-x86_64.tar.lz" - ] + ] files = [ - "etc/default-permissions/default-permissions.xml", - "etc/default-permissions/opengapps-permissions-q.xml", - "etc/permissions/com.google.android.maps.xml", - "etc/permissions/com.google.android.media.effects.xml", - "etc/permissions/privapp-permissions-google.xml", - "etc/permissions/split-permissions-google.xml", - "etc/preferred-apps/google.xml", - "etc/sysconfig/google.xml", - "etc/sysconfig/google_build.xml", - "etc/sysconfig/google_exclusives_enable.xml", - "etc/sysconfig/google-hiddenapi-package-whitelist.xml", - "framework/com.google.android.maps.jar", - "framework/com.google.android.media.effects.jar", - "priv-app/AndroidMigratePrebuilt", - "priv-app/GoogleExtServices", - "priv-app/GoogleRestore", - "priv-app/CarrierSetup", - "priv-app/GoogleExtShared", - "priv-app/GoogleServicesFramework", - "priv-app/ConfigUpdater", - "priv-app/GoogleFeedback", - "priv-app/Phonesky", - "priv-app/GoogleBackupTransport", - "priv-app/GoogleOneTimeInitializer", - "priv-app/PrebuiltGmsCore", - "priv-app/GoogleContactsSyncAdapter", - "priv-app/GooglePartnerSetup", - "product/overlay/PlayStoreOverlay.apk" - ] + "etc/default-permissions/default-permissions.xml", + "etc/default-permissions/opengapps-permissions-q.xml", + "etc/permissions/com.google.android.maps.xml", + "etc/permissions/com.google.android.media.effects.xml", + "etc/permissions/privapp-permissions-google.xml", + "etc/permissions/split-permissions-google.xml", + "etc/preferred-apps/google.xml", + "etc/sysconfig/google.xml", + "etc/sysconfig/google_build.xml", + "etc/sysconfig/google_exclusives_enable.xml", + "etc/sysconfig/google-hiddenapi-package-whitelist.xml", + "framework/com.google.android.maps.jar", + "framework/com.google.android.media.effects.jar", + "priv-app/AndroidMigratePrebuilt", + "priv-app/GoogleExtServices", + "priv-app/GoogleRestore", + "priv-app/CarrierSetup", + "priv-app/GoogleExtShared", + "priv-app/GoogleServicesFramework", + "priv-app/ConfigUpdater", + "priv-app/GoogleFeedback", + "priv-app/Phonesky", + "priv-app/GoogleBackupTransport", + "priv-app/GoogleOneTimeInitializer", + "priv-app/PrebuiltGmsCore", + "priv-app/GoogleContactsSyncAdapter", + "priv-app/GooglePartnerSetup", + "product/overlay/PlayStoreOverlay.apk", + "system_ext/permissions/privapp-permissions-google-system-ext.xml", + "system_ext/priv-app/GoogleFeedback", + "system_ext/priv-app/GoogleServicesFramework", + "system_ext/priv-app/SetupWizard", + "product/priv-app/GmsCore", + "product/priv-app/AndroidAutoStub", + "product/priv-app/GoogleRestore", + "product/priv-app/Phonesky", + "product/priv-app/Velvet", + "product/priv-app/GooglePartnerSetup", + "product/app/GoogleCalendarSyncAdapter", + "product/app/PrebuiltExchange3Google", + "product/app/GoogleContactsSyncAdapter", + "product/framework/com.google.android.dialer.support.jar", + "product/lib64/libjni_latinimegoogle.so", + "product/etc/default-permissions/default-permissions-google.xml", + "product/etc/default-permissions/default-permissions-mtg.xml", + "product/etc/sysconfig/google.xml", + "product/etc/sysconfig/d2d_cable_migration_feature.xml", + "product/etc/sysconfig/google-hiddenapi-package-allowlist.xml", + "product/etc/sysconfig/google_build.xml", + "product/etc/permissions/privapp-permissions-google-product.xml", + "product/etc/permissions/com.google.android.dialer.support.xml", + "product/etc/security/fsverity/gms_fsverity_cert.der", + "product/lib/libjni_latinimegoogle.so", + ] + + def __init__(self, android_version="11") -> None: + super().__init__() + self.android_version = android_version + self.dl_link = self.dl_links[android_version][self.arch[0]][0] + self.act_md5 = self.dl_links[android_version][self.arch[0]][1] def copy(self): + if self.android_version == "11": + return self.copy_11() + elif self.android_version == "13": + return self.copy_13() + + def copy_11(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")): @@ -68,18 +115,41 @@ class Gapps(General): 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) + 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) + 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")) + 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) + 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) + + def copy_13(self): + for root, dirs, files in os.walk(os.path.join(self.extract_to, "system")): + for dir in dirs: + os.chmod(os.path.join(root, dir), 0o755) + for file in files: + os.chmod(os.path.join(root, file), 0o644) + os.chown(os.path.join(root, file), 0, 0) + + shutil.copytree(os.path.join(self.extract_to, "system"), os.path.join( + self.copy_dir, self.partition), dirs_exist_ok=True) diff --git a/stuffs/general.py b/stuffs/general.py index feb0a20..cd8a11a 100644 --- a/stuffs/general.py +++ b/stuffs/general.py @@ -5,7 +5,7 @@ import shutil import zipfile import hashlib from tools import images -from tools.helper import download_file, get_download_dir, upgrade +from tools.helper import download_file, get_download_dir, host, upgrade from tools import container from tools.logger import Logger @@ -60,11 +60,31 @@ class General: z.extractall(self.extract_to) def add_props(self): + arch = host()[0] + bin_dir = os.path.join(self.copy_dir, "system", "bin") + resetprop_rc=os.path.join(self.copy_dir, "system/etc/init/resetprop.rc") + if not os.path.isfile(os.path.join(bin_dir, "resetprop")): + if not os.path.exists(bin_dir): + os.makedirs(bin_dir) + shutil.copy(os.path.join("./bin",arch,"resetprop"), bin_dir) + os.chmod(os.path.join(bin_dir, "resetprop"), 0o755) + if not os.path.isfile(os.path.join(bin_dir, "resetprop.sh")): + with open(os.path.join(bin_dir, "resetprop.sh"), "w") as f: + f.write("#!/system/bin/sh\nwhile read line; do resetprop ${line%=*} ${line#*=}; done < /vendor/waydroid.prop") + os.chmod(os.path.join(bin_dir, "resetprop.sh"), 0o755) + if not os.path.isfile(resetprop_rc): + if not os.path.exists(os.path.dirname(resetprop_rc)): + os.makedirs(os.path.dirname(resetprop_rc)) + with open(resetprop_rc, "w") as f: + f.write("on post-fs-data\n exec u:r:su:s0 root root -- /system/bin/sh /system/bin/resetprop.sh") + os.chmod(resetprop_rc, 0o644) + cfg = configparser.ConfigParser() cfg.read("/var/lib/waydroid/waydroid.cfg") for key in self.apply_props.keys(): - cfg.set('properties', key, self.apply_props[key]) + if self.apply_props[key]: + cfg.set('properties', key, self.apply_props[key]) with open("/var/lib/waydroid/waydroid.cfg", "w") as f: cfg.write(f) @@ -120,7 +140,6 @@ class General: def restart(self): self.stop() self.start() - upgrade() def copy(self): pass diff --git a/stuffs/houdini.py b/stuffs/houdini.py index b2144d3..6856060 100644 --- a/stuffs/houdini.py +++ b/stuffs/houdini.py @@ -8,8 +8,12 @@ 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_links = { + "11": ["https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/81f2a51ef539a35aead396ab7fce2adf89f46e88.zip", "fbff756612b4144797fbc99eadcb6653"], + "13": ["https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/978d8cba061a08837b7e520cd03b635af643ba08.zip", "1e139054c05034648fae58a1810573b4"] + } + act_md5 = ... + dl_link = ... dl_file_name = "libhoudini.zip" extract_to = "/tmp/houdiniunpack" init_rc_component = """ @@ -32,17 +36,22 @@ on property:ro.enable.native.bridge.exec=1 "ro.dalvik.vm.isa.arm64": "x86_64" } files = [ - "bin/arm", - "bin/arm64", - "bin/houdini", - "bin/houdini64", - "etc/binfmt_misc", - "etc/init/houdini.rc", - "lib/arm", - "lib/libhoudini.so", - "lib64/arm64", - "lib64/libhoudini.so" - ] + "bin/arm", + "bin/arm64", + "bin/houdini", + "bin/houdini64", + "etc/binfmt_misc", + "etc/init/houdini.rc", + "lib/arm", + "lib/libhoudini.so", + "lib64/arm64", + "lib64/libhoudini.so" + ] + + def __init__(self, android_version="11") -> None: + super().__init__() + self.dl_link = self.dl_links[android_version][0] + self.act_md5 = self.dl_links[android_version][1] def copy(self): run(["chmod", "+x", self.extract_to, "-R"]) @@ -50,9 +59,10 @@ on property:ro.enable.native.bridge.exec=1 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") + 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) + initfile.write(self.init_rc_component) os.chmod(init_path, 0o644) diff --git a/stuffs/ndk.py b/stuffs/ndk.py index d2fc052..eb547d8 100644 --- a/stuffs/ndk.py +++ b/stuffs/ndk.py @@ -1,9 +1,9 @@ -import glob import os import shutil from stuffs.general import General from tools.helper import run from tools.logger import Logger +from tools.container import use_overlayfs class Ndk(General): partition = "system" @@ -16,8 +16,10 @@ class Ndk(General): "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.enable.native.bridge.exec": None, + "ro.vendor.enable.native.bridge.exec": None, + "ro.vendor.enable.native.bridge.exec64": None, + "ro.ndk_translation.version": "0.2.3", "ro.dalvik.vm.isa.arm": "x86", "ro.dalvik.vm.isa.arm64": "x86_64" } @@ -35,6 +37,14 @@ class Ndk(General): "lib/libndk*", "lib64/libndk*" ] + def __init__(self, android_version="11") -> None: + super().__init__() + if android_version=="11": + self.apply_props["ro.enable.native.bridge.exec"] = "1" + elif android_version=="13": + self.apply_props["ro.vendor.enable.native.bridge.exec"] = "1" + self.apply_props["ro.vendor.enable.native.bridge.exec64"] = "1" + def copy(self): run(["chmod", "+x", self.extract_to, "-R"])