2021-10-02 13:15:41 -07:00
import configparser
import sys
import os
import hashlib
import shutil
import zipfile
import subprocess
import argparse
import platform
from tqdm import tqdm
import requests
import re
2023-01-01 09:02:57 -08:00
import gzip
2021-10-02 13:15:41 -07:00
2022-01-17 05:33:08 -08:00
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 :
2022-11-11 00:03:02 -08:00
download_loc = os . path . join ( os . environ [ " XDG_CACHE_HOME " ] , " waydroid_script " , " downloads " )
2022-12-31 03:25:59 -08:00
2022-01-17 05:33:08 -08:00
print ( download_loc )
if not os . path . exists ( download_loc ) :
os . makedirs ( download_loc )
2021-10-02 13:15:41 -07:00
def stop_waydroid ( ) :
print ( " ==> Stopping waydroid and unmounting already mounted images... " )
os . system ( " waydroid container stop &> /dev/null " )
os . system ( " umount /var/lib/waydroid/rootfs/vendor/waydroid.prop &> /dev/null " )
os . system ( " umount /var/lib/waydroid/rootfs/vendor &> /dev/null " )
os . system ( " umount /var/lib/waydroid/rootfs &> /dev/null " )
2021-10-05 08:23:04 -07:00
def download_file ( url , f_name ) :
md5 = " "
2022-12-31 05:50:21 -08:00
response = requests . get ( url , stream = True )
2021-10-05 08:23:04 -07:00
total_size_in_bytes = int ( response . headers . get ( ' content-length ' , 0 ) )
block_size = 1024 # 1 Kibibyte
progress_bar = tqdm ( total = total_size_in_bytes , unit = ' iB ' , unit_scale = True )
with open ( f_name , ' wb ' ) as file :
for data in response . iter_content ( block_size ) :
progress_bar . update ( len ( data ) )
file . write ( data )
progress_bar . close ( )
with open ( f_name , " rb " ) as f :
bytes = f . read ( )
md5 = hashlib . md5 ( bytes ) . hexdigest ( )
if total_size_in_bytes != 0 and progress_bar . n != total_size_in_bytes :
print ( " ==> Something went wrong while downloading " )
sys . exit ( 1 )
return md5
2021-10-02 13:15:41 -07:00
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 ) :
print ( " ==> Cannot locate waydroid config file, reinit wayland and try again ! " )
sys . exit ( 1 )
cfg . read ( cfg_file )
if " waydroid " not in cfg :
2022-12-31 03:25:59 -08:00
print ( " ==> Required entry in config was not found, Cannot continue !s " ) #magisk
2021-10-02 13:15:41 -07:00
sys . exit ( 1 )
return cfg [ " waydroid " ] [ " images_path " ]
def install_gapps ( ) :
dl_links = {
2022-01-21 23:10:45 -08:00
" x86_64 " : [ " https://master.dl.sourceforge.net/project/opengapps/x86_64/20220121/open_gapps-x86_64-10.0-pico-20220121.zip?viasf=1 " , " e8c9a7412f5712eea7948957a62a7d66 " ] ,
" x86 " : [ " https://udomain.dl.sourceforge.net/project/opengapps/x86/20220122/open_gapps-x86-10.0-pico-20220122.zip " , " 9e39e45584b7ade4529e6be654af7b81 " ] ,
" aarch64 " : [ " https://liquidtelecom.dl.sourceforge.net/project/opengapps/arm64/20220122/open_gapps-arm64-10.0-pico-20220122.zip " , " 8dfa6e76aeb2d1d5aed40b058e8a852c " ] ,
" arm " : [ " https://nav.dl.sourceforge.net/project/opengapps/arm/20220122/open_gapps-arm-10.0-pico-20220122.zip " , " a48ccbd25eb0a3c5e30f5db5435f5536 " ]
2021-10-02 13:15:41 -07:00
}
if platform . machine ( ) not in dl_links . keys ( ) :
print ( " ==> Unsupported architecture ' {} ' .. " . format ( platform . machine ( ) ) )
sys . exit ( 1 )
2021-10-05 08:23:04 -07:00
google_apps_dl_link = dl_links [ platform . machine ( ) ] [ 0 ]
2022-01-17 05:33:08 -08:00
dl_file_name = os . path . join ( download_loc , " open_gapps.zip " )
2021-10-02 13:15:41 -07:00
act_md5 = dl_links [ platform . machine ( ) ] [ 1 ]
loc_md5 = " "
2022-11-14 18:08:22 -08:00
sys_image_mount = " /var/lib/waydroid/overlay "
2021-10-02 13:15:41 -07:00
extract_to = " /tmp/ogapps/extract "
non_apks = [
" defaultetc-common.tar.lz " ,
" defaultframework-common.tar.lz " ,
" googlepixelconfig-common.tar.lz "
]
skip = [
" setupwizarddefault-x86_64.tar.lz " ,
" setupwizardtablet-x86_64.tar.lz "
]
if not os . path . exists ( extract_to ) :
os . makedirs ( extract_to )
if not os . path . exists ( os . path . join ( extract_to , " appunpack " ) ) :
os . makedirs ( os . path . join ( extract_to , " appunpack " ) )
2022-01-17 05:33:08 -08:00
if os . path . isfile ( dl_file_name ) :
with open ( dl_file_name , " rb " ) as f :
2021-10-02 13:15:41 -07:00
bytes = f . read ( )
loc_md5 = hashlib . md5 ( bytes ) . hexdigest ( )
print ( " ==> Excepted hash: {} | File hash: {} " . format ( act_md5 , loc_md5 ) )
# Download the file if hash mismatches or if file does not exist
2022-01-17 05:33:08 -08:00
while not os . path . isfile ( dl_file_name ) or loc_md5 != act_md5 :
if os . path . isfile ( dl_file_name ) :
os . remove ( dl_file_name )
2021-10-02 13:15:41 -07:00
print ( " ==> OpenGapps zip not downloaded or hash mismatches, downloading now ..... " )
2022-01-17 05:33:08 -08:00
loc_md5 = download_file ( google_apps_dl_link , dl_file_name )
2021-10-02 13:15:41 -07:00
# Extract opengapps
print ( " ==> Extracting opengapps... " )
2022-01-17 05:33:08 -08:00
with zipfile . ZipFile ( dl_file_name ) as z :
2021-10-02 13:15:41 -07:00
z . extractall ( extract_to )
# Now copy the files
for lz_file in os . listdir ( os . path . join ( extract_to , " Core " ) ) :
for d in os . listdir ( os . path . join ( extract_to , " appunpack " ) ) :
shutil . rmtree ( os . path . join ( extract_to , " appunpack " , d ) )
if lz_file not in skip :
if lz_file not in non_apks :
print ( " ==> Processing app package : " + os . path . join ( extract_to , " Core " , lz_file ) )
os . system ( " tar --lzip -xvf ' {} ' -C ' {} ' >/dev/null " . format ( os . path . join ( extract_to , " Core " , lz_file ) , os . path . join ( extract_to , " appunpack " ) ) )
app_name = os . listdir ( os . path . join ( extract_to , " appunpack " ) ) [ 0 ]
xx_dpi = os . listdir ( os . path . join ( extract_to , " appunpack " , app_name ) ) [ 0 ]
app_priv = os . listdir ( os . path . join ( extract_to , " appunpack " , app_name , " nodpi " ) ) [ 0 ]
app_src_dir = os . path . join ( extract_to , " appunpack " , app_name , xx_dpi , app_priv )
for app in os . listdir ( app_src_dir ) :
shutil . copytree ( os . path . join ( app_src_dir , app ) , os . path . join ( sys_image_mount , " system " , " priv-app " , app ) , dirs_exist_ok = True )
else :
print ( " ==> Processing extra package : " + os . path . join ( extract_to , " Core " , lz_file ) )
os . system ( " tar --lzip -xvf ' {} ' -C ' {} ' >/dev/null " . format ( os . path . join ( extract_to , " Core " , lz_file ) , os . path . join ( extract_to , " appunpack " ) ) )
app_name = os . listdir ( os . path . join ( extract_to , " appunpack " ) ) [ 0 ]
common_content_dirs = os . listdir ( os . path . join ( extract_to , " appunpack " , app_name , " common " ) )
for ccdir in common_content_dirs :
shutil . copytree ( os . path . join ( extract_to , " appunpack " , app_name , " common " , ccdir ) , os . path . join ( sys_image_mount , " system " , ccdir ) , dirs_exist_ok = True )
2021-10-05 08:23:04 -07:00
print ( " ==> OpenGapps installation complete try re init /restarting waydroid " )
2021-10-02 13:15:41 -07:00
print ( " ==> Please note, google apps wont be usable without device registration !, Use --get-android-id for registration instructions " )
def get_android_id ( ) :
try :
if not os . path . isfile ( " /var/lib/waydroid/data/data/com.google.android.gsf/databases/gservices.db " ) :
print ( " Cannot access gservices.db, make sure gapps is installed and waydroid was started at least once after installation and make sure waydroid is running ! " )
sys . exit ( 1 )
sqs = """
SELECT * FROM main WHERE name = ' android_id '
"""
queryout = subprocess . check_output ( [ " sqlite3 " , " /var/lib/waydroid/data/data/com.google.android.gsf/databases/gservices.db " , sqs . strip ( ) ] , stderr = subprocess . STDOUT )
print ( queryout . decode ( ) . replace ( " android_id| " , " " ) . strip ( ) )
print ( " ^----- Open https://google.com/android/uncertified/?pli=1 " )
print ( " Login with your google id then submit the form with id shown above " )
except subprocess . CalledProcessError as e :
print ( " ==> Error getting id... ' {} ' " . format ( str ( e . output . decode ( ) ) ) )
def install_ndk ( ) :
2022-11-25 02:08:45 -08:00
# sys_image_mount = "/tmp/waydroidimage"
sys_image_mount = " /var/lib/waydroid/overlay "
prop_file = " /var/lib/waydroid/waydroid_base.prop "
2022-12-31 03:25:59 -08:00
ndk_zip_url = " https://www.dropbox.com/s/eaf4dj3novwiccp/libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3.zip?dl=1 "
2022-01-17 05:33:08 -08:00
dl_file_name = os . path . join ( download_loc , " libndktranslation.zip " )
2021-10-28 21:47:48 -07:00
extract_to = " /tmp/libndkunpack " #All catalog files will be marked as executable!
2022-12-31 03:25:59 -08:00
act_md5 = " 4456fc1002dc78e544e8d9721bb24398 "
2021-10-02 13:15:41 -07:00
loc_md5 = " "
apply_props = {
2022-12-31 03:25:59 -08:00
" ro.product.cpu.abilist " : " x86_64,x86,armeabi-v7a,armeabi,arm64-v8a " ,
2021-10-02 13:15:41 -07:00
" ro.product.cpu.abilist32 " : " x86,armeabi-v7a,armeabi " ,
2022-12-31 03:25:59 -08:00
" ro.product.cpu.abilist64 " : " x86_64,arm64-v8a " ,
2021-10-02 13:15:41 -07:00
" ro.dalvik.vm.native.bridge " : " libndk_translation.so " ,
" ro.enable.native.bridge.exec " : " 1 " ,
2022-12-31 03:25:59 -08:00
# "ro.ndk_translation.version": "0.2.2",
2021-10-02 13:15:41 -07:00
" ro.dalvik.vm.isa.arm " : " x86 " ,
" ro.dalvik.vm.isa.arm64 " : " x86_64 "
}
init_rc_component = """
on early - init
2021-11-15 06:39:54 -08:00
mount - t binfmt_misc binfmt_misc / proc / sys / fs / binfmt_misc
2021-10-02 13:15:41 -07:00
on property : ro . enable . native . bridge . exec = 1
2021-10-31 10:46:25 -07:00
exec - - / system / bin / sh - c " cat /system/etc/binfmt_misc/arm_exe > /proc/sys/fs/binfmt_misc/register "
exec - - / system / bin / sh - c " cat /system/etc/binfmt_misc/arm_dyn >> /proc/sys/fs/binfmt_misc/register "
exec - - / system / bin / sh - c " cat /system/etc/binfmt_misc/arm64_exe >> /proc/sys/fs/binfmt_misc/register "
exec - - / system / bin / sh - c " cat /system/etc/binfmt_misc/arm64_dyn >> /proc/sys/fs/binfmt_misc/register "
2021-10-02 13:15:41 -07:00
"""
2022-01-17 05:33:08 -08:00
if os . path . isfile ( dl_file_name ) :
with open ( dl_file_name , " rb " ) as f :
2021-10-02 13:15:41 -07:00
bytes = f . read ( )
loc_md5 = hashlib . md5 ( bytes ) . hexdigest ( )
2021-10-05 08:23:04 -07:00
2022-11-25 02:08:45 -08:00
#system_img = os.path.join(get_image_dir(), "system.img")
#if not os.path.isfile(system_img):
# print("The system image path '{}' from waydroid config is not valid !".format(system_img))
# sys.exit(1)
#print("==> Found system image: "+system_img)
2021-10-02 13:15:41 -07:00
# Resize rootfs
2022-11-25 02:08:45 -08:00
#img_size = int(os.path.getsize(system_img)/(1024*1024))
2022-01-02 22:22:20 -08:00
# Resize image to get some free space
2022-11-25 02:08:45 -08:00
#resize_img(system_img, "{}M".format(img_size+50))
2021-10-02 13:15:41 -07:00
# Mount the system image
2022-11-25 02:08:45 -08:00
#mount_image(system_img, sys_image_mount)
2021-10-02 13:15:41 -07:00
# Download the file if hash mismatches or if file does not exist
2022-01-17 05:33:08 -08:00
while not os . path . isfile ( dl_file_name ) or loc_md5 != act_md5 :
if os . path . isfile ( dl_file_name ) :
os . remove ( dl_file_name )
2021-10-02 13:15:41 -07:00
print ( " ==> NDK Translation zip not downloaded or hash mismatches, downloading now ..... " )
2022-01-17 05:33:08 -08:00
loc_md5 = download_file ( ndk_zip_url , dl_file_name )
2021-10-02 13:15:41 -07:00
2021-10-05 08:23:04 -07:00
# Extract ndk files
2021-10-02 13:15:41 -07:00
print ( " ==> Extracting archive... " )
2022-01-17 05:33:08 -08:00
with zipfile . ZipFile ( dl_file_name ) as z :
2021-10-02 13:15:41 -07:00
z . extractall ( extract_to )
2021-10-28 21:47:48 -07:00
#Mark ndk files as executable
print ( " ==> Chmodding... " )
try : os . system ( " chmod +x " + extract_to + " -R " )
2021-11-15 03:39:45 -08:00
except : print ( " ==> Couldn ' t mark files as executable! " )
2021-10-28 21:47:48 -07:00
2021-10-02 13:15:41 -07:00
# Copy library file
print ( " ==> Copying library files ... " )
shutil . copytree ( os . path . join ( extract_to , " libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3 " , " system " ) , os . path . join ( sys_image_mount , " system " ) , dirs_exist_ok = True )
2022-11-25 02:08:45 -08:00
##add this
2021-10-02 13:15:41 -07:00
# Add entries to build.prop
2022-11-25 02:08:45 -08:00
#print("==> Adding arch in build.prop")
#with open(os.path.join(sys_image_mount, "system", "build.prop"), "r") as propfile:
# prop_content = propfile.read()
# for key in apply_props:
# if key not in prop_content:
# prop_content = prop_content+"\n{key}={value}".format(key=key, value=apply_props[key])
# else:
# p = re.compile(r"^{key}=.*$".format(key=key), re.M)
# prop_content = re.sub(p, "{key}={value}".format(key=key, value=apply_props[key]), prop_content)
#with open(os.path.join(sys_image_mount, "system", "build.prop"), "w") as propfile:
# propfile.write(prop_content)
2021-10-02 13:15:41 -07:00
# Add entries to build.prop
2022-11-25 02:08:45 -08:00
print ( " ==> Adding arch in " , prop_file )
with open ( os . path . join ( prop_file ) , " r " ) as propfile :
2021-10-05 08:23:04 -07:00
prop_content = propfile . read ( )
2021-10-02 13:15:41 -07:00
for key in apply_props :
2021-10-05 08:23:04 -07:00
if key not in prop_content :
prop_content = prop_content + " \n {key} = {value} " . format ( key = key , value = apply_props [ key ] )
2021-10-02 13:15:41 -07:00
else :
p = re . compile ( r " ^ {key} =.*$ " . format ( key = key ) , re . M )
2021-10-05 08:23:04 -07:00
prop_content = re . sub ( p , " {key} = {value} " . format ( key = key , value = apply_props [ key ] ) , prop_content )
2022-11-25 02:08:45 -08:00
with open ( os . path . join ( prop_file ) , " w " ) as propfile :
2021-10-05 08:23:04 -07:00
propfile . write ( prop_content )
2021-10-02 13:15:41 -07:00
2022-11-25 02:08:45 -08:00
###add This
## Add entry to init.rc
#print("==> Adding entry to init.rc")
## Check if init.rc is located in Android 11's path
#init_path = os.path.join(sys_image_mount, "system", "etc", "init", "hw", "init.rc")
#if not os.path.isfile(init_path):
# # init.rc not found, assuming it's located in the root folder (Android 10 and older)
# init_path = os.path.join(sys_image_mount, "init.rc")
#with open(init_path, "r") as initfile:
# initcontent = initfile.read()
# if init_rc_component not in initcontent:
# initcontent=initcontent+init_rc_component
#with open(init_path, "w") as initfile:
# initfile.write(initcontent)
2021-10-02 13:15:41 -07:00
# Add entry to init.rc
2021-10-05 08:23:04 -07:00
print ( " ==> Adding entry to init.rc " )
2021-11-26 14:48:50 -08:00
# Check if init.rc is located in Android 11's path
2022-11-25 02:08:45 -08:00
init_path = os . path . join ( sys_image_mount , " system " , " etc " , " init " , " houdini.rc " )
2021-11-26 14:48:50 -08:00
if not os . path . isfile ( init_path ) :
2022-11-25 02:08:45 -08:00
os . makedirs ( os . path . dirname ( init_path ) , exist_ok = True )
f = open ( init_path , " x " )
2021-11-15 03:39:45 -08:00
with open ( init_path , " r " ) as initfile :
2021-10-02 13:15:41 -07:00
initcontent = initfile . read ( )
if init_rc_component not in initcontent :
initcontent = initcontent + init_rc_component
2021-11-15 03:39:45 -08:00
with open ( init_path , " w " ) as initfile :
2021-10-02 13:15:41 -07:00
initfile . write ( initcontent )
# Unmount and exit
2022-11-25 02:08:45 -08:00
##print("==> Unmounting .. ")
##try:
## subprocess.check_output(["umount", sys_image_mount], stderr=subprocess.STDOUT)
##except subprocess.CalledProcessError as e:
## print("==> Warning: umount failed.. {} ".format(str(e.output.decode())))
2021-10-02 13:15:41 -07:00
2021-10-05 08:23:04 -07:00
print ( " ==> libndk translation installed ! Restart waydroid service to apply changes ! " )
2021-11-15 03:39:45 -08:00
def install_houdini ( ) :
2022-11-14 13:08:54 -08:00
sys_image_mount = " /var/lib/waydroid/overlay "
prop_file = " /var/lib/waydroid/waydroid_base.prop "
2022-12-31 03:25:59 -08:00
houdini_zip_url = " https://www.dropbox.com/s/v7g0fluc7e8tod8/libhoudini.zip?dl=1 "
2022-01-17 05:33:08 -08:00
dl_file_name = os . path . join ( download_loc , " libhoudini.zip " )
2021-11-15 03:39:45 -08:00
extract_to = " /tmp/houdiniunpack " #All catalog files will be marked as executable!
2022-12-31 03:25:59 -08:00
act_md5 = " 838097117cec7762e958d7cbc209415e "
2021-11-15 03:39:45 -08:00
loc_md5 = " "
apply_props = {
" ro.product.cpu.abilist " : " x86_64,x86,arm64-v8a,armeabi-v7a,armeabi " ,
" ro.product.cpu.abilist32 " : " x86,armeabi-v7a,armeabi " ,
" ro.product.cpu.abilist64 " : " x86_64,arm64-v8a " ,
" ro.dalvik.vm.native.bridge " : " libhoudini.so " ,
" ro.enable.native.bridge.exec " : " 1 " ,
" ro.dalvik.vm.isa.arm " : " x86 " ,
" ro.dalvik.vm.isa.arm64 " : " x86_64 "
}
init_rc_component = """
on early - init
2021-11-15 06:39:54 -08:00
mount - t binfmt_misc binfmt_misc / proc / sys / fs / binfmt_misc
2021-11-15 03:39:45 -08:00
on property : ro . enable . native . bridge . exec = 1
2021-11-15 06:39:54 -08:00
exec - - / system / bin / sh - c " echo ' :arm_exe:M:: \\ \\ x7f \\ \\ x45 \\ \\ x4c \\ \\ x46 \\ \\ x01 \\ \\ x01 \\ \\ x01 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x02 \\ \\ x00 \\ \\ x28::/system/bin/houdini:P ' > /proc/sys/fs/binfmt_misc/register "
exec - - / system / bin / sh - c " echo ' :arm_dyn:M:: \\ \\ x7f \\ \\ x45 \\ \\ x4c \\ \\ x46 \\ \\ x01 \\ \\ x01 \\ \\ x01 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x03 \\ \\ x00 \\ \\ x28::/system/bin/houdini:P ' >> /proc/sys/fs/binfmt_misc/register "
exec - - / system / bin / sh - c " echo ' :arm64_exe:M:: \\ \\ x7f \\ \\ x45 \\ \\ x4c \\ \\ x46 \\ \\ x02 \\ \\ x01 \\ \\ x01 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x02 \\ \\ x00 \\ \\ xb7::/system/bin/houdini64:P ' >> /proc/sys/fs/binfmt_misc/register "
exec - - / system / bin / sh - c " echo ' :arm64_dyn:M:: \\ \\ x7f \\ \\ x45 \\ \\ x4c \\ \\ x46 \\ \\ x02 \\ \\ x01 \\ \\ x01 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x00 \\ \\ x03 \\ \\ x00 \\ \\ xb7::/system/bin/houdini64:P ' >> /proc/sys/fs/binfmt_misc/register "
2021-11-15 03:39:45 -08:00
"""
2022-01-17 05:33:08 -08:00
if os . path . isfile ( dl_file_name ) :
with open ( dl_file_name , " rb " ) as f :
2021-11-15 03:39:45 -08:00
bytes = f . read ( )
loc_md5 = hashlib . md5 ( bytes ) . hexdigest ( )
# Download the file if hash mismatches or if file does not exist
2022-01-17 05:33:08 -08:00
while not os . path . isfile ( dl_file_name ) or loc_md5 != act_md5 :
if os . path . isfile ( dl_file_name ) :
os . remove ( dl_file_name )
2021-11-15 03:39:45 -08:00
print ( " ==> libhoudini zip not downloaded or hash mismatches, downloading now ..... " )
2022-01-17 05:33:08 -08:00
loc_md5 = download_file ( houdini_zip_url , dl_file_name )
2021-11-15 03:39:45 -08:00
# Extract ndk files
print ( " ==> Extracting archive... " )
2022-01-17 05:33:08 -08:00
with zipfile . ZipFile ( dl_file_name ) as z :
2021-11-15 03:39:45 -08:00
z . extractall ( extract_to )
# Mark libhoudini files as executable
print ( " ==> Chmodding... " )
try : os . system ( " chmod +x " + extract_to + " -R " )
except : print ( " ==> Couldn ' t mark files as executable! " )
# Copy library file
print ( " ==> Copying library files ... " )
shutil . copytree ( os . path . join ( extract_to , " system " ) , os . path . join ( sys_image_mount , " system " ) , dirs_exist_ok = True )
# Add entries to build.prop
2022-11-14 13:08:54 -08:00
print ( " ==> Adding arch in " , prop_file )
with open ( os . path . join ( prop_file ) , " r " ) as propfile :
2021-11-15 03:39:45 -08:00
prop_content = propfile . read ( )
for key in apply_props :
if key not in prop_content :
prop_content = prop_content + " \n {key} = {value} " . format ( key = key , value = apply_props [ key ] )
else :
p = re . compile ( r " ^ {key} =.*$ " . format ( key = key ) , re . M )
prop_content = re . sub ( p , " {key} = {value} " . format ( key = key , value = apply_props [ key ] ) , prop_content )
2022-11-14 13:08:54 -08:00
with open ( os . path . join ( prop_file ) , " w " ) as propfile :
2021-11-15 03:39:45 -08:00
propfile . write ( prop_content )
# Add entry to init.rc
print ( " ==> Adding entry to init.rc " )
2021-11-26 14:48:50 -08:00
# Check if init.rc is located in Android 11's path
2022-11-14 13:08:54 -08:00
init_path = os . path . join ( sys_image_mount , " system " , " etc " , " init " , " houdini.rc " )
2021-11-26 14:48:50 -08:00
if not os . path . isfile ( init_path ) :
2022-11-14 13:08:54 -08:00
os . makedirs ( os . path . dirname ( init_path ) , exist_ok = True )
f = open ( init_path , " x " )
2021-11-15 03:39:45 -08:00
with open ( init_path , " r " ) as initfile :
initcontent = initfile . read ( )
if init_rc_component not in initcontent :
initcontent = initcontent + init_rc_component
with open ( init_path , " w " ) as initfile :
initfile . write ( initcontent )
print ( " ==> libhoudini translation installed ! Restart waydroid service to apply changes ! " )
2021-10-05 08:23:04 -07:00
def install_magisk ( ) :
2022-12-31 05:47:21 -08:00
dl_link = " https://huskydg.github.io/magisk-files/app-release.apk "
2022-12-31 03:25:59 -08:00
dl_file_name = os . path . join ( download_loc , " magisk.apk " )
2021-10-05 08:23:04 -07:00
extract_to = " /tmp/magisk_unpack "
2023-01-02 01:55:03 -08:00
# sys_overlay_dir = "/var/lib/waydroid/overlay_rw/system"
sys_overlay_dir = " /var/lib/waydroid/overlay "
merge_dir = " /var/lib/waydroid/rootfs "
magisk_dir = os . path . join ( sys_overlay_dir , " system " , " etc " , " init " , " magisk " )
2023-01-01 09:18:35 -08:00
arch_dir = " x86 " if " x86 " in platform . machine ( ) else " arm "
arch = " _64 " if " 64 " in platform . machine ( ) else " "
2022-12-31 03:25:59 -08:00
init_rc_component = """
on post - fs - data
2022-12-31 05:47:21 -08:00
start logd
2023-01-01 09:18:35 -08:00
exec - root root - - / system / etc / init / magisk / magisk { arch } - - setup - sbin / system / etc / init / magisk
2023-01-01 09:02:57 -08:00
exec - 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
2022-12-31 03:25:59 -08:00
start FAhW7H9G5sf
2022-12-31 05:47:21 -08:00
wait / dev / . magisk_unblock 40
2023-01-01 09:02:57 -08:00
rm / dev / . magisk_unblock
service FAhW7H9G5sf / sbin / magisk - - post - fs - data
2022-12-31 03:25:59 -08:00
user root
2022-12-31 05:47:21 -08:00
seclabel -
2022-12-31 03:25:59 -08:00
oneshot
2023-01-01 09:02:57 -08:00
service HLiFsR1HtIXVN6 / sbin / magisk - - service
2022-12-31 03:25:59 -08:00
class late_start
2021-10-05 08:23:04 -07:00
user root
2022-12-31 05:47:21 -08:00
seclabel -
2021-10-05 08:23:04 -07:00
oneshot
2022-12-31 03:25:59 -08:00
on property : sys . boot_completed = 1
2022-12-31 05:47:21 -08:00
mkdir / data / adb / magisk 755
2023-01-01 09:02:57 -08:00
exec - root root - - / sbin / magisk - - 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 "
2022-12-31 05:47:21 -08:00
on property : init . svc . zygote = restarting
2023-01-01 09:02:57 -08:00
exec - root root - - / sbin / magisk - - zygote - restart
2022-12-31 05:47:21 -08:00
on property : init . svc . zygote = stopped
2023-01-01 09:02:57 -08:00
exec - root root - - / sbin / magisk - - zygote - restart
2023-01-01 09:18:35 -08:00
""" .format(arch=32 if arch== " " else 64)
2022-01-02 22:22:20 -08:00
2023-01-02 01:55:03 -08:00
if " RUNNING " not in subprocess . check_output ( " waydroid status | grep Container | awk -F ' [: \t ] ' ' { print $3} ' " , shell = True ) . decode ( ) :
print ( " Please make sure waydroid container is running! " )
sys . exit ( 1 )
2021-10-05 08:23:04 -07:00
# Download magisk
2023-01-01 09:02:57 -08:00
if os . path . isfile ( dl_file_name ) :
os . remove ( dl_file_name )
print ( " ==> Downloading latest Magisk-Delta now ..... " )
download_file ( dl_link , dl_file_name )
2021-10-05 08:23:04 -07:00
# Extract magisk files
print ( " ==> Extracting archive... " )
2022-01-17 05:33:08 -08:00
with zipfile . ZipFile ( dl_file_name ) as z :
2021-10-05 08:23:04 -07:00
z . extractall ( extract_to )
2023-01-01 09:02:57 -08:00
if not os . path . exists ( magisk_dir ) :
os . makedirs ( magisk_dir , exist_ok = True )
2022-12-31 03:25:59 -08:00
2023-01-02 01:55:03 -08:00
if not os . path . exists ( os . path . join ( sys_overlay_dir , " sbin " ) ) :
os . makedirs ( os . path . join ( sys_overlay_dir , " sbin " ) , exist_ok = True )
2023-01-01 09:02:57 -08:00
2021-10-05 08:23:04 -07:00
# Now setup and install magisk binary and app
print ( " ==> Installing magisk now ... " )
2022-12-31 03:25:59 -08:00
lib_dir = os . path . join ( extract_to , " lib " , " {arch_dir} {arch} " . format ( arch_dir = arch_dir , arch = arch ) )
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 )
2023-01-01 09:02:57 -08:00
n_path = os . path . join ( magisk_dir , filename . group ( 1 ) )
2022-12-31 03:25:59 -08:00
shutil . copyfile ( o_path , n_path )
2023-01-01 09:02:57 -08:00
shutil . copyfile ( dl_file_name , os . path . join ( magisk_dir , " magisk.apk " ) )
# Mark magisk files as executable
print ( " ==> Chmodding... " )
try : os . system ( " chmod +x " + os . path . join ( magisk_dir , " magisk* " ) )
except : print ( " ==> Couldn ' t mark files as executable! " )
2021-10-02 13:15:41 -07:00
2023-01-01 09:02:57 -08:00
# Updating Magisk from Magisk manager will modify bootanim.rc,
# So it is necessary to backup the original bootanim.rc.
2023-01-02 01:55:03 -08:00
print ( " ==> Adding entry to bootanim.rc " )
bootanim = os . path . join ( sys_overlay_dir , " system " , " etc " , " init " , " bootanim.rc " )
original_bootanim = os . path . join ( merge_dir , " system " , " etc " , " init " , " bootanim.rc " )
if not os . path . isfile ( bootanim ) :
os . makedirs ( os . path . dirname ( bootanim ) , exist_ok = True )
gz_filename = bootanim + " .gz "
with open ( original_bootanim , ' rb ' ) as f_ungz :
2023-01-01 09:02:57 -08:00
with gzip . open ( gz_filename , ' wb ' ) as f_gz :
f_gz . writelines ( f_ungz )
2023-01-02 01:55:03 -08:00
with open ( original_bootanim , " r " ) as initfile :
2021-10-05 08:23:04 -07:00
initcontent = initfile . read ( )
if init_rc_component not in initcontent :
initcontent = initcontent + init_rc_component
2023-01-02 01:55:03 -08:00
with open ( bootanim , " w " ) as initfile :
2021-10-05 08:23:04 -07:00
initfile . write ( initcontent )
2023-01-01 09:02:57 -08:00
2021-10-05 08:23:04 -07:00
print ( " ==> Magisk was installed ! Restart waydroid service to apply changes ! " )
2023-01-02 01:55:03 -08:00
2022-12-31 03:25:59 -08:00
def install_widevine ( ) :
2023-01-02 01:55:03 -08:00
vendor_image_mount = " /var/lib/waydroid/overlay/vendor "
2022-12-31 03:25:59 -08:00
widevine_zip_url = " https://codeload.github.com/supremegamers/vendor_google_proprietary_widevine-prebuilt/zip/refs/heads/chromeos_hatch "
dl_file_name = os . path . join ( download_loc , " widevine.zip " )
extract_to = " /tmp/widevineunpack " #All catalog files will be marked as executable!
act_md5 = " 7fe3b2a9502da9ad63189a077c457ad2 "
loc_md5 = " "
if os . path . isfile ( dl_file_name ) :
with open ( dl_file_name , " rb " ) as f :
bytes = f . read ( )
loc_md5 = hashlib . md5 ( bytes ) . hexdigest ( )
# Download the file if hash mismatches or if file does not exist
while not os . path . isfile ( dl_file_name ) or loc_md5 != act_md5 :
if os . path . isfile ( dl_file_name ) :
os . remove ( dl_file_name )
print ( " ==> windevine zip not downloaded or hash mismatches, downloading now ..... " )
loc_md5 = download_file ( widevine_zip_url , dl_file_name )
# Extract widevine files
print ( " ==> Extracting archive... " )
with zipfile . ZipFile ( dl_file_name ) as z :
z . extractall ( extract_to )
#Mark widevine files as executable
print ( " ==> Chmodding... " )
try : os . system ( " chmod +x " + extract_to + " -R " )
except : print ( " ==> Couldn ' t mark files as executable! " )
# Copy library file
print ( " ==> Copying library files ... " )
shutil . copytree ( os . path . join ( extract_to , " vendor_google_proprietary_widevine-prebuilt-chromeos_hatch " , " prebuilts " ) , vendor_image_mount , dirs_exist_ok = True )
print ( " ==> Widevine installed ! Restart waydroid service to apply changes ! " )
2021-10-02 13:15:41 -07:00
def main ( ) :
2022-01-17 05:33:08 -08:00
about = """
2021-10-02 13:15:41 -07:00
WayDroid Helper script v0 .3
Does stuff like installing Gapps , Installing NDK Translation and getting Android ID for device registration .
Use - h flag for help !
"""
parser = argparse . ArgumentParser ( description = about , formatter_class = argparse . RawDescriptionHelpFormatter )
parser . add_argument ( ' -g ' , ' --install-gapps ' ,
dest = ' install ' ,
help = ' Install OpenGapps to waydroid ' ,
action = ' store_true ' )
parser . add_argument ( ' -n ' , ' --install-ndk-translation ' ,
dest = ' installndk ' ,
help = ' Install experimental libndk translation files ' ,
action = ' store_true ' )
parser . add_argument ( ' -i ' , ' --get-android-id ' , dest = ' getid ' ,
help = ' Displays your android id for manual registration ' ,
action = ' store_true ' )
2021-10-05 08:23:04 -07:00
parser . add_argument ( ' -m ' , ' --install-magisk ' , dest = ' magisk ' ,
help = ' Attempts to install Magisk ( Bootless ) ' ,
action = ' store_true ' )
2021-11-15 03:39:45 -08:00
parser . add_argument ( ' -l ' , ' --install-libhoudini ' , dest = ' houdini ' ,
help = ' Install libhoudini for arm translation ' ,
action = ' store_true ' )
2022-12-31 03:25:59 -08:00
parser . add_argument ( ' -w ' , ' --install-windevine ' , dest = ' widevine ' ,
help = ' Integrate Widevine DRM (L3) ' ,
action = ' store_true ' )
2021-10-02 13:15:41 -07:00
args = parser . parse_args ( )
if args . install :
stop_waydroid ( )
install_gapps ( )
elif args . installndk :
stop_waydroid ( )
install_ndk ( )
elif args . getid :
get_android_id ( )
2021-10-05 08:23:04 -07:00
elif args . magisk :
install_magisk ( )
2021-11-15 03:39:45 -08:00
elif args . houdini :
install_houdini ( )
2022-12-31 03:25:59 -08:00
elif args . widevine :
install_widevine ( )
2021-10-02 13:15:41 -07:00
2022-12-31 11:17:56 -08:00
if __name__ == " __main__ " :
2021-10-02 13:15:41 -07:00
main ( )