Compare commits

..
Author SHA1 Message Date
Mitchel Stewart 38e4fa2794 Readme: fix interactive guide 2023-06-03 06:43:28 -04:00
22 changed files with 179 additions and 413 deletions
-3
View File
@@ -105,7 +105,4 @@ venv.bak/
# mypy
.mypy_cache/
# nix
result*
test.py
+31 -43
View File
@@ -1,6 +1,5 @@
# Waydroid Extras Script
Script to add GApps and other stuff to Waydroid!
Script to add gapps and other stuff to waydroid !
# Installation/Usage
@@ -9,9 +8,8 @@ Script to add GApps and other stuff to Waydroid!
```
git clone https://github.com/casualsnek/waydroid_script
cd waydroid_script
python3 -m venv venv
venv/bin/pip install -r requirements.txt
sudo venv/bin/python3 main.py
sudo python3 -m pip install -r requirements.txt
sudo python main.py
```
![image-20230430013103883](assets/img/README/image-20230430013103883.png)
@@ -24,20 +22,17 @@ sudo venv/bin/python3 main.py
## Command Line
```bash
git clone https://github.com/casualsnek/waydroid_script
cd waydroid_script
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}
# uninstall something
sudo venv/bin/python3 main.py uninstall {gapps, magisk, libndk, libhoudini, nodataperm, smartdock, microg}
# get Android device ID
sudo venv/bin/python3 main.py certified
# some hacks
sudo venv/bin/python3 main.py hack {nodataperm, hidestatusbar}
```
git clone https://github.com/casualsnek/waydroid_script
cd waydroid_script
sudo python3 -m pip install -r requirements.txt
# install something
sudo python3 main.py install {gapps, magisk, libndk, libhoudini, nodataperm, smartdock, microg}
# uninstall something
sudo python3 main.py uninstall {gapps, magisk, libndk, libhoudini, nodataperm, smartdock, microg}
# get Android device ID
sudo python main.py certified
# some hacks
sudo python3 hack {nodataperm, hidestatusbar}
## Dependencies
@@ -55,19 +50,18 @@ sudo venv/bin/python3 main.py hack {nodataperm, hidestatusbar}
![](assets/1.png)
Open terminal and switch to the directory where "main.py" is located then run:
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py install gapps
sudo python3 main.py install gapps
Then launch waydroid with:
waydroid show-full-ui
After waydroid has finished booting, open terminal and switch to directory where "main.py" is located then run:
After waydroid has finished booting open terminal and switch to directory where "main.py" is located then run:
sudo 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!
Copy the returned numeric ID open ["https://google.com/android/uncertified/?pli=1"](https://google.com/android/uncertified/?pli=1) enter the id and register it, you may need to wait upto 10-20 minutes for device to get registered, then clear Google Play Service's cache and try logging in !
## Install Magisk
@@ -75,9 +69,9 @@ Copy the returned numeric ID, then open ["https://google.com/android/uncertified
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py install magisk
sudo python3 main.py install magisk
Magisk will be installed on next boot!
Magisk will be installed on next boot !
Zygisk and modules like LSPosed should work now.
@@ -93,7 +87,7 @@ libndk seems to have better performance than libhoudini on AMD.
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py install libndk
sudo python3 main.py install libndk
## Install libhoudini arm translation
@@ -105,7 +99,7 @@ houdini64 version: 11.0.1b_z.38765.m
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py install libhoudini
sudo python3 main.py install libhoudini
## Integrate Widevine DRM (L3)
@@ -113,7 +107,7 @@ Open terminal and switch to directory where "main.py" is located then run:
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py install widevine
sudo python3 main.py install widevine
## Install Smart Dock
@@ -122,13 +116,7 @@ Open terminal and switch to directory where "main.py" is located then run:
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py install smartdock
## Install a self-signed CA certificate
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py install mitm --ca-cert mycert.pem
sudo python3 main.py install smartdock
## Granting full permission for apps data (HACK)
@@ -142,9 +130,9 @@ Arknights, PUNISHING: GRAY RAVEN and other games won't freeze on the black scree
Open terminal and switch to directory where "main.py" is located then run:
```
sudo venv/bin/python3 main.py hack nodataperm
sudo python3 main.py hack nodataperm
```
**WARNING**: Tested on `lineage-18.1-20230128-VANILLA-waydroid_x86_64.img`. This script will replace `/system/framework/service.jar`, which may prevent WayDroid from booting. If so, run `sudo venv/bin/python3 main.py uninstall nodataperm` to remove it.
**WARNING**: Tested on `lineage-18.1-20230128-VANILLA-waydroid_x86_64.img`. This script will replace `/system/framework/service.jar`, which may prevent WayDroid from booting. If so, run `sudo python3 main.py uninstall nodataperm` to remove it.
Or you can run the following commands directly in `sudo waydroid shell`. In this way, every time a new game is installed, you need to run it again, but it's much less risky.
@@ -166,7 +154,7 @@ chmod 777 -R /mnt/*/*/*/*/Android/obb
![](assets/7.png)
```
sudo venv/bin/python3 main.py install microg
sudo python main.py install microg
```
## Hide Status Bar
@@ -177,18 +165,18 @@ After
![After](assets/9.png)
```
sudo venv/bin/python3 main.py hack hidestatusbar
sudo python3 main.py hack hidestatusbar
```
## Get Android ID for device registration
You need to register you device with its it before being able to use gapps, this will print out your Android ID which you can use for device registration required for Google apps:
You need to register you device with its it before being able to use gapps, this will print out your Android ID which you can use for device registration required for google apps:
Open terminal and switch to directory where "main.py" is located then run:
sudo venv/bin/python3 main.py certified
sudo python3 main.py google
Star this repository if you find this useful, if you encounter problem create an issue on GitHub!
Star this repository if you find this useful, if you encounter problem create a issue on github !
## Error handling
-4
View File
@@ -1,4 +0,0 @@
let
pkgs = import <nixpkgs> {};
in
pkgs.callPackage ./package.nix { }
Generated
-41
View File
@@ -1,41 +0,0 @@
{
"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
}
-21
View File
@@ -1,21 +0,0 @@
{
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;
});
};
}
+8 -22
View File
@@ -12,12 +12,10 @@ from stuff.hidestatusbar import HideStatusBar
from stuff.houdini import Houdini
from stuff.magisk import Magisk
from stuff.microg import MicroG
from stuff.mitm import Mitm
from stuff.ndk import Ndk
from stuff.nodataperm import Nodataperm
from stuff.smartdock import Smartdock
from stuff.widevine import Widevine
from stuff.fdroidpriv import FDroidPriv
import tools.helper as helper
from tools import container
from tools import images
@@ -84,11 +82,7 @@ def install_app(args):
if "smartdock" in app:
install_list.append(Smartdock())
if "microg" in app:
install_list.append(MicroG(args.android_version, args.microg_variant))
if "mitm" in app:
install_list.append(Mitm(args.ca_cert_file))
if "fdroidpriv" in app:
install_list.append(FDroidPriv(args.android_version))
install_list.append(MicroG(args.android_version))
if not container.use_overlayfs():
copy_dir = "/tmp/waydroid"
@@ -136,10 +130,6 @@ def remove_app(args):
remove_list.append(Smartdock())
if "microg" in app:
remove_list.append(MicroG(args.android_version, args.microg_variant))
if "mitm" in app:
remove_list.append(Mitm())
if "fdroidpriv" in app:
remove_list.append(FDroidPriv(args.android_version))
if "nodataperm" in app:
remove_list.append(Nodataperm(args.android_version))
if "hidestatusbar" in app:
@@ -210,7 +200,7 @@ def interact():
Choice(name="Android 13", value="13"),
Choice(name="Exit", value=None)
],
default="13",
default="11",
).execute()
if not android_version:
exit()
@@ -229,9 +219,10 @@ def interact():
if not action:
exit()
install_choices = ["gapps", "microg", "libndk", "libhoudini", "magisk", "smartdock", "fdroidpriv", "widevine",]
install_choices = ["gapps", "microg", "libndk", "magisk", "smartdock",]
hack_choices = []
if android_version=="11":
install_choices.extend(["libhoudini", "widevine"])
hack_choices.extend(["nodataperm", "hidestatusbar"])
if action == "Install":
@@ -244,7 +235,7 @@ def interact():
).execute()
microg_variants = ["Standard", "NoGoolag",
"UNLP", "Minimal", "MinimalIAP"]
if "microg" in apps:
if "MicroG" in apps:
microg_variant = inquirer.select(
message="Select MicroG variant",
choices=microg_variants,
@@ -287,7 +278,7 @@ def main():
parser.add_argument('-a', '--android-version',
dest='android_version',
help='Specify the Android version',
default="13",
default="11",
choices=["11", "13"])
# android command
@@ -295,8 +286,8 @@ def main():
'certified', help='Get device ID to obtain Play Store certification')
certified.set_defaults(func=get_certified)
install_choices = ["gapps", "microg", "libndk", "libhoudini",
"magisk", "mitm", "smartdock", "widevine"]
install_choices = ["gapps", "microg", "libndk",
"libhoudini", "magisk", "smartdock", "widevine"]
hack_choices = ["nodataperm", "hidestatusbar"]
micrg_variants = ["Standard", "NoGoolag", "UNLP", "Minimal", "MinimalIAP"]
remove_choices = install_choices
@@ -314,7 +305,6 @@ microg: Add microG, Aurora Store and Aurora Droid to WayDriod
libndk: Add libndk arm translation, better for AMD CPUs
libhoudini: Add libhoudini arm translation, better for Intel CPUs
magisk: Install Magisk Delta to WayDroid
mitm -c CA_CERT_FILE: Install root CA cert into system trust store
smartdock: A desktop mode launcher for Android
widevine: Add support for widevine DRM L3
"""
@@ -323,10 +313,6 @@ widevine: Add support for widevine DRM L3
'install', formatter_class=argparse.RawTextHelpFormatter, help='Install an app')
install_parser.add_argument(
**arg_template, choices=install_choices, help=install_help)
install_parser.add_argument('-c', '--ca-cert',
dest='ca_cert_file',
help='[for mitm only] The CA certificate file (*.pem) to install',
default=None)
install_parser.set_defaults(func=install_app)
# remove and its aliases
-32
View File
@@ -1,32 +0,0 @@
{ 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}"
'';
}
+1 -1
View File
@@ -14,7 +14,7 @@ class AndroidId:
except:
return
else:
Logger.error("Please make sure Waydroid is running and Gapps has been installed!")
Logger.error("WayDroid isn't running !")
return
print(queryout.replace("android_id|", "").strip())
print(" ^----- Open https://google.com/android/uncertified/?pli=1")
-42
View File
@@ -1,42 +0,0 @@
import os
import shutil
from stuff.general import General
class FDroidPriv(General):
id = "fdroid priv"
dl_links = {"11": ["https://f-droid.org/repo/org.fdroid.fdroid.privileged.ota_2130.zip",
"6242cab56d197d80c598593a46da62e4"],
"13": ["https://f-droid.org/repo/org.fdroid.fdroid.privileged.ota_2130.zip",
"6242cab56d197d80c598593a46da62e4"]}
partition = "system"
dl_file_name = "org.fdroid.fdroid.privileged.ota_2130.zip"
dl_link = ...
act_md5 = ...
extract_to = "/tmp/fdroid_ota_2130"
files = [
"app/F-Droid.apk"
"app/F-Droid/F-Droid.apk"
"etc/permissions/permissions_org.fdroid.fdroid.privileged.xml"
"priv-app/F-DroidPrivilegedExtension.apk"
"priv-app/F-DroidPrivilegedExtension/F-DroidPrivilegedExtension.apk"
]
file_map = {
"permissions_org.fdroid.fdroid.privileged.xml": "etc/permissions/permissions_org.fdroid.fdroid.privileged.xml",
"F-Droid.apk": "app/F-Droid/F-Droid.apk",
"F-DroidPrivilegedExtension.apk": "priv-app/F-DroidPrivilegedExtension/F-DroidPrivilegedExtension.apk",
}
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):
for f, d in self.file_map.items():
rro_file = os.path.join(
self.copy_dir, self.partition, d)
rro_dir = os.path.dirname(rro_file)
if not os.path.exists(rro_dir):
os.makedirs(rro_dir)
shutil.copyfile(os.path.join(self.extract_to, f), rro_file)
+4 -4
View File
@@ -15,10 +15,10 @@ class Gapps(General):
"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/s1204IT/MindTheGappsBuilder/releases/download/20231028/MindTheGapps-13.0.0-x86_64-20231028.zip", "63ccebbf93d45c384f58d7c40049d398"],
"x86": ["https://github.com/s1204IT/MindTheGappsBuilder/releases/download/20231028/MindTheGapps-13.0.0-x86-20231028.zip", "f12b6a8ed14eedbb4b5b3c932a865956"],
"arm64-v8a": ["https://github.com/s1204IT/MindTheGappsBuilder/releases/download/20231028/MindTheGapps-13.0.0-arm64-20231028.zip", "11180da0a5d9f2ed2863882c30a8d556"],
"armeabi-v7a": ["https://github.com/s1204IT/MindTheGappsBuilder/releases/download/20231028/MindTheGapps-13.0.0-arm-20231028.zip", "d525c980bac427844aa4cb01628f8a8f"]
"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 = ...
+2 -2
View File
@@ -73,8 +73,8 @@ class General:
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(os.path.join(os.path.dirname(__file__), "..", "bin",
self.arch[0], "resetprop")), bin_dir)
shutil.copy(os.path.join(
"./bin", self.arch[0], "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:
+2 -2
View File
@@ -5,8 +5,8 @@ from stuff.general import General
class HideStatusBar(General):
id = "hide status bar"
dl_links = {"11": ["https://github.com/ayasa520/hide-status-bar/releases/download/v0.0.2/app-release.apk",
"ff2fe63ddfb4b035e6720a1b195b2355"]}
dl_links = {"11": ["https://github.com/ayasa520/hide-status-bar/releases/download/v0.0.1/app-release.apk",
"ae6c4cc567d6f3de77068e54e43818e2"]}
partition = "system"
dl_file_name = "hidestatusbar.apk"
dl_link = ...
+2 -2
View File
@@ -10,7 +10,7 @@ class Houdini(General):
partition = "system"
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/9e77896350caccd228b36b2e1b4a994aa4bd48da.zip", "3807fe029559db3037efe245d9e74270"]
# "13": ["https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/978d8cba061a08837b7e520cd03b635af643ba08.zip", "1e139054c05034648fae58a1810573b4"]
}
act_md5 = ...
dl_link = ...
@@ -18,7 +18,7 @@ class Houdini(General):
extract_to = "/tmp/houdiniunpack"
init_rc_component = """
on early-init
mount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
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"
+17 -15
View File
@@ -10,7 +10,7 @@ from tools import container
class Magisk(General):
id = "magisk delta"
partition = "system"
dl_link = "https://github.com/mistrmochov/magiskdeltaorig/raw/main/app-release.apk"
dl_link = "https://huskydg.github.io/magisk-files/app-debug.apk"
dl_file_name = "magisk.apk"
extract_to = "/tmp/magisk_unpack"
magisk_dir = os.path.join(partition, "etc", "init", "magisk")
@@ -29,28 +29,30 @@ service bootanim /system/bin/bootanimation
bootanim_component = f"""
on post-fs-data
start logd
exec u:r:su:s0 root root -- /system/etc/init/magisk/magiskpolicy --live --magisk
exec u:r:magisk:s0 root root -- /system/etc/init/magisk/magiskpolicy --live --magisk
exec u:r:update_engine:s0 root root -- /system/etc/init/magisk/magiskpolicy --live --magisk
mkdir /dev/magisk_iqeoVo2mDrO 700
exec u:r:su:s0 root root -- /system/etc/init/magisk/magisk64 --auto-selinux --setup-sbin /system/etc/init/magisk /dev/magisk_iqeoVo2mDrO
exec u:r:su:s0 root root -- /dev/magisk_iqeoVo2mDrO/magisk --auto-selinux --post-fs-data
exec u:r:su:s0 root root -- /system/etc/init/magisk/magisk{host()[1]} --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 nonencrypted
exec u:r:su:s0 root root -- /dev/magisk_iqeoVo2mDrO/magisk --auto-selinux --service
on property:vold.decrypt=trigger_restart_framework
exec u:r:su:s0 root root -- /dev/magisk_iqeoVo2mDrO/magisk --auto-selinux --service
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 -- /dev/magisk_iqeoVo2mDrO/magisk --auto-selinux --boot-complete
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 -- /dev/magisk_iqeoVo2mDrO/magisk --auto-selinux --zygote-restart
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 -- /dev/magisk_iqeoVo2mDrO/magisk --auto-selinux --zygote-restart
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --zygote-restart
"""
def download(self):
-40
View File
@@ -1,40 +0,0 @@
import os
import shutil
from stuff.general import General
from tools.helper import run
from tools.logger import Logger
class Mitm(General):
id = "mitm"
partition = "system"
def __init__(self, ca_cert_file: str=None) -> None:
super().__init__()
self.ca_cert_file = ca_cert_file
def download(self):
pass
def skip_extract(self):
return True
def copy(self):
file_hash = run([
'openssl', 'x509', '-noout', '-subject_hash_old', '-in',
self.ca_cert_file,
]).stdout.decode("ascii").strip()
target_dir = os.path.join(
self.copy_dir, self.partition, "etc", "security", "cacerts")
Logger.info(f"Creating directory: {target_dir}")
os.makedirs(target_dir, exist_ok=True)
target_path = os.path.join(target_dir, f'{file_hash}.0')
Logger.info(f"Copying {self.ca_cert_file} to system trust store")
Logger.info(f"Target file: {target_path}")
shutil.copyfile(self.ca_cert_file, target_path)
os.chmod(target_path, 0o644)
def install(self):
if not self.ca_cert_file:
raise ValueError(
"This command requires the --ca-cert switch and a *.pem file")
super().install()
+2 -2
View File
@@ -9,12 +9,12 @@ class Ndk(General):
partition = "system"
dl_links = {
"11": ["https://github.com/supremegamers/vendor_google_proprietary_ndk_translation-prebuilt/archive/9324a8914b649b885dad6f2bfd14a67e5d1520bf.zip", "c9572672d1045594448068079b34c350"],
"13": ["https://github.com/supremegamers/vendor_google_proprietary_ndk_translation-prebuilt/archive/68734c52556d3d7a6db34c603dd9276915c29f2f.zip", "0b2207c490fcb400aa5c87fcf0d52d38"]
"13": ["https://github.com/supremegamers/vendor_google_proprietary_ndk_translation-prebuilt/archive/a090003c60df53a9eadb2df09bd4fd2fa86ea629.zip", "e6f0d9fc28ebc427b59a3942a9a4ffc0"]
}
dl_file_name = "libndktranslation.zip"
extract_to = "/tmp/libndkunpack"
apply_props = {
"ro.product.cpu.abilist": "x86_64,x86,arm64-v8a,armeabi-v7a,armeabi",
"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",
+19 -45
View File
@@ -1,8 +1,7 @@
import gzip
import os
import re
import shutil
from stuff.general import General
from tools.helper import backup, restore
from tools.logger import Logger
from tools import container
@@ -10,59 +9,37 @@ from tools import container
class Nodataperm(General):
id = "nodataperm"
dl_links = {
"11": {
"x86_64": [
"https://github.com/ayasa520/hack_full_data_permission/archive/d4beab7780eb792059d33e77d865579c9ee41546.zip",
"b0e3908ffcf5df8ea62f4929aa680f1a"
],
},
"13": {
"x86_64": [
"https://github.com/ayasa520/hack_full_data_permission/archive/d4beab7780eb792059d33e77d865579c9ee41546.zip",
"b0e3908ffcf5df8ea62f4929aa680f1a"
],
},
"11": ["https://github.com/ayasa520/hack_full_data_permission/archive/refs/heads/main.zip",
"eafd7b0986f3edaebaf1dd89f19d49bf"],
"13": ["", ""]
}
dl_file_name = "nodataperm.zip"
extract_to = "/tmp/nodataperm"
dl_link = None
act_md5 = None
dl_link = ...
act_md5 = ...
partition = "system"
files = [
"etc/nodataperm.sh",
"etc/init/nodataperm.rc",
"framework/services.jar",
"framework/services.jar.prof",
"framework/services.jar.bprof",
"framework/services.jar"
]
def __init__(self, android_version="11") -> None:
super().__init__()
print("ok")
arch = self.arch[0]
if android_version not in self.dl_links:
raise KeyError(f"No download links for Android version '{android_version}'")
if arch not in self.dl_links[android_version]:
raise KeyError(f"No download links for architecture '{arch}' in Android version '{android_version}'")
self.dl_link = self.dl_links[android_version][arch][0]
self.act_md5 = self.dl_links[android_version][arch][1]
self.dl_link = self.dl_links[android_version][0]
self.act_md5 = self.dl_links[android_version][1]
def copy(self):
name = re.findall(r"([a-zA-Z0-9]+)\.zip", self.dl_link)[0]
extract_path = os.path.join(
self.extract_to, f"hack_full_data_permission-{name}")
self.extract_to, "hack_full_data_permission-main")
if not container.use_overlayfs():
services_jar = os.path.join(
self.copy_dir, self.partition, "framework", "services.jar")
services_jar_prof = os.path.join(
self.copy_dir, self.partition, "framework", "services.jar.prof")
services_jar_bprof = os.path.join(
self.copy_dir, self.partition, "framework", "services.jar.bprof")
backup(services_jar)
backup(services_jar_prof)
backup(services_jar_bprof)
Logger.info(f"Copying {self.id} library files ...")
gz_filename = services_jar+".gz"
with gzip.open(gz_filename, 'wb') as f_gz:
with open(services_jar, "rb") as f:
f_gz.write(f.read())
Logger.info("Copying widevine library files ...")
shutil.copytree(extract_path, os.path.join(
self.copy_dir, self.partition), dirs_exist_ok=True)
@@ -70,10 +47,7 @@ class Nodataperm(General):
if not container.use_overlayfs():
services_jar = os.path.join(
self.copy_dir, self.partition, "framework", "services.jar")
services_jar_prof = os.path.join(
self.copy_dir, self.partition, "framework", "services.jar.prof")
services_jar_bprof = os.path.join(
self.copy_dir, self.partition, "framework", "services.jar.bprof")
restore(services_jar)
restore(services_jar_prof)
restore(services_jar_bprof)
gz_filename = services_jar+".gz"
with gzip.GzipFile(gz_filename) as f_gz:
with open(services_jar, "wb") as f:
f.writelines(f_gz)
+2 -2
View File
@@ -4,10 +4,10 @@ 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_198.apk"
partition = "system"
dl_file_name = "smartdock.apk"
act_md5 = "f4087d34218eac902a5cca98ee03d215"
act_md5 = "a8ce0bca5e1772796404602e0fa250a4"
apply_props = { "qemu.hw.mainkeys" : "1" }
skip_extract = True
permissions = """<?xml version="1.0" encoding="utf-8"?>
+2 -13
View File
@@ -13,8 +13,8 @@ class Widevine(General):
"x86_64": {
"11": ["https://github.com/supremegamers/vendor_google_proprietary_widevine-prebuilt/archive/48d1076a570837be6cdce8252d5d143363e37cc1.zip",
"f587b8859f9071da4bca6cea1b9bed6a"],
"13": ["https://github.com/WayDroid-ATV/vendor_google_proprietary_widevine-prebuilt/archive/679552343d8b2e8d7a19b6df61c7a03963d0c75b.zip",
"80ab79ea85c7b2556baedb371a54e01c"]
"13": ["https://github.com/supremegamers/vendor_google_proprietary_widevine-prebuilt/archive/a8524d608431573ef1c9313822d271f78728f9a6.zip",
"5c55df61da5c012b4e43746547ab730f"]
},
# "armeabi-v7a": ["https://github.com/supremegamers/vendor_google_proprietary_widevine-prebuilt/archive/a1a19361d36311bee042da8cf4ced798d2c76d98.zip", "fed6898b5cfd2a908cb134df97802554"],
"arm64-v8a": {
@@ -30,10 +30,7 @@ class Widevine(General):
"etc/init/*widevine.rc",
"etc/vintf/manifest/*widevine.xml",
"lib/libwvhidl.so",
"lib/libwvaidl.so",
"lib/mediadrm",
"lib64/libwvhidl.so",
"lib64/libwvaidl.so",
"lib64/mediadrm"
]
@@ -41,17 +38,9 @@ class Widevine(General):
super().__init__()
self.dl_link = self.dl_links[self.arch[0]][android_version][0]
self.act_md5 = self.dl_links[self.arch[0]][android_version][1]
self.android_version = android_version
self.libdir = "lib64" if self.arch[1] == 64 else "lib"
def copy(self):
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)
if self.android_version == "13":
try:
os.symlink("libprotobuf-cpp-lite-3.9.1.so",
os.path.join(self.copy_dir, self.partition, self.libdir, "libprotobuf-cpp-lite.so"))
except FileExistsError:
pass
+24 -4
View File
@@ -1,9 +1,23 @@
import configparser
import os
import sys
# import dbus
from tools.helper import run
from tools.logger import Logger
# 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 use_dbus():
# try:
# DBusContainerService()
# except:
# return False
# return True
def use_overlayfs():
cfg = configparser.ConfigParser()
cfg_file = os.environ.get("WAYDROID_CONFIG", "/var/lib/waydroid/waydroid.cfg")
@@ -20,14 +34,20 @@ def use_overlayfs():
return False
# def get_session():
# return DBusContainerService().GetSession()
def stop():
# if use_dbus():
# session = DBusContainerService().GetSession()
# if session:
# DBusContainerService().Stop(False)
# else:
run(["waydroid", "container", "stop"])
def is_running():
return "Session:\tRUNNING" in run(["waydroid", "status"]).stdout.decode()
def upgrade():
try:
run(["waydroid", "upgrade"], ignore=r"\[.*\] Stopping container\n\[.*\] Starting container")
except subprocess.CalledProcessError:
Logger.warning("Waydroid upgrade reported an error (likely system_ota), but we are continuing...")
run(["waydroid", "upgrade", "-o"], ignore=r"\[.*\] Stopping container\n\[.*\] Starting container")
+55 -66
View File
@@ -1,7 +1,7 @@
import gzip
import os
import re
import platform
import re
import subprocess
import sys
import requests
@@ -10,24 +10,27 @@ from tqdm import tqdm
import hashlib
from typing import Optional
def get_download_dir():
if os.environ.get("XDG_CACHE_HOME"):
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"
)
else:
user = os.environ.get("SUDO_USER", os.environ.get("USER", "root"))
download_loc = os.path.join("/", "home", user, ".cache", "waydroid-script", "downloads")
if not os.path.exists(download_loc):
os.makedirs(download_loc, exist_ok=True)
os.makedirs(download_loc)
return download_loc
# not good
def get_data_dir():
user = os.environ.get("SUDO_USER", os.environ.get("USER", "root"))
return os.path.join("/", "home", user, ".local", "share", "waydroid", "data")
return os.path.join('/', "home", os.environ.get("SUDO_USER", os.environ["USER"]), ".local", "share", "waydroid", "data")
def run(args: list, env: Optional[dict] = None, ignore: Optional[str] = None):
# execute on host
def run(args: list, env: Optional[str] = None, ignore: Optional[str] = None):
result = subprocess.run(
args=args,
env=env,
@@ -35,12 +38,11 @@ def run(args: list, env: Optional[dict] = None, ignore: Optional[str] = None):
stderr=subprocess.PIPE
)
# print(result.stdout.decode())
if result.stderr:
error = result.stderr.decode("utf-8").strip()
if (ignore and re.search(ignore, error)) or "system_ota" in error:
error = result.stderr.decode("utf-8")
if ignore and re.match(ignore, error):
return result
Logger.error(error)
raise subprocess.CalledProcessError(
returncode=result.returncode,
@@ -49,58 +51,64 @@ def run(args: list, env: Optional[dict] = None, ignore: Optional[str] = None):
)
return result
# execute on waydroid shell
def shell(arg: str, env: Optional[str] = None):
cmd = ["sudo", "waydroid", "shell"]
process = subprocess.Popen(
args=cmd,
a = subprocess.Popen(
args=["sudo", "waydroid", "shell"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
stderr=subprocess.PIPE
)
subprocess.Popen(
args=["echo", "export BOOTCLASSPATH=/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar"],
stdout=a.stdin,
stdin=subprocess.PIPE
).communicate()
boot_classpath = "export BOOTCLASSPATH=/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar"
full_script = f"{boot_classpath}\n"
if env:
full_script += f"{env}\n"
full_script += f"{arg}\n"
subprocess.Popen(
args=["echo", env],
stdout=a.stdin,
stdin=subprocess.PIPE
).communicate()
stdout, stderr = process.communicate(input=full_script)
subprocess.Popen(
args=["echo", arg],
stdout=a.stdin,
stdin=subprocess.PIPE
).communicate()
if process.returncode != 0 and stderr:
Logger.error(stderr.strip())
a.stdin.close()
if a.stderr.read():
Logger.error(a.stderr.read().decode('utf-8'))
raise subprocess.CalledProcessError(
returncode=process.returncode,
cmd=cmd,
stderr=stderr.encode()
returncode=a.returncode,
cmd=a.args,
stderr=a.stderr
)
return stdout
return a.stdout.read().decode("utf-8")
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
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()
hash_md5 = hashlib.md5()
with open(f_name, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
bytes = f.read()
md5 = hashlib.md5(bytes).hexdigest()
if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes:
raise ValueError("Download incomplete or corrupted")
return hash_md5.hexdigest()
raise ValueError("Something went wrong while downloading")
return md5
def host():
machine = platform.machine()
mapping = {
"i686": ("x86", 32),
"x86_64": ("x86_64", 64),
@@ -108,37 +116,18 @@ def host():
"armv7l": ("armeabi-v7a", 32),
"armv8l": ("armeabi-v7a", 32)
}
if machine in mapping:
if machine == "x86_64":
try:
with open("/proc/cpuinfo", "r") as f:
if mapping[machine] == "x86_64":
with open("/proc/cpuinfo") as f:
if "sse4_2" not in f.read():
Logger.warning("CPU does not support SSE4.2, falling back to x86...")
Logger.warning("x86_64 CPU does not support SSE4.2, falling back to x86...")
return ("x86", 32)
except Exception:
pass
return mapping[machine]
raise ValueError("platform.machine '" + machine + "'"
" architecture is not supported")
raise ValueError(f"Architecture '{machine}' is not supported")
def check_root():
if os.geteuid() != 0:
Logger.error("This script must be run as root (sudo). Aborting.")
Logger.error("This script must be run as root. Aborting.")
sys.exit(1)
def backup(path):
if not os.path.exists(path):
return
gz_filename = path + ".gz"
with open(path, "rb") as f_in:
with gzip.open(gz_filename, "wb") as f_out:
f_out.writelines(f_in)
def restore(path):
gz_filename = path + ".gz"
if not os.path.exists(gz_filename):
return
with gzip.open(gz_filename, "rb") as f_in:
with open(path, "wb") as f_out:
f_out.write(f_in.read())
+2 -1
View File
@@ -28,6 +28,7 @@ def resize(img_file, size):
run(["sudo", "resize2fs", img_file, size], ignore="^resize2fs \d+\.\d+\.\d (.+)\n$")
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):
@@ -35,6 +36,6 @@ def get_image_dir():
sys.exit(1)
cfg.read(cfg_file)
if "waydroid" not in cfg:
Logger.error("Required entry in config was not found, Cannot continue!")
Logger.error("Required entry in config was not found, Cannot continue!") #magisk
sys.exit(1)
return cfg["waydroid"]["images_path"]