mirror of
https://github.com/ayasa520/redroid-script.git
synced 2026-02-24 16:35:08 +08:00
init
This commit is contained in:
111
.gitignore
vendored
Normal file
111
.gitignore
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
git
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# 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/
|
||||
|
||||
gapps
|
||||
magisk
|
||||
ndk
|
||||
widevine
|
||||
houdini
|
||||
4
Dockerfile
Normal file
4
Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM redroid/redroid:11.0.0-latest
|
||||
COPY gapps /
|
||||
COPY ndk /
|
||||
COPY magisk /
|
||||
7
LICENSE
Normal file
7
LICENSE
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright © 2023 <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
80
README.md
Normal file
80
README.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Remote-Android Script
|
||||
|
||||
This script adds Gapps, Magisk and libndk to redroid **without recompiling the entire image**
|
||||
|
||||
## Specify an Android version
|
||||
|
||||
Use `-a` or `--android-version` to specify the Android version of the image being pulled. The value can be `8.1.0`, `9.0.0`, `10.0.0`, `11.0.0`, `12.0.0` or `13.0.0`. The default is 11.0.0.
|
||||
|
||||
```bash
|
||||
# pull the latest image
|
||||
python redroid.py -a 11.0.0
|
||||
```
|
||||
|
||||
## Add OpenGapps to ReDroid image
|
||||
|
||||
<img src="./assets/3.png" style="zoom:50%;" />
|
||||
|
||||
```bash
|
||||
python redroid.py -g
|
||||
```
|
||||
|
||||
## Add libndk arm translation to ReDroid image
|
||||
<img src="./assets/2.png" style="zoom:50%;" />
|
||||
|
||||
libndk_translation from guybrush firmware.
|
||||
|
||||
libndk seems to have better performance than libhoudini on AMD.
|
||||
|
||||
```bash
|
||||
python redroid.py -n
|
||||
```
|
||||
|
||||
## Add Magisk to ReDroid image
|
||||
<img src="./assets/1.png" style="zoom:50%;" />
|
||||
|
||||
Zygisk and modules like LSPosed should work.
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
python redroid.py -m
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
This command will add Gapps, Magisk and Libndk to the ReDroid image at the same time.
|
||||
|
||||
```bash
|
||||
python redroid.py -a 11.0.0 -gmn
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Magisk installed: N/A
|
||||
|
||||
According to some feedback from WayDroid users, changing the kernel may solve this issue. https://t.me/WayDroid/126202
|
||||
|
||||
- The device isn't Play Protect certified
|
||||
1. Run below command on host
|
||||
```
|
||||
adb root
|
||||
adb shell 'sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \
|
||||
"select * from main where name = \"android_id\";"'
|
||||
```
|
||||
|
||||
2. Grab device id and register on this website: https://www.google.com/android/uncertified/
|
||||
|
||||
- libndk doesn't work
|
||||
|
||||
I only made it work on `redroid/redroid:11.0.0`. Also, turning on Zygisk seems to break libndk.
|
||||
|
||||
- libhoudini doesn't work
|
||||
|
||||
I have no idea. I can't get any version of libhoudini to work on redroid.
|
||||
|
||||
|
||||
## Credits
|
||||
1. [waydroid_script](https://github.com/casualsnek/waydroid_script)
|
||||
2. [Magisk Delta](https://huskydg.github.io/magisk-files/)
|
||||
3. [vendor_intel_proprietary_houdini](https://github.com/supremegamers/vendor_intel_proprietary_houdini)
|
||||
BIN
assets/1.png
Normal file
BIN
assets/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
BIN
assets/2.png
Normal file
BIN
assets/2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 348 KiB |
BIN
assets/3.png
Normal file
BIN
assets/3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 364 KiB |
85
redroid.py
Normal file
85
redroid.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from io import BytesIO
|
||||
import argparse
|
||||
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
|
||||
import docker
|
||||
|
||||
|
||||
def main():
|
||||
dockerfile = ""
|
||||
tags = []
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument('-a', '--android-version',
|
||||
dest='android',
|
||||
help='Specify the Android version to build',
|
||||
default='11.0.0',
|
||||
choices=['13.0.0', '12.0.0', '11.0.0', '10.0.0', '9.0.0', '8.1.0'])
|
||||
parser.add_argument('-g', '--install-gapps',
|
||||
dest='gapps',
|
||||
help='Install OpenGapps to ReDroid',
|
||||
action='store_true')
|
||||
parser.add_argument('-n', '--install-ndk-translation',
|
||||
dest='ndk',
|
||||
help='Install libndk translation files',
|
||||
action='store_true')
|
||||
parser.add_argument('-m', '--install-magisk', dest='magisk',
|
||||
help='Install Magisk ( Bootless )',
|
||||
action='store_true')
|
||||
# Not working
|
||||
# parser.add_argument('-h', '--install-libhoudini', dest='houdini',
|
||||
# help='Install libhoudini for arm translation',
|
||||
# action='store_true')
|
||||
# Not working
|
||||
# parser.add_argument('-w', '--install-widevine', dest='widevine',
|
||||
# help='Integrate Widevine DRM (L3)',
|
||||
# action='store_true')
|
||||
|
||||
args = parser.parse_args()
|
||||
dockerfile = dockerfile + \
|
||||
"FROM redroid/redroid:{}-latest\n".format(
|
||||
args.android)
|
||||
tags.append(args.android)
|
||||
if args.gapps:
|
||||
Gapps().install()
|
||||
dockerfile = dockerfile + "COPY gapps /\n"
|
||||
tags.append("gapps")
|
||||
# if args.ndk and not args.houdini:
|
||||
if args.ndk:
|
||||
if args.android == "11.0.0":
|
||||
arch = helper.host()[0]
|
||||
if arch == "x86" or arch == "x86_64":
|
||||
Ndk().install()
|
||||
dockerfile = dockerfile+"COPY ndk /\n"
|
||||
tags.append("ndk")
|
||||
else:
|
||||
helper.print_color(
|
||||
"WARNING: Libndk seems to work only on redroid:11.0.0", helper.bcolors.YELLOW)
|
||||
# if args.houdini and not args.installndk:
|
||||
# arch = helper.host()[0]
|
||||
# if arch == "x86" or arch == "x86_64":
|
||||
# Houdini(args.android).install()
|
||||
# dockerfile = dockerfile+"COPY houdini /\n"
|
||||
if args.magisk:
|
||||
Magisk().install()
|
||||
dockerfile = dockerfile+"COPY magisk /\n"
|
||||
tags.append("magisk")
|
||||
# if args.widevine:
|
||||
# Widevine().install()
|
||||
# dockerfile = dockerfile+"COPY widevine /\n"
|
||||
print("\nDockerfile\n"+dockerfile)
|
||||
with open("./Dockerfile", "w") as f:
|
||||
f.write(dockerfile)
|
||||
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
|
||||
new_image_name = "redroid/redroid:"+"-".join(tags)
|
||||
client.images.build(path="/home/rikka/redroid-script",
|
||||
dockerfile="Dockerfile",
|
||||
tag=new_image_name)
|
||||
helper.print_color("Successfully built {}".format(new_image_name), helper.bcolors.GREEN)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
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 get_download_dir, host, print_color, run, bcolors
|
||||
|
||||
class Gapps(General):
|
||||
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()
|
||||
download_loc = get_download_dir()
|
||||
dl_link = dl_links[arch[0]][0]
|
||||
dl_file_name = os.path.join(download_loc, "open_gapps.zip")
|
||||
act_md5 = dl_links[arch[0]][1]
|
||||
sys_image_mount = "./gapps"
|
||||
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):
|
||||
print_color("Downloading OpenGapps now .....", bcolors.GREEN)
|
||||
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.sys_image_mount, "system", "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.sys_image_mount, "system", ccdir), dirs_exist_ok=True)
|
||||
34
stuffs/general.py
Normal file
34
stuffs/general.py
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
import os
|
||||
import zipfile
|
||||
import hashlib
|
||||
|
||||
from tools.helper import bcolors, download_file, print_color
|
||||
|
||||
class General:
|
||||
def download(self):
|
||||
loc_md5 = ""
|
||||
if os.path.isfile(self.dl_file_name):
|
||||
with open(self.dl_file_name,"rb") as f:
|
||||
bytes = f.read()
|
||||
loc_md5 = hashlib.md5(bytes).hexdigest()
|
||||
while not os.path.isfile(self.dl_file_name) or loc_md5 != self.act_md5:
|
||||
if os.path.isfile(self.dl_file_name):
|
||||
os.remove(self.dl_file_name)
|
||||
print_color("md5 mismatches, redownloading now ....",bcolors.YELLOW)
|
||||
loc_md5 = download_file(self.dl_link, self.dl_file_name)
|
||||
|
||||
def extract(self):
|
||||
print_color("Extracting archive...", bcolors.GREEN)
|
||||
print(self.dl_file_name)
|
||||
print(self.extract_to)
|
||||
with zipfile.ZipFile(self.dl_file_name) as z:
|
||||
z.extractall(self.extract_to)
|
||||
def copy(self):
|
||||
pass
|
||||
def install(self):
|
||||
# pass
|
||||
self.download()
|
||||
self.extract()
|
||||
self.copy()
|
||||
53
stuffs/houdini.py
Normal file
53
stuffs/houdini.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from stuffs.general import General
|
||||
from tools.helper import bcolors, get_download_dir, print_color, run
|
||||
|
||||
|
||||
class Houdini(General):
|
||||
download_loc = get_download_dir()
|
||||
sys_image_mount = "./houdini"
|
||||
dl_links = {
|
||||
"11.0.0": [
|
||||
"https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/81f2a51ef539a35aead396ab7fce2adf89f46e88.zip",
|
||||
"fbff756612b4144797fbc99eadcb6653"],
|
||||
"12.0.0": [
|
||||
"https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/0e0164611d5fe5595229854759c30a9b5c1199a5.zip",
|
||||
"9709701b44b6ab7fc311c7dc95945bd0"],
|
||||
"13.0.0": [
|
||||
"https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/978d8cba061a08837b7e520cd03b635af643ba08.zip",
|
||||
"1e139054c05034648fae58a1810573b4"
|
||||
],
|
||||
# "9.0.0":[],
|
||||
# "8.1.0":[]
|
||||
}
|
||||
dl_file_name = os.path.join(download_loc, "libhoudini.zip")
|
||||
extract_to = "/tmp/houdiniunpack"
|
||||
|
||||
def __init__(self, version):
|
||||
self.version = version
|
||||
if version in self.dl_links.keys():
|
||||
self.dl_link = self.dl_links[version][0]
|
||||
self.act_md5 = self.dl_links[version][1]
|
||||
else:
|
||||
raise ValueError(
|
||||
"No available libhoudini for Android {}".format(version))
|
||||
|
||||
def download(self):
|
||||
print_color("Downloading libhoudini now .....", bcolors.GREEN)
|
||||
super().download()
|
||||
|
||||
def copy(self):
|
||||
run(["chmod", "+x", self.extract_to, "-R"])
|
||||
|
||||
print_color("Copying libhoudini library files ...", bcolors.GREEN)
|
||||
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.sys_image_mount, "vendor"), dirs_exist_ok=True)
|
||||
|
||||
init_path = os.path.join(self.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)
|
||||
with open(init_path, "w") as initfile:
|
||||
initfile.write(self.init_rc_component)
|
||||
101
stuffs/magisk.py
Normal file
101
stuffs/magisk.py
Normal file
@@ -0,0 +1,101 @@
|
||||
import gzip
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
from stuffs.general import General
|
||||
from tools.helper import bcolors, download_file, host, print_color, run, get_download_dir
|
||||
|
||||
class Magisk(General):
|
||||
download_loc = get_download_dir()
|
||||
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 = "./magisk"
|
||||
magisk_dir = os.path.join(sys_overlay_dir, "system", "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
|
||||
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])
|
||||
|
||||
def download(self):
|
||||
if os.path.isfile(self.dl_file_name):
|
||||
os.remove(self.dl_file_name)
|
||||
print_color("Downloading latest Magisk-Delta now .....", bcolors.GREEN)
|
||||
download_file(self.dl_link, self.dl_file_name)
|
||||
|
||||
def copy(self):
|
||||
if not os.path.exists(self.magisk_dir):
|
||||
os.makedirs(self.magisk_dir, exist_ok=True)
|
||||
|
||||
if not os.path.exists(os.path.join(self.sys_overlay_dir, "sbin")):
|
||||
os.makedirs(os.path.join(self.sys_overlay_dir, "sbin"), exist_ok=True)
|
||||
|
||||
print_color("Copying magisk libs now ...", bcolors.GREEN)
|
||||
|
||||
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(self.magisk_dir, filename.group(1))
|
||||
shutil.copyfile(o_path, n_path)
|
||||
run(["chmod", "+x", n_path])
|
||||
shutil.copyfile(self.dl_file_name, os.path.join(self.magisk_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.sys_overlay_dir, "system", "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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
39
stuffs/ndk.py
Normal file
39
stuffs/ndk.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
import shutil
|
||||
from stuffs.general import General
|
||||
from tools.helper import bcolors, get_download_dir, print_color, run
|
||||
|
||||
class Ndk(General):
|
||||
download_loc = get_download_dir()
|
||||
sys_image_mount = "./ndk"
|
||||
dl_link = "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"
|
||||
act_md5 = "4456fc1002dc78e544e8d9721bb24398"
|
||||
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):
|
||||
print_color("Downloading libndk now .....", bcolors.GREEN)
|
||||
super().download()
|
||||
|
||||
def copy(self):
|
||||
run(["chmod", "+x", self.extract_to, "-R"])
|
||||
|
||||
print_color("Copying libndk library files ...", bcolors.GREEN)
|
||||
shutil.copytree(os.path.join(self.extract_to, "libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3", "system"), os.path.join(self.sys_image_mount, "system"), dirs_exist_ok=True)
|
||||
|
||||
init_path = os.path.join(self.sys_image_mount, "system", "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 bcolors, get_download_dir, print_color, run
|
||||
|
||||
|
||||
class Widevine(General):
|
||||
download_loc = get_download_dir()
|
||||
vendor_image_mount = "./widevine"
|
||||
dl_link = "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"
|
||||
act_md5 = "a31f325453c5d239c21ecab8cfdbd878"
|
||||
|
||||
def download(self):
|
||||
print_color("Downloading widevine now .....", bcolors.GREEN)
|
||||
super().download()
|
||||
|
||||
def copy(self):
|
||||
run(["chmod", "+x", self.extract_to, "-R"])
|
||||
print_color("Copying widevine library files ...", bcolors.GREEN)
|
||||
shutil.copytree(os.path.join(self.extract_to, "vendor_google_proprietary_widevine-prebuilt-94c9ee172e3d78fecc81863f50a59e3646f7a2bd",
|
||||
"prebuilts"), os.path.join(self.vendor_image_mount, "vendor"), dirs_exist_ok=True)
|
||||
74
tools/helper.py
Normal file
74
tools/helper.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import requests
|
||||
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", "redroid", "downloads")
|
||||
else:
|
||||
download_loc = os.path.join(os.environ["XDG_CACHE_HOME"], "redroid", "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)
|
||||
if result.stderr:
|
||||
print(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, proxies={"https":"127.0.0.1:7890"})
|
||||
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():
|
||||
# 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")
|
||||
|
||||
class bcolors:
|
||||
RED = '\033[31m'
|
||||
YELLOW = '\033[33m'
|
||||
GREEN = '\033[32m'
|
||||
ENDC = '\033[0m'
|
||||
|
||||
def print_color(str, color):
|
||||
print(color+str+bcolors.ENDC)
|
||||
Reference in New Issue
Block a user