#!/sbin/sh OUTFD=$2 ZIP=$3 GOOGLE_APPS="GoogleFeedback GoogleLoginService GoogleOneTimeInitializer GoogleServicesFramework GsfProxy MarketUpdater PlayGames Velvet GmsDroidGuard YouTube GmsCore_update GmsCoreSetupPrebuilt PrebuiltGmsCore WhisperPush BlankStore FDroidPriv PlayStore Vending AMAPNetworkLocation BaiduNetworkLocation LegacyNetworkLocation NetworkLocation UnifiedNlp DejaVuBackend DejaVuNlpBackend IchnaeaNlpBackend MozillaNlpBackend NominatimGeocoderBackend NominatimNlpBackend com.mgoogle.android.gms com.google.android.gms com.google.android.feedback com.google.android.gsf.login com.google.android.gsf com.android.vending org.microg.gms.droidguard org.schabi.newpipe com.google.android.youtube com.qualcomm.location com.amap.android.location com.baidu.location com.google.android.location org.microg.nlp org.microg.unifiednlp com.google.android.maps org.fitchfamily.android.dejavu org.microg.nlp.backend.ichnaea org.microg.nlp.backend.nominatim" ui_print() { echo -n -e "ui_print $1\n" >> /proc/self/fd/$OUTFD echo -n -e "ui_print\n" >> /proc/self/fd/$OUTFD } grep_prop() { REGEX="s/^$1=//p" shift FILES=$@ if [ -z "$FILES" ]; then FILES='/system/build.prop' fi cat $FILES 2>/dev/null | sed -n "$REGEX" | head -n 1 } is_mounted() { if [ ! -z "$2" ]; then cat /proc/mounts | grep $1 | grep $2, >/dev/null else cat /proc/mounts | grep $1 >/dev/null fi return $? } error () { ui_print "${@}" ui_print " " ui_print " ** post your /tmp/recovery.log" ui_print " ** in the XDA support thread" ui_print " " exit 1 } request_size_check() { reqSizeM=`unzip -l "$1" 2>/dev/null | tail -n 1 | awk '{ print $1 }'` reqSizeM=$((reqSizeM / 1048576 + 1)) } image_size_check() { e2fsck -yf $1 curBlocks=`e2fsck -n $1 2>/dev/null | grep $1 | cut -d, -f3 | cut -d\ -f2`; curUsedM=`echo "$curBlocks" | cut -d/ -f1` curSizeM=`echo "$curBlocks" | cut -d/ -f1` curFreeM=$(((curSizeM - curUsedM) * 4 / 1024)) curUsedM=$((curUsedM * 4 / 1024 + 1)) curSizeM=$((curSizeM * 4 / 1024)) } shrink_magisk_img () { image_size_check /data/magisk.img NEWDATASIZE=$((curUsedM / 32 * 32 + 32)) if [ "$curSizeM" -gt "$NEWDATASIZE" ]; then resize2fs $IMG ${NEWDATASIZE}M fi } mount_image() { if [ ! -d "$2" ]; then mount -o rw,remount rootfs / mkdir -p "$2" 2>/dev/null $BOOTMODE && mount -o ro,remount rootfs / [ ! -d "$2" ] && return 1 fi if ! is_mounted "$2"; then LOOPDEVICE= for LOOP in 0 1 2 3 4 5 6 7; do if ! is_mounted "$2"; then LOOPDEVICE=/dev/block/loop$LOOP [ -e $LOOPDEVICE ] || mknod $LOOPDEVICE b 7 $LOOP 2>/dev/null losetup $LOOPDEVICE "$1" && mount -t ext4 -o loop $LOOPDEVICE "$2" if is_mounted "$2"; then break; fi fi done fi } # taken from Magisk, with minor modifications for NanoDroid mount_partitions () { SLOT=$(getprop ro.boot.slot_suffix) if [ -z ${SLOT} ]; then SLOT=$(getprop ro.boot.slot) [ "${SLOT}" = "_" ] && SLOT= fi is_mounted /data || mount /data 2>/dev/null ${BOOTMODE} || mount -o bind /dev/urandom /dev/random [ ! -f /system/build.prop ] && mount -o ro /system 2>/dev/null if [ ! -f /system/build.prop ]; then SYSTEMBLOCK=$(find /dev/block -iname system${SLOT} | head -n 1) mount -t ext4 -o ro $SYSTEMBLOCK /system fi if [ -f /system/init.rc ]; then mkdir /system_root 2>/dev/null mount --move /system /system_root mount -o bind /system_root/system /system fi [ ! -f /system/build.prop ] && error "failed to mount /system" } # check for configuration files config_locations="/sdcard /external_sd /data $(dirname ${ZIP}))" config_files=".nanomod-setup .nanomod-apps .nanomod-overlay .nanodroid-setup .nanodroid-apps .nanodroid-overlay" system_mode_uninstall () { ui_print " << uninstalling: NanoDroid (System)" ui_print " << using: ${1}" system_list=${1} # services.jar needs special treament if grep -q /system/framework/services.jar ${system_list}; then if [ -f /sdcard/services.jar ]; then ui_print " << restoring: unpatched services.jar" mv /sdcard/services.jar /system/framework/services.jar \ || error " !! failed to restore services.jar" else ui_print " << can't restore unpatched services.jar" fi sed '/\/system\/framework\/services.jar/d' -i ${system_list} fi for sapp in Settings SecSettings SecSettings2; do if grep -q /system/priv-app/${sapp}/${sapp}.apk ${system_list}; then if [ -f /sdcard/${sapp}.apk ]; then ui_print " << restoring: unpatched ${sapp}.apk" mv /sdcard/${sapp}.apk /system/priv-app/${sapp}/${sapp}.apk \ || error " !! failed to restore ${sapp}.apk" else ui_print " << can't restore unpatched ${sapp}.apk" fi sed "/\/system\/priv-app\/${sapp}\/${sapp}.apk/d" \ -i ${system_list} break fi done for app in ${GOOGLE_APPS}; do if [ -d /sdcard/nanodroid_backups/priv-app/${app} ]; then ui_print " << restoring: priv-app / ${app}" mv /sdcard/nanodroid_backups/priv-app/${app} \ /system/priv-app/ || error " !! failed to restore ${app}" elif [ -d /sdcard/nanodroid_backups/app/${app} ]; then ui_print " << restoring: app / ${app}" mv /sdcard/nanodroid_backups/app/${app} \ /system/app/ || error " !! failed to restore ${app}" fi done xargs rm -f < ${system_list} || " !! failed to remove files" # remove empty directories # (find -empty not available on Android) for dir in app priv-app share; do find /system/${dir} -type d | \ xargs rmdir --ignore-fail-on-non-empty done rm -f "${system_list}" } addond_uninstall () { for addond in /data/nanomod.patcher /data/adb/nanomod_patcher \ /data/adb/nanodroid_patcher; do [ -d ${addond} ] && rm -rf ${addond} done for addonsh in /system/addon.d/75-nanomodpatcher.sh \ /system/addon.d/75-nanodroidpatcher.sh; do [ -f ${addonsh} ] && rm -f ${addonsh} done for pfile in /system/.nanomod-patcher /data/adb/.nanomod-patcher \ /data/adb/.nanodroid-patcher; do [ -f ${pfile} ] && ${pfile} done } ui_print " " ui_print "*****************************" ui_print " NanoDroid 15.90.20180119 " ui_print " created by Nanolx " ui_print " Uninstaller " ui_print "*****************************" ui_print " " mount_partitions ui_print " << Removing configuration files (if any)" for path in ${config_locations}; do for file in ${config_files}; do if [ -f "${path}/${file}" ]; then rm -f "${path}/${file}" ui_print " <<> removing ${path}/${file}" fi done done # System Mode uninstallation for install_info in /system/.nanomod-list /data/adb/.nanomod-list \ /data/adb/.nanodroid-list; do if [ -f ${install_info} ]; then system_mode_uninstall ${install_info} fi done addond_uninstall if [ -f /data/adb/magisk.img ]; then mkdir -p /magisk mount_image /data/adb/magisk.img /magisk || \ error " !! failed to mount /magisk" elif [ -f /data/magisk.img ]; then mkdir -p /magisk mount_image /data/magisk.img || \ error " !! failed to mount /magisk" fi if (is_mounted /magisk); then for module in NanoMod NanoDroid NanoModmicroG NanoDroid_microG \ NanoModfdroid NanoDroid_FDroid; do if [ -d /magisk/${module} ]; then ui_print " << uninstalling: ${module}" rm -rf /magisk/${module} fi done fi ui_print " >> clean up" if (is_mounted /magisk); then umount /magisk losetup -d $LOOPDEVICE rmdir /magisk shrink_magisk_img || \ error " !! failed to shrink magisk.img" fi umount /system ui_print " " ui_print " > Done!" ui_print " " ui_print "Thanks for giving NanoDroid a try" ui_print " " exit 0