From ccda6b1a4672ee6540d21629f21395c5556ee14f Mon Sep 17 00:00:00 2001 From: Lolmc0587 Date: Thu, 10 Jul 2025 16:46:04 +0700 Subject: [PATCH 1/4] Add gps support --- main.py | 32 +++++++-- stuff/gps.py | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 5 deletions(-) create mode 100644 stuff/gps.py diff --git a/main.py b/main.py index d76f415..138d53d 100755 --- a/main.py +++ b/main.py @@ -18,6 +18,7 @@ from stuff.nodataperm import Nodataperm from stuff.smartdock import Smartdock from stuff.widevine import Widevine from stuff.fdroidpriv import FDroidPriv +from stuff.gps import GPS import tools.helper as helper from tools import container from tools import images @@ -89,6 +90,8 @@ def install_app(args): install_list.append(Mitm(args.ca_cert_file)) if "fdroidpriv" in app: install_list.append(FDroidPriv(args.android_version)) + if "gps" in app: + install_list.append(GPS(args.android_version, args.gps_host, args.baud_rate)) if not container.use_overlayfs(): copy_dir = "/tmp/waydroid" @@ -115,8 +118,7 @@ def install_app(args): if not container.use_overlayfs(): umount("vendor", copy_dir) umount("system", copy_dir) - - container.upgrade() + container.upgrade() def remove_app(args): @@ -144,6 +146,8 @@ def remove_app(args): remove_list.append(Nodataperm(args.android_version)) if "hidestatusbar" in app: remove_list.append(HideStatusBar()) + if "gps" in app: + remove_list.append(GPS()) if not container.use_overlayfs(): copy_dir = "/tmp/waydroid" @@ -169,6 +173,7 @@ def hack_option(args): hack_list.append(Nodataperm()) if "hidestatusbar" in options: hack_list.append(HideStatusBar()) + if not container.use_overlayfs(): copy_dir = "/tmp/waydroid" @@ -229,10 +234,11 @@ def interact(): if not action: exit() - install_choices = ["gapps", "microg", "libndk", "libhoudini", "magisk", "smartdock", "fdroidpriv",] + install_choices = ["gapps", "microg", "libndk", "libhoudini", "magisk", "smartdock", "fdroidpriv","gps"] + baud_rate_choices = ["9600", "19200", "38400", "57600", "115200"] hack_choices = [] if android_version=="11": - install_choices.extend(["widevine"]) + install_choices.extend(["widevine", ]) hack_choices.extend(["nodataperm", "hidestatusbar"]) if action == "Install": @@ -252,6 +258,20 @@ def interact(): default="Standard", ).execute() args.microg_variant = microg_variant + if "gps" in apps: + gps_host = inquirer.text( + message="Enter GPS host (default: /dev/ttyGPSD)", + default="/dev/ttyGPSD", + ).execute() + args.gps_host = gps_host + baud_rate = inquirer.select( + message="Enter baud rate (default: 9600)", + instruction="([\u2191\u2193]: [Enter]: Confirm", + default="9600", + choices=baud_rate_choices + ).execute() + args.baud_rate = baud_rate + args.app = apps install_app(args) elif action == "Remove": @@ -270,7 +290,7 @@ def interact(): message="Select hack options", instruction="([\u2191\u2193]: Select Item. [Space]: Toggle Choice), [Enter]: Confirm", validate=lambda result: len(result) >= 1, - invalid_message="should be at least 1 selection", + invalid_message="should be at leinstall_appast 1 selection", choices=hack_choices ).execute() args.option_name = apps @@ -345,6 +365,8 @@ widevine: Add support for widevine DRM L3 args = parser.parse_args() args.microg_variant = "Standard" + args.gps_host = "/dev/ttyGPSD" + args.baud_rate = "9600" if hasattr(args, 'func'): args_dict = vars(args) helper.check_root() diff --git a/stuff/gps.py b/stuff/gps.py new file mode 100644 index 0000000..e6f8e81 --- /dev/null +++ b/stuff/gps.py @@ -0,0 +1,197 @@ +import os +from xml.dom import minidom +import xml.etree.ElementTree as ET +import shutil +from stuff.general import General +from tools.logger import Logger +import tools.images as images +from tools.helper import run, host +from tools import container + +class GPS(General): + id = "gps" + partition = "vendor" + dl_links = ["https://github.com/Lolmc0587/android_gps_libraries/archive/refs/tags/2.1.zip","f84c369c7cebd9dbb8987ca15c6aa856"] + act_md5 = ... + dl_link = ... + dl_file_name = "android_gps_libraries-2.1.zip" + extract_to = "/tmp/android_gps_libraries-2.1" + + files = [ + "lib/hw/android.hardware.gnss@1.0-impl.so", + "lib64/hw/android.hardware.gnss@1.0-impl.so", + "lib/hw/gps.default.so", + "lib64/hw/gps.default.so", + "etc/init/android.hardware.gnss@1.0-service.rc", + ] + + + def __init__(self, android_version="11", gps_host="/dev/ttyGPSD", baud_rate=9600) -> None: + super().__init__() + self.host_arch = host() + # Set for arm 32 bit support from file downloaded + self.host = "arm64-v8a" if "arm" in self.host_arch[0] else self.host_arch[0] + self.gps_host = gps_host + self.baud_rate = baud_rate + self.android_version = android_version + self.usb_name = self.gps_host.split("/")[-1] + self.files_vendor = [ + "bin/hw/android.hardware.gnss@1.0-service", + ] + self.config_files = { + "11": [ + "etc/vintf/compatibility_matrix.legacy.xml", + "etc/vintf/manifest.xml", + "build.prop", + ], + "13": [ + "etc/vintf/compatibility_matrix.7.xml", + "etc/vintf/manifest.xml", + "build.prop", + ], + } + + self.compatibility_files = { + "11": "etc/vintf/compatibility_matrix.legacy.xml", + "13": "etc/vintf/compatibility_matrix.7.xml", + } + + self.dl_link = self.dl_links[0] + self.act_md5 = self.dl_links[1] + + def update_manifest(self, manifest_path, data): + """ + Update the manifest file by inserting data into the tag and format the XML. + """ + tree = ET.parse(manifest_path) + root = tree.getroot() + + root.append(ET.fromstring(data)) + tree.write(manifest_path, encoding="utf-8", xml_declaration=True) + + with open(manifest_path, "r") as f: + content = f.read() + formatted_content = minidom.parseString(content).toprettyxml(indent=" ") + + formatted_content = "\n".join( + [line for line in formatted_content.split("\n") if line.strip()] + ) + + with open(manifest_path, "w") as f: + f.write(formatted_content) + + def copy(self): + Logger.info("Copying gps library files ...") + if self.android_version == "11": + shutil.copytree(os.path.join(self.extract_to, self.dl_file_name.replace(".zip", ""), self.android_version, + self.host, "system"), os.path.join(self.copy_dir, "system"), dirs_exist_ok=True) + self.partition = "system" + if self.android_version == "13": + shutil.copytree(os.path.join(self.extract_to, self.dl_file_name.replace(".zip", ""), self.android_version, + self.host, "system"), os.path.join(self.copy_dir, "vendor"), dirs_exist_ok=True) + self.partition = "vendor" + shutil.copytree(os.path.join(self.extract_to, self.dl_file_name.replace(".zip", ""), self.android_version, + self.host, "vendor"), os.path.join(self.copy_dir, "vendor"), dirs_exist_ok=True) + + def extra1(self): + Logger.info("Setting extra permissions ...") + # set permissions for vendor files + path = os.path.join(self.copy_dir, "vendor", self.files_vendor[0]) + self.set_perm2(path, recursive=True) + + # Copy nessessary files to the overlayfs + container.stop() + copy_dir = "/tmp/waydroid" + if container.use_overlayfs(): + img = os.path.join(images.get_image_dir(), "system.img") + # images.mount(img, copy_dir) + if not os.path.exists(copy_dir): + os.makedirs(copy_dir) + run(["sudo", "mount", img, copy_dir]) + + for file in self.config_files[self.android_version]: + file_dir = os.path.join(self.copy_dir, "system", file) + if not os.path.exists(os.path.dirname(file_dir)): + os.makedirs(os.path.dirname(file_dir)) + shutil.copyfile(os.path.join(copy_dir, "system", file), file_dir) + self.set_perm2(file_dir, recursive=True) + + if self.android_version == "13": + # Copy missing libraries file for android 13 vendor partition from system partition + if not os.path.exists(os.path.join(self.copy_dir, "vendor", "lib64", "hw")): + os.makedirs(os.path.join(self.copy_dir, "vendor", "lib64", "hw")) + + copy_ = True + if "arm" in self.host and self.host_arch[1] == 32: + copy_ = False + if copy_: + shutil.copyfile(os.path.join(copy_dir, "system", "lib64/android.hardware.gnss@1.0.so"), + os.path.join(self.copy_dir, "vendor", "lib64/hw/android.hardware.gnss@1.0.so")) + + if not os.path.exists(os.path.join(self.copy_dir, "vendor", "lib", "hw")): + os.makedirs(os.path.join(self.copy_dir, "vendor", "lib", "hw")) + + shutil.copyfile(os.path.join(copy_dir, "system", "lib/android.hardware.gnss@1.0.so"), + os.path.join(self.copy_dir, "vendor", "lib/hw/android.hardware.gnss@1.0.so")) + + images.umount(copy_dir) + + # Update manifest files + container.upgrade() + + manifest_entry_1 = """ + + android.hardware.gnss + 1.0 + + IGnss + default + + + """ + self.update_manifest( + os.path.join(self.copy_dir, "system", self.compatibility_files[self.android_version]), + data=manifest_entry_1, + ) + + manifest_entry_2 = """ + + android.hardware.gnss + hwbinder + 1.0 + + IGnss + default + + @1.0::IGnss/default + + """ + self.update_manifest(os.path.join(self.copy_dir, "system", "etc", "vintf", "manifest.xml"), data=manifest_entry_2) + config_nodes = "/var/lib/waydroid/lxc/waydroid/config_nodes" + # lxc.mount.entry = /dev/ttyGPSD dev/ttyGPSD none bind,create=file,optional 0 0 + + with open(config_nodes, "a") as f: + f.write(f"lxc.mount.entry = {self.gps_host} dev/{self.usb_name} none bind,create=file,optional 0 0\n") + + with open(os.path.join(self.copy_dir, "system", "build.prop"), "a") as f: + f.write("ro.factory.hasGPS=true\n") + f.write(f"ro.kernel.android.gps={self.usb_name}\n") + f.write(f"ro.kernel.android.gps.speed={self.baud_rate}\n") + Logger.warning( + "You need to add user to the 'dialout' group to access the GPS device." + "\nYou can do this by running: sudo usermod -aG dialout " + "\nand then reboot your system." + ) + def extra2(self): + # Remove vendor files from system partition + self.files = self.files_vendor + self.partition = "vendor" + self.remove() + + # Remove config files from system partition + self.files = self.config_files[self.android_version] + self.partition = "system" + self.remove() + + container.upgrade() + From 4b7b609d67ee9f5e3c7e88f8944da02a5b0dbdd5 Mon Sep 17 00:00:00 2001 From: Tom <59377673+Lolmc0587@users.noreply.github.com> Date: Thu, 10 Jul 2025 16:48:50 +0700 Subject: [PATCH 2/4] Fix typo --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 138d53d..4ca118e 100755 --- a/main.py +++ b/main.py @@ -290,7 +290,7 @@ def interact(): message="Select hack options", instruction="([\u2191\u2193]: Select Item. [Space]: Toggle Choice), [Enter]: Confirm", validate=lambda result: len(result) >= 1, - invalid_message="should be at leinstall_appast 1 selection", + invalid_message="should be at least 1 selection", choices=hack_choices ).execute() args.option_name = apps From 446970ad4831c53b42af3502d8b1f2f00a1ac115 Mon Sep 17 00:00:00 2001 From: huakim <92579808+huakim@users.noreply.github.com> Date: Sat, 5 Jul 2025 06:44:21 +0300 Subject: [PATCH 3/4] Merge branch 'main' into main --- README.md | 46 +++++++++++---------- default.nix | 26 ++---------- flake.lock | 41 +++++++++++++++++++ flake.nix | 21 ++++++++++ main.py | 99 ++++++++++++++++----------------------------- package.nix | 32 +++++++++++++++ requirements.txt | 1 - stuff/microg.py | 4 +- stuff/ndk.py | 2 +- stuff/nodataperm.py | 2 +- stuff/smartdock.py | 32 ++++++++------- stuff/widevine.py | 2 +- tools/container.py | 4 +- tools/images.py | 2 +- 14 files changed, 182 insertions(+), 132 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 package.nix diff --git a/README.md b/README.md index ed03881..2b34f3c 100644 --- a/README.md +++ b/README.md @@ -7,27 +7,26 @@ Script to add GApps and other stuff to Waydroid! ## Interactive terminal interface ``` -git clone https://github.com/casualsnek/waydroid_script +git clone --depth 1 --single-branch https://github.com/huakim/waydroid_script cd waydroid_script python3 -m venv venv venv/bin/pip install -r requirements.txt sudo venv/bin/python3 main.py ``` -![image-20230430013103883](assets/img/README/image-20230430013103883.png) +![image-20230430013103883](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/img/README/image-20230430013103883.png) -![image-20230430013119763](assets/img/README/image-20230430013119763.png) - -![image-20230430013148814](assets/img/README/image-20230430013148814.png) +![image-20230430013119763](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/img/README/image-20230430013119763.png) +![image-20230430013148814](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main//assets/img/README/image-20230430013148814.png) ## Command Line ```bash -git clone https://github.com/casualsnek/waydroid_script +git clone --depth 1 --single-branch https://github.com/huakim/waydroid_script cd waydroid_script -python3 -m venv venv +venv/bin/python3 -m venv venv venv/bin/pip install -r requirements.txt # install something sudo venv/bin/python3 main.py install {gapps, magisk, libndk, libhoudini, nodataperm, smartdock, microg, mitm} @@ -42,18 +41,23 @@ sudo venv/bin/python3 main.py hack {nodataperm, hidestatusbar} ## Dependencies "lzip" is required for this script to work, install it using your distribution's package manager: +### openSUSE, Gecko based distributions: + sudo zypper install lzip +### RHEL, Fedora and Rocky based distributions: + sudo dnf install lzip ### Arch, Manjaro and EndeavourOS based distributions: sudo pacman -S lzip ### Debian and Ubuntu based distributions: sudo apt install lzip -### RHEL, Fedora and Rocky based distributions: - sudo dnf install lzip -### openSUSE based distributions: - sudo zypper install lzip ## Install OpenGapps ![](assets/1.png) +======= + +## Install OpenGapps + +![](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/1.png) Open terminal and switch to the directory where "main.py" is located then run: @@ -65,13 +69,13 @@ Then launch waydroid with: After waydroid has finished booting, open terminal and switch to directory where "main.py" is located then run: - sudo python3 main.py google + sudo venv/bin/python3 main.py google Copy the returned numeric ID, then open ["https://google.com/android/uncertified/?pli=1"](https://google.com/android/uncertified/?pli=1). Enter the ID and register it. Wait 10-20 minutes for device to get registered. Then clear Google Play Service's cache and try logging in! ## Install Magisk -![](assets/2.png) +![](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/2.png) Open terminal and switch to directory where "main.py" is located then run: @@ -81,7 +85,7 @@ Magisk will be installed on next boot! Zygisk and modules like LSPosed should work now. -If you want to update Magisk, Please use `Direct Install into system partition` or run this sript again. +If you want to update Magisk, Please use `Direct Install into system partition` or run this script again. This script only focuses on Magisk installation, if you need more management, please check https://github.com/nitanmarcel/waydroid-magisk @@ -109,7 +113,7 @@ Open terminal and switch to directory where "main.py" is located then run: ## Integrate Widevine DRM (L3) -![](assets/3.png) +![](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/3.png) Open terminal and switch to directory where "main.py" is located then run: @@ -117,8 +121,8 @@ Open terminal and switch to directory where "main.py" is located then run: ## Install Smart Dock -![](assets/4.png) -![](assets/5.png) +![](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/4.png) +![](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/5.png) Open terminal and switch to directory where "main.py" is located then run: @@ -137,7 +141,7 @@ This is a temporary hack to combat against the apps permission issue on Android Arknights, PUNISHING: GRAY RAVEN and other games won't freeze on the black screen. -![](assets/6.png) +![](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/6.png) Open terminal and switch to directory where "main.py" is located then run: @@ -163,7 +167,7 @@ chmod 777 -R /mnt/*/*/*/*/Android/obb ## Install microG, Aurora Store and Aurora Droid -![](assets/7.png) +![](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/7.png) ``` sudo venv/bin/python3 main.py install microg @@ -171,10 +175,10 @@ sudo venv/bin/python3 main.py install microg ## Hide Status Bar Before -![Before](assets/8.png) +![Before](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/8.png) After -![After](assets/9.png) +![After](https://raw.githubusercontent.com/huakim/waydroid_script_assets/main/assets/9.png) ``` sudo venv/bin/python3 main.py hack hidestatusbar diff --git a/default.nix b/default.nix index 9ab2954..23423af 100644 --- a/default.nix +++ b/default.nix @@ -1,22 +1,4 @@ -with (import {}); - -stdenv.mkDerivation { - name = "waydroid_script"; - - buildInputs = [ - (python3.withPackages(ps: with ps; [ tqdm requests inquirerpy ])) - ]; - - src = ./.; - - postPatch = '' - patchShebangs main.py - ''; - - installPhase = '' - mkdir -p $out/libexec - cp -r . $out/libexec/waydroid_script - mkdir -p $out/bin - ln -s $out/libexec/waydroid_script/main.py $out/bin/waydroid_script - ''; -} +let + pkgs = import {}; +in + pkgs.callPackage ./package.nix { } diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..fb6d247 --- /dev/null +++ b/flake.lock @@ -0,0 +1,41 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1707650010, + "narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "systems": "systems" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a0a7172 --- /dev/null +++ b/flake.nix @@ -0,0 +1,21 @@ +{ + description = "Waydroid Extras Script"; + inputs = { + systems.url = "github:nix-systems/default"; + }; + outputs = { self, nixpkgs, systems }: + let + inherit (nixpkgs) lib; + eachSystem = lib.genAttrs (import systems); + mkApp = program: { type = "app"; inherit program; }; + in { + packages = eachSystem (system: rec { + waydroid_script = nixpkgs.legacyPackages."${system}".callPackage ./package.nix { }; + default = waydroid_script; + }); + apps = eachSystem (system: rec { + waydroid_script = mkApp "${self.outputs.packages.${system}.waydroid_script}/bin/waydroid_script"; + default = waydroid_script; + }); + }; +} diff --git a/main.py b/main.py index 4ca118e..2de0ef7 100755 --- a/main.py +++ b/main.py @@ -1,7 +1,10 @@ #!/usr/bin/env python3 -from InquirerPy import inquirer -from InquirerPy.base.control import Choice -from InquirerPy.separator import Separator +try: + from InquirerPy import inquirer + from InquirerPy.base.control import Choice + from InquirerPy.separator import Separator +except ModuleNotFoundError: + inquirer = None import argparse import os from typing import List @@ -22,45 +25,29 @@ from stuff.gps import GPS import tools.helper as helper from tools import container from tools import images - -import argparse - from tools.logger import Logger - -def get_certified(args): +def get_certified(): AndroidId().get_id() - def mount(partition, copy_dir): - img = os.path.join(images.get_image_dir(), partition+".img") - mount_point = "" - if partition == "system": - mount_point = os.path.join(copy_dir) - else: - mount_point = os.path.join(copy_dir, partition) - Logger.info("Mounting {} to {}".format(img, mount_point)) + img = os.path.join(images.get_image_dir(), f"{partition}.img") + mount_point = os.path.join(copy_dir) if partition == "system" else os.path.join(copy_dir, partition) + Logger.info(f"Mounting {img} to {mount_point}") images.mount(img, mount_point) - def resize(partition): - img = os.path.join(images.get_image_dir(), 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)) + img = os.path.join(images.get_image_dir(), f"{partition}.img") + img_size = int(os.path.getsize(img) / (1024 * 1024)) + new_size = f"{img_size + 500}M" + Logger.info(f"Resizing {img} to {new_size}") images.resize(img, new_size) - def umount(partition, copy_dir): - mount_point = "" - if partition == "system": - mount_point = os.path.join(copy_dir) - else: - mount_point = os.path.join(copy_dir, partition) - Logger.info("Umounting {}".format(mount_point)) + mount_point = os.path.join(copy_dir) if partition == "system" else os.path.join(copy_dir, partition) + Logger.info(f"Unmounting {mount_point}") images.umount(mount_point) - def install_app(args): install_list: List[General] = [] app = args.app @@ -92,7 +79,6 @@ def install_app(args): install_list.append(FDroidPriv(args.android_version)) if "gps" in app: install_list.append(GPS(args.android_version, args.gps_host, args.baud_rate)) - if not container.use_overlayfs(): copy_dir = "/tmp/waydroid" container.stop() @@ -118,8 +104,7 @@ def install_app(args): if not container.use_overlayfs(): umount("vendor", copy_dir) umount("system", copy_dir) - container.upgrade() - + container.upgrade() def remove_app(args): remove_list: List[General] = [] @@ -148,7 +133,6 @@ def remove_app(args): remove_list.append(HideStatusBar()) if "gps" in app: remove_list.append(GPS()) - if not container.use_overlayfs(): copy_dir = "/tmp/waydroid" container.stop() @@ -162,19 +146,14 @@ def remove_app(args): container.upgrade() - def hack_option(args): - Logger.warning( - "If these hacks cause any problems, run `sudo python main.py remove ` to remove") - + Logger.warning("If these hacks cause any problems, run `sudo python main.py remove ` to remove") hack_list: List[General] = [] options = args.option_name if "nodataperm" in options: hack_list.append(Nodataperm()) if "hidestatusbar" in options: hack_list.append(HideStatusBar()) - - if not container.use_overlayfs(): copy_dir = "/tmp/waydroid" container.stop() @@ -203,10 +182,11 @@ def hack_option(args): container.upgrade() - def interact(): + if inquirer is None: + print('Please, install InquirerPy module first') + return os.system("clear") - args = argparse.Namespace() android_version = inquirer.select( message="Select Android version", instruction="(\u2191\u2193 Select Item)", @@ -219,15 +199,11 @@ def interact(): ).execute() if not android_version: exit() - args.android_version = android_version + args = argparse.Namespace(android_version=android_version, microg_variant="Standard") + action = inquirer.select( message="Please select an action", - choices=[ - "Install", - "Remove", - "Hack", - "Get Google Device ID to Get Certified" - ], + choices=["Install", "Remove", "Hack", "Get Google Device ID to Get Certified"], instruction="([↑↓]: Select Item)", default=None, ).execute() @@ -238,7 +214,7 @@ def interact(): baud_rate_choices = ["9600", "19200", "38400", "57600", "115200"] hack_choices = [] if android_version=="11": - install_choices.extend(["widevine", ]) + install_choices.extend(["widevine"]) hack_choices.extend(["nodataperm", "hidestatusbar"]) if action == "Install": @@ -249,8 +225,7 @@ def interact(): invalid_message="should be at least 1 selection", choices=install_choices ).execute() - microg_variants = ["Standard", "NoGoolag", - "UNLP", "Minimal", "MinimalIAP"] + microg_variants = ["Standard", "NoGoolag", "UNLP", "Minimal", "MinimalIAP"] if "microg" in apps: microg_variant = inquirer.select( message="Select MicroG variant", @@ -271,7 +246,6 @@ def interact(): choices=baud_rate_choices ).execute() args.baud_rate = baud_rate - args.app = apps install_app(args) elif action == "Remove": @@ -283,7 +257,7 @@ def interact(): choices=[*install_choices, *hack_choices] ).execute() args.app = apps - args.microg_variant="Standard" + args.microg_variant = "Standard" remove_app(args) elif action == "Hack": apps = inquirer.checkbox( @@ -296,15 +270,13 @@ def interact(): args.option_name = apps hack_option(args) elif action == "Get Google Device ID to Get Certified": - AndroidId().get_id() - + get_certified() def main(): parser = argparse.ArgumentParser(description=''' Does stuff like installing Gapps, installing Magisk, installing NDK Translation and getting Android ID for device registration. Use -h flag for help!''') - - subparsers = parser.add_subparsers(title="coomand", dest='command') + subparsers = parser.add_subparsers(title="command", dest='command') parser.add_argument('-a', '--android-version', dest='android_version', help='Specify the Android version', @@ -317,7 +289,7 @@ def main(): certified.set_defaults(func=get_certified) install_choices = ["gapps", "microg", "libndk", "libhoudini", - "magisk", "mitm", "smartdock", "widevine"] + "magisk", "mitm", "smartdock", "widevine", "gps"] hack_choices = ["nodataperm", "hidestatusbar"] micrg_variants = ["Standard", "NoGoolag", "UNLP", "Minimal", "MinimalIAP"] remove_choices = install_choices @@ -325,8 +297,7 @@ def main(): arg_template = { "dest": "app", "type": str, - "nargs": '+', - # "metavar":"", + "nargs": '+' } install_help = """ @@ -364,17 +335,15 @@ widevine: Add support for widevine DRM L3 hack_parser.set_defaults(func=hack_option) args = parser.parse_args() - args.microg_variant = "Standard" - args.gps_host = "/dev/ttyGPSD" - args.baud_rate = "9600" + args.microg_variant = os.environ.get("MICROG_VARIANT", "Standard") + args.gps_host = os.environ.get("GPS_HOST", "/dev/ttyGPSD") + args.baud_rate = os.environ.get("BAUD_RATE", "9600") if hasattr(args, 'func'): - args_dict = vars(args) helper.check_root() args.func(args) else: helper.check_root() interact() - if __name__ == "__main__": main() diff --git a/package.nix b/package.nix new file mode 100644 index 0000000..07c5519 --- /dev/null +++ b/package.nix @@ -0,0 +1,32 @@ +{ lib, + stdenvNoCC, + lzip, + python3, + makeWrapper }: +let + wrappedPath = lib.makeBinPath [ lzip ]; +in stdenvNoCC.mkDerivation { + name = "waydroid_script"; + + buildInputs = [ + (python3.withPackages(ps: with ps; [ tqdm requests inquirerpy ])) + ]; + + nativeBuildInputs = [ + makeWrapper + ]; + + src = ./.; + + postPatch = '' + patchShebangs main.py + ''; + + installPhase = '' + mkdir -p $out/libexec + cp -r . $out/libexec/waydroid_script + mkdir -p $out/bin + makeShellWrapper $out/libexec/waydroid_script/main.py $out/bin/waydroid_script \ + --prefix PATH : "${wrappedPath}" + ''; +} diff --git a/requirements.txt b/requirements.txt index cf6e127..329890b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ tqdm requests -InquirerPy diff --git a/stuff/microg.py b/stuff/microg.py index 78faf87..933c452 100644 --- a/stuff/microg.py +++ b/stuff/microg.py @@ -36,11 +36,11 @@ class MicroG(General): "6136b383153c2a6797d14fb4d7ca3f97" ], "Minimal": [ - "https://github.com/ayasa520/MinMicroG/releases/download/latest/MinMicroG-Minimal-2.11.1-20230429100521.zip" + "https://github.com/ayasa520/MinMicroG/releases/download/latest/MinMicroG-Minimal-2.11.1-20230429100521.zip", "afb87eb64e7749cfd72c4760d85849da" ], "MinimalIAP": [ - "https://github.com/ayasa520/MinMicroG/releases/download/latest/MinMicroG-MinimalIAP-2.11.1-20230429100556.zip" + "https://github.com/ayasa520/MinMicroG/releases/download/latest/MinMicroG-MinimalIAP-2.11.1-20230429100556.zip", "cc071f4f776cbc16c4c1f707aff1f7fa" ] } diff --git a/stuff/ndk.py b/stuff/ndk.py index d07623f..ac8cc81 100644 --- a/stuff/ndk.py +++ b/stuff/ndk.py @@ -49,4 +49,4 @@ class Ndk(General): Logger.info("Copying libndk library files ...") name = re.findall("([a-zA-Z0-9]+)\.zip", self.dl_link)[0] shutil.copytree(os.path.join(self.extract_to, "vendor_google_proprietary_ndk_translation-prebuilt-" + name, - "prebuilts"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True) \ No newline at end of file + "prebuilts"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True) diff --git a/stuff/nodataperm.py b/stuff/nodataperm.py index 4f140db..8c99b97 100644 --- a/stuff/nodataperm.py +++ b/stuff/nodataperm.py @@ -40,7 +40,7 @@ class Nodataperm(General): self.act_md5 = self.dl_links[android_version][arch][1] def copy(self): - name = re.findall("([a-zA-Z0-9]+)\.zip", self.dl_link)[0] + name = re.findall("([a-zA-Z0-9]+)\\.zip", self.dl_link)[0] extract_path = os.path.join( self.extract_to, f"hack_full_data_permission-{name}") if not container.use_overlayfs(): diff --git a/stuff/smartdock.py b/stuff/smartdock.py index 5b2e8ae..1607747 100644 --- a/stuff/smartdock.py +++ b/stuff/smartdock.py @@ -4,32 +4,34 @@ from stuff.general import General class Smartdock(General): id = "smartdock" - dl_link = "https://f-droid.org/repo/cu.axel.smartdock_1100.apk" + dl_link = "https://f-droid.org/repo/cu.axel.smartdock_1130.apk" partition = "system" dl_file_name = "smartdock.apk" - act_md5 = "f4087d34218eac902a5cca98ee03d215" + act_md5 = "6bfedb959ef5855c3782e8001cb67f86" apply_props = { "qemu.hw.mainkeys" : "1" } skip_extract = True permissions = """ - - - + + + - - - - - - - - - - + + + + + + + + + + + + """ diff --git a/stuff/widevine.py b/stuff/widevine.py index 316a4a5..b400f57 100644 --- a/stuff/widevine.py +++ b/stuff/widevine.py @@ -40,7 +40,7 @@ class Widevine(General): self.act_md5 = self.dl_links[self.arch[0]][android_version][1] def copy(self): - name = re.findall("([a-zA-Z0-9]+)\.zip", self.dl_link)[0] + name = re.findall("([a-zA-Z0-9]+)\\.zip", self.dl_link)[0] Logger.info("Copying widevine library files ...") shutil.copytree(os.path.join(self.extract_to, "vendor_google_proprietary_widevine-prebuilt-"+name, "prebuilts"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True) diff --git a/tools/container.py b/tools/container.py index 7dd2f7c..fae8013 100644 --- a/tools/container.py +++ b/tools/container.py @@ -22,7 +22,7 @@ def use_overlayfs(): 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!") + Logger.error("Cannot locate waydroid config file, reinit waydroid and try again!") sys.exit(1) cfg.read(cfg_file) if "waydroid" not in cfg: @@ -50,4 +50,4 @@ def is_running(): return "Session:\tRUNNING" in run(["waydroid", "status"]).stdout.decode() def upgrade(): - run(["waydroid", "upgrade", "-o"], ignore=r"\[.*\] Stopping container\n\[.*\] Starting container") \ No newline at end of file + run(["waydroid", "upgrade", "-o"], ignore=r"\[.*\] Stopping container\n\[.*\] Starting container") diff --git a/tools/images.py b/tools/images.py index 9d6cd92..ef508fb 100644 --- a/tools/images.py +++ b/tools/images.py @@ -32,7 +32,7 @@ def get_image_dir(): 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!") + Logger.error("Cannot locate waydroid config file, reinit waydroid and try again!") sys.exit(1) cfg.read(cfg_file) if "waydroid" not in cfg: From 3b349b19aa9198a159e0d602a9d6be224a36ee30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=91=E9=9B=84=E9=95=95?= Date: Fri, 11 Jul 2025 14:11:33 +0800 Subject: [PATCH 4/4] Reorder ro.product.cpu.abilist to prioritize 64-bit ABIs --- stuff/ndk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stuff/ndk.py b/stuff/ndk.py index ac8cc81..f513cf4 100644 --- a/stuff/ndk.py +++ b/stuff/ndk.py @@ -14,7 +14,7 @@ class Ndk(General): dl_file_name = "libndktranslation.zip" extract_to = "/tmp/libndkunpack" apply_props = { - "ro.product.cpu.abilist": "x86_64,x86,armeabi-v7a,armeabi,arm64-v8a", + "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": "libndk_translation.so",