add uninstall function

pull/70/head
Rikka 2 years ago committed by Rikka
parent 4d15b6153c
commit 0d7681bccb
No known key found for this signature in database
GPG Key ID: CD36B07FA9F7D2AA

@ -140,17 +140,19 @@ Star this repository if you find this useful, if you encounter problem create a
## Error handling
In case of error, if you retry immediately and it fails with this error
```
==> Failed to resize image '/var/lib/waydroid/images/system.img' .. ! e2fsck 1.45.5 (07-Jan-2020)
/var/lib/waydroid/images/system.img is mounted.
e2fsck: Cannot continue, aborting.
```
You need to get the mounting point using `df | grep waydroid`. It will be something like `/dev/loopXXX`. Then, unmount it
- WayDroid no longer boots
```
sudo umount /dev/loopXXX
sudo waydroid upgrade -o
sudo systemctl restart waydroid-container.service
```
And re-run the script.
This will make `/var/lib/waydroid/waydroid_base.prop` return to original state, so libndk/libhoudini will be invalid. You need to modify `waydroid_base.prop` again.
Or use `sudo python3 main.py uninstall xxxxx` to remove what is causing the issue.
- Magisk installed: N/A
Check [waydroid-magisk](https://github.com/nitanmarcel/waydroid-magisk)
## Credits
- [WayDroid](https://github.com/waydroid/waydroid)

@ -41,18 +41,10 @@ def install(*args):
def uninstall(*args):
if "gapps" in args:
Gapps().uninstall()
if "libndk" in args and "houdini" not in args:
arch = helper.host()[0]
if arch == "x86_64":
Ndk().uninstall()
else:
Logger.warn("libndk is not supported on your CPU")
if "libhoudini" in args and "ndk" not in args:
arch = helper.host()[0]
if arch == "x86_64":
Houdini().uninstall()
else:
Logger.warn("libhoudini is not supported on your CPU")
if "libndk" in args:
Ndk().uninstall()
if "libhoudini" in args:
Houdini().uninstall()
if "magisk" in args:
Magisk().uninstall()
if "widevine" in args:
@ -61,6 +53,8 @@ def uninstall(*args):
Smartdock().uninstall()
if "nodataperm" in args:
Nodataperm().uninstall()
if "microg" in args:
MicroG().uninstall()
def main():
about = """
@ -85,7 +79,7 @@ def main():
"type": str,
"nargs": '+',
"metavar":"",
"choices": ["gapps", "microg", "libndk","libhoudini","magisk", "smartdock","widevine", "nodataperm"],
"choices": ["gapps", "microg", "libndk", "libhoudini", "magisk", "smartdock", "widevine", "nodataperm"],
}
install_help = """

@ -27,6 +27,36 @@ class Gapps(General):
"setupwizarddefault-x86_64.tar.lz",
"setupwizardtablet-x86_64.tar.lz"
]
files = [
"etc/default-permissions/default-permissions.xml",
"etc/default-permissions/opengapps-permissions-q.xml",
"etc/permissions/com.google.android.maps.xml",
"etc/permissions/com.google.android.media.effects.xml",
"etc/permissions/privapp-permissions-google.xml",
"etc/permissions/split-permissions-google.xml",
"etc/preferred-apps/google.xml",
"etc/sysconfig/google.xml",
"etc/sysconfig/google_build.xml",
"etc/sysconfig/google_exclusives_enable.xml",
"etc/sysconfig/google-hiddenapi-package-whitelist.xml",
"framework/com.google.android.maps.jar",
"framework/com.google.android.media.effects.jar",
"priv-app/AndroidMigratePrebuilt",
"priv-app/GoogleExtServices",
"priv-app/GoogleRestore",
"priv-app/CarrierSetup",
"priv-app/GoogleExtShared",
"priv-app/GoogleServicesFramework",
"priv-app/ConfigUpdater",
"priv-app/GoogleFeedback",
"priv-app/Phonesky",
"priv-app/GoogleBackupTransport",
"priv-app/GoogleOneTimeInitializer",
"priv-app/PrebuiltGmsCore",
"priv-app/GoogleContactsSyncAdapter",
"priv-app/GooglePartnerSetup",
"product/overlay/PlayStoreOverlay.apk"
]
def copy(self):
if not os.path.exists(self.extract_to):

@ -1,6 +1,7 @@
import configparser
import glob
import os
import re
import shutil
import zipfile
import hashlib
from tools import images
@ -37,6 +38,21 @@ class General:
Logger.warning(
"md5 mismatches, redownloading now ....")
loc_md5 = download_file(self.dl_link, self.download_loc)
def remove(self):
for f in self.files:
file = os.path.join(self.copy_dir, self.partition, f)
if "*" in file:
for wildcard_file in glob.glob(file):
if os.path.isdir(wildcard_file):
shutil.rmtree(wildcard_file)
elif os.path.isfile(wildcard_file):
os.remove(wildcard_file)
else:
if os.path.isdir(file):
shutil.rmtree(file)
elif os.path.isfile(file):
os.remove(file)
def extract(self):
Logger.info("Extracting archive...")
@ -44,14 +60,26 @@ class General:
z.extractall(self.extract_to)
def add_props(self):
cfg = configparser.ConfigParser()
cfg.read("/var/lib/waydroid/waydroid.cfg")
for key in self.apply_props.keys():
cfg.set('properties', key, self.apply_props[key])
with open("/var/lib/waydroid/waydroid.cfg", "w") as f:
cfg.write(f)
with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "r") as propfile:
prop_content = propfile.read()
for key in self.apply_props:
if key not in prop_content:
prop_content = prop_content+"\n{key}={value}".format(key=key, value=self.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=self.apply_props[key]), prop_content)
with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "w") as propfile:
propfile.write(prop_content)
def remove_props(self):
with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "r") as propfile:
prop_content = propfile.read()
for key in self.apply_props:
if key in prop_content:
p = re.compile(r"^{key}=.*(\n)*".format(key=key), re.M)
prop_content = re.sub(p, "", prop_content)
with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "w") as propfile:
propfile.write(prop_content)
def mount(self):
img = os.path.join(images.get_image_dir(), self.partition+".img")
@ -103,6 +131,9 @@ class General:
def extra2(self):
pass
def extra3(self):
pass
def install(self):
if container.use_overlayfs():
self.download()
@ -131,4 +162,19 @@ class General:
Logger.info("Installation finished")
def uninstall(self):
pass
if container.use_overlayfs():
self.remove()
if hasattr(self, "apply_props"):
self.remove_props()
self.extra3()
self.restart()
else:
self.stop()
self.mount()
self.remove()
if hasattr(self, "apply_props"):
self.remove_props()
self.extra3()
self.umount()
self.start()
Logger.info("Uninstallation finished")

@ -31,6 +31,18 @@ on property:ro.enable.native.bridge.exec=1
"ro.dalvik.vm.isa.arm": "x86",
"ro.dalvik.vm.isa.arm64": "x86_64"
}
files = [
"bin/arm",
"bin/arm64",
"bin/houdini",
"bin/houdini64",
"etc/binfmt_misc",
"etc/init/houdini.rc",
"lib/arm",
"lib/libhoudini.so",
"lib64/arm64",
"lib64/libhoudini.so"
]
def copy(self):
run(["chmod", "+x", self.extract_to, "-R"])

@ -3,7 +3,7 @@ import os
import shutil
import re
from stuffs.general import General
from tools.helper import download_file, host, run
from tools.helper import download_file, get_data_dir, host, run
from tools.logger import Logger
from tools import container
@ -14,6 +14,7 @@ class Magisk(General):
extract_to = "/tmp/magisk_unpack"
magisk_dir = os.path.join(partition, "etc", "init", "magisk")
machine = host()
files = ["etc/init/magisk"]
oringinal_bootanim = """
service bootanim /system/bin/bootanimation
class core animation
@ -60,6 +61,13 @@ on property:init.svc.zygote=stopped
Logger.info("Downloading latest Magisk-Delta to {} now ...".format(self.download_loc))
download_file(self.dl_link, self.download_loc)
# require additional setup
def setup(self):
Logger.info("Additional setup")
magisk_absolute_dir = os.path.join(self.copy_dir, self.magisk_dir)
data_dir = get_data_dir()
shutil.copytree(magisk_absolute_dir, os.path.join(data_dir, "adb", "magisk"), dirs_exist_ok=True)
def copy(self):
magisk_absolute_dir = os.path.join(self.copy_dir, self.magisk_dir)
if not os.path.exists(magisk_absolute_dir):
@ -79,6 +87,16 @@ on property:init.svc.zygote=stopped
shutil.copyfile(o_path, n_path)
run(["chmod", "+x", n_path])
shutil.copyfile(self.download_loc, os.path.join(magisk_absolute_dir,"magisk.apk") )
shutil.copytree(os.path.join(self.extract_to, "assets", "chromeos"), os.path.join(magisk_absolute_dir, "chromeos"), dirs_exist_ok=True)
assets_files = [
"addon.d.sh",
"boot_patch.sh",
"stub.apk",
"util_functions.sh"
]
for f in assets_files:
shutil.copyfile(os.path.join(self.extract_to, "assets", f), os.path.join(magisk_absolute_dir, f))
self.setup()
# Updating Magisk from Magisk manager will modify bootanim.rc,
# So it is necessary to backup the original bootanim.rc.
@ -94,16 +112,36 @@ on property:init.svc.zygote=stopped
def extra1(self):
if container.use_overlayfs():
sys_overlay_rw = "/var/lib/waydroid/overlay_rw"
old_bootanim_rc = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "bootanim.rc")
old_bootanim_rc_gz = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "bootanim.rc.gz")
old_magisk = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "magisk")
files = [
"system/system/etc/init/bootanim.rc",
"system/system/etc/init/bootanim.rc.gz",
"system/system/etc/init/magisk",
"system/system/addon.d/99-magisk.sh",
"vendor/etc/selinux/precompiled_sepolicy"
]
if os.path.exists(old_bootanim_rc):
os.remove(old_bootanim_rc)
if os.path.exists(old_bootanim_rc_gz):
os.remove(old_bootanim_rc_gz)
if os.path.exists(old_magisk):
if os.path.isdir(old_magisk):
shutil.rmtree(old_magisk)
else:
os.remove(old_magisk)
for f in files:
file = os.path.join(sys_overlay_rw, f)
if os.path.isdir(file):
shutil.rmtree(file)
elif os.path.isfile(file) or os.path.exists(file):
os.remove(file)
def extra3(self):
self.extra1()
data_dir = get_data_dir()
files = [
os.path.join(data_dir, "adb/magisk.db"),
os.path.join(data_dir, "adb/magisk")
]
for file in files:
if os.path.isdir(file):
shutil.rmtree(file)
elif os.path.isfile(file):
os.remove(file)
bootanim_path = os.path.join(self.copy_dir, self.partition, "etc", "init", "bootanim.rc")
if container.use_overlayfs():
os.remove(bootanim_path)
else:
with open(bootanim_path, "w") as initfile:
initfile.write(self.oringinal_bootanim)

@ -28,6 +28,7 @@ class MicroG(General):
"com.android.vending-22.apk": "6815d191433ffcd8fa65923d5b0b0573",
"org.microg.gms.droidguard-14.apk": "4734b41c1a6bc34a541053ddde7a0f8e"
}
priv_apps = ["com.google.android.gms", "com.android.vending"]
def skip_extract(self):
return True
@ -59,12 +60,11 @@ class MicroG(General):
def copy(self):
Logger.info("Copying MicroG and other files")
priv_apps = ["com.google.android.gms", "com.android.vending"]
for apk in {**self.fdroid_repo_apks, **self.microg_apks}.keys():
splitor = "_" if apk in self.fdroid_repo_apks.keys() else "-"
package = apk.split(splitor)[0]
download_dir = get_download_dir()
apk_dir = "app" if package not in priv_apps else "priv-app"
apk_dir = "app" if package not in self.priv_apps else "priv-app"
if not os.path.exists(os.path.join(self.copy_dir, self.partition, apk_dir, package)):
os.makedirs(os.path.join(self.copy_dir, self.partition, apk_dir, package))
shutil.copyfile(os.path.join(download_dir, apk),
@ -89,3 +89,17 @@ class MicroG(General):
Logger.info("Signature spoofing")
run("waydroid shell pm grant com.google.android.gms android.permission.FAKE_PACKAGE_SIGNATURE".split())
run("waydroid shell pm grant com.android.vending android.permission.FAKE_PACKAGE_SIGNATURE".split())
def remove(self):
system_dir = os.path.join(self.copy_dir, self.partition)
files = [key.split("_")[0] for key in self.fdroid_repo_apks.keys()]
files += [key.split("-")[0] for key in self.microg_apks.keys()]
for f in files:
if f in self.priv_apps:
file = os.path.join(system_dir, "priv-app", f)
else:
file = os.path.join(system_dir, "app", f)
if os.path.isdir(file):
shutil.rmtree(file)
elif os.path.isfile(file):
os.remove(file)

@ -1,4 +1,5 @@
from os import path, makedirs
import glob
import os
import shutil
from stuffs.general import General
from tools.helper import run
@ -6,10 +7,10 @@ from tools.logger import Logger
class Ndk(General):
partition = "system"
dl_link = "https://github.com/supremegamers/vendor_google_proprietary_ndk_translation-prebuilt/archive/181d9290a69309511185c4417ba3d890b3caaaa8.zip"
dl_link = "https://www.dropbox.com/s/eaf4dj3novwiccp/libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3.zip?dl=1"
dl_file_name = "libndktranslation.zip"
extract_to = "/tmp/libndkunpack"
act_md5 = "0beff55f312492f24d539569d84f5bfb"
act_md5 = "4456fc1002dc78e544e8d9721bb24398"
apply_props = {
"ro.product.cpu.abilist": "x86_64,x86,armeabi-v7a,armeabi,arm64-v8a",
"ro.product.cpu.abilist32": "x86,armeabi-v7a,armeabi",
@ -31,23 +32,29 @@ on property:ro.enable.native.bridge.exec=1
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
"""
files = [
"bin/arm",
"bin/arm64",
"bin/ndk_translation_program_runner_binfmt_misc",
"bin/ndk_translation_program_runner_binfmt_misc_arm64",
"etc/binfmt_misc",
"etc/ld.config.arm.txt",
"etc/ld.config.arm64.txt",
"etc/init/libndk.rc",
"lib/arm",
"lib64/arm64",
"lib/libndk*",
"lib64/libndk*"
]
def copy(self):
run(["chmod", "+x", self.extract_to, "-R"])
Logger.info("Copying libndk library files ...")
archive_url, commit_sha = path.split(path.splitext(self.dl_link)[0])
zipped_basepath, _ = path.split(archive_url)
prebuilts_sourcedir = path.join(
self.extract_to,
f"{path.basename(zipped_basepath)}-{commit_sha}",
"prebuilts")
shutil.copytree(
prebuilts_sourcedir,
path.join(self.copy_dir, self.partition),
dirs_exist_ok=True)
shutil.copytree(os.path.join(self.extract_to, "libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3", "system"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True)
init_path = path.join(self.copy_dir, self.partition, "etc", "init", "libndk.rc")
if not path.isfile(init_path):
makedirs(path.dirname(init_path), exist_ok=True)
init_path = os.path.join(self.copy_dir, self.partition, "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)

@ -1,8 +1,10 @@
import gzip
import os
import shutil
from stuffs.general import General
from tools.helper import run
from tools.logger import Logger
from tools import container
class Nodataperm(General):
dl_link = "https://github.com/ayasa520/hack_full_data_permission/archive/refs/heads/main.zip"
@ -10,11 +12,30 @@ class Nodataperm(General):
extract_to = "/tmp/nodataperm"
act_md5 = "eafd7b0986f3edaebaf1dd89f19d49bf"
partition = "system"
files = [
"etc/nodataperm.sh",
"etc/init/nodataperm.rc",
"framework/services.jar"
]
def copy(self):
extract_path = os.path.join(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")
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())
os.chmod(os.path.join(extract_path, "framework", "services.jar"), 0o644)
os.chmod(os.path.join(extract_path, "etc", "nodataperm.sh"), 0o755)
os.chmod(os.path.join(extract_path, "etc", "init", "nodataperm.rc"), 0o755)
Logger.info("Copying widevine library files ...")
shutil.copytree(extract_path, os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True)
def extra3(self):
if not container.use_overlayfs():
services_jar = os.path.join(self.copy_dir, self.partition, "framework", "services.jar")
gz_filename = services_jar+".gz"
with gzip.GzipFile(gz_filename) as f_gz:
with open(services_jar, "wb") as f:
f.writelines(f_gz)

@ -12,6 +12,10 @@ class Smartdock(General):
dl_file_name = "smartdock.zip"
act_md5 = "ad0cc5e023ac6ee97e7b013b9b0defee"
apply_props = { "qemu.hw.mainkeys" : "1" }
files = [
"etc/permissions/permissions_cu.axel.smartdock.xml",
"priv-app/SmartDock"
]
def copy(self):
if not os.path.exists(os.path.join(self.copy_dir, self.partition, "priv-app", "SmartDock")):

@ -11,6 +11,15 @@ class Widevine(General):
dl_file_name = "widevine.zip"
extract_to = "/tmp/widevineunpack"
act_md5 = "a31f325453c5d239c21ecab8cfdbd878"
files = [
"bin/hw/android.hardware.drm@1.3-service-lazy.widevine",
"bin/move_widevine_data.sh",
"etc/init/android.hardware.drm@1.3-service-lazy.widevine.rc",
"etc/vintf/manifest/manifest_android.hardware.drm@1.3-service.widevine.xml",
"lib/libwvhidl.so",
"lib/mediadrm",
"lib64/mediadrm"
]
def copy(self):
run(["chmod", "+x", self.extract_to, "-R"])

@ -19,6 +19,10 @@ def get_download_dir():
os.makedirs(download_loc)
return download_loc
# not good
def get_data_dir():
return os.path.join('/', "home", os.environ.get("SUDO_USER", os.environ["USER"]), ".local", "share", "waydroid", "data")
def run(args, ignore=""):
result = subprocess.run(args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# print(result.stdout.decode())

Loading…
Cancel
Save