#!/sbin/sh VERSION=20.2.90.99999999 NANODROID_UPGRADE=0 INSTALL_SUCCESS=TRUE NANODROID_LIST=/data/adb/NanoDroid_FileList GOOGLE_APPS="AMAPNetworkLocation BaiduNetworkLocation BlankStore com.qualcomm.location DejaVuBackend DejaVuNlpBackend FDroidPriv GmsCoreSetupPrebuilt GmsCore_update GmsDroidGuard GoogleFeedback GoogleLoginService GoogleOneTimeInitializer GoogleServicesFramework GoogleTTS IchnaeaNlpBackend LegacyNetworkLocation MarketUpdater MarkupGoogle MozillaNlpBackend NetworkLocation NominatimGeocoderBackend NominatimNlpBackend PlayGames PlayStore PrebuiltGmsCore PrebuiltGmsCorePix UnifiedNlp Velvet Vending WhisperPush" GOOGLE_DATA="com.amap.android.location com.baidu.location com.google.android.feedback com.google.android.gsf.login com.google.android.location com.google.android.youtube com.mgoogle.android.gms com.qualcomm.location org.microg.nlp org.microg.unifiednlp" GOOGLE_DATA_DIRTY="com.google.android.gms com.google.android.gsf com.android.vending" ########################################################################################## # Misc. Functions ########################################################################################## detect_bootmode () { [ -z ${BOOTMODE} ] && BOOTMODE=false ${BOOTMODE} || ps | grep zygote | grep -qv grep && BOOTMODE=true ${BOOTMODE} || ps -A | grep zygote | grep -qv grep && BOOTMODE=true ${BOOTMODE} && error "${MODID} can't be installed from Magisk Manager!" } ui_print() { if ${BOOTMODE}; then echo "${@}" else echo -n -e "ui_print ${@}\n" >> /proc/self/fd/${OUTFD} echo -n -e "ui_print\n" >> /proc/self/fd/${OUTFD} fi } show_progress() { echo "progress ${1} ${2}" >> /proc/self/fd/${OUTFD} } set_progress() { echo "set_progress ${1}" >> /proc/self/fd/${OUTFD} } grep_prop() { REGEX="${1}" shift FILES="${@}" [ -z "${@}" ] && FILES='/system/build.prop' sed -n "s/^${REGEX}=//p" ${FILES} | \ head -n 1 } grep_cmdline() { local REGEX="s/^${1}=//p" sed -E 's/ +/\n/g' /proc/cmdline | \ sed -n "${REGEX}" 2>/dev/null } 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 $? } set_perm () { chown ${2}:${3} ${1} || error "failed change owner for ${1}" chmod ${4} ${1} || error "failed to change mode for ${1}" if [ ! -z "${5}" ]; then chcon ${5} ${1} 2>/dev/null else chcon 'u:object_r:system_file:s0' ${1} 2>/dev/null fi } set_perm_recursive() { find ${1} -type d 2>/dev/null | while read dir; do set_perm ${dir} ${2} ${3} ${4} ${6} done find ${1} -type f 2>/dev/null | while read file; do set_perm ${file} ${2} ${3} ${5} ${6} done } set_perm_data () { if [ "${1}" = "-r" ]; then echo " perm: data [recursive] {${2}}" set_perm_recursive ${2} 0 0 0755 0644 else echo " perm: data [single] {${1}}" set_perm ${1} 0 0 0644 fi } set_perm_bin () { if [ "${1}" = "-r" ]; then echo " perm: exec [recursive] {${2}}" set_perm_recursive ${2} 0 0 0755 0755 else echo " perm: exec [single] {${1}}" set_perm ${1} 0 0 0755 fi } installinfo_add () { if [ "${MODE}" = "SYSTEM" ]; then for file in ${@}; do echo ${file} >> ${NANODROID_LIST} done fi } detect_outfd () { if [ -z $OUTFD ] || readlink /proc/$$/fd/$OUTFD | grep -q /tmp; then # We will have to manually find out OUTFD for FD in `ls /proc/$$/fd`; do if readlink /proc/$$/fd/$FD | grep -q pipe; then if ps | grep -v grep | grep -q " 3 $FD "; then OUTFD=$FD break fi fi done fi } show_banner () { ui_print " " ui_print "*****************************" ui_print " NanoDroid ${VERSION} " ui_print " created by Nanolx " case ${MODID} in NanoDroid ) ui_print " Full package " ;; NanoDroid_microG ) ui_print " microG package " ;; NanoDroid_FDroid ) ui_print " F-Droid package " ;; NanoDroid_BromiteWebView ) ui_print " Bromite WebView package " ;; NanoDroid_OsmAnd ) ui_print " OsmAnd package " ;; esac ui_print "*****************************" ui_print " " } error () { ui_print " !!" ui_print "${@}" ui_print " !!" if [ "${MODE}" = "MAGISK" ]; then rm -rf "${MODPATH}" unmount_magisk_img fi recovery_cleanup INSTALL_SUCCESS=FALSE nanodroid_storelogs exit 1 } # taken from Magisk, with minor modifications for NanoDroid mount_partitions () { SLOT=$(grep_cmdline androidboot.slot_suffix) if [ -z ${SLOT} ]; then SLOT=_$(grep_cmdline androidboot.slot) [ "${SLOT}" = "_" ] && SLOT= fi is_mounted /data || mount /data || error "failed to mount /data!" mount -o bind /dev/urandom /dev/random ! is_mounted /system && mount -o rw /system if [ ! -f /system/build.prop ]; then SYSTEMBLOCK=$(find /dev/block -iname system${SLOT} | head -n 1) mount -t ext4 -o rw ${SYSTEMBLOCK} /system fi [ -f /system/build.prop ] || is_mounted /system || error "failed to mount /system (unsupported A/B device?)" if [ -f /system/init ]; 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 (unsupported A/B device?)" if [ -L /system/vendor ]; then ! is_mounted /vendor && mount /vendor if ! is_mounted /vendor; then VENDORBLOCK=$(find /dev/block -iname vendor${SLOT} | head -n 1) mount -t ext4 -o ro ${VENDORBLOCK} /vendor fi elif [ -d /system/vendor ]; then ### XXX work-around required for some ROMs echo " xxx compat /vendor link created!" ln -sf /system/vendor /vendor >/dev/null fi mount | awk '{print $1 " on " $3}' } migrate_magisk_custom () { if [ ! -d /data/adb/ ]; then mkdir -p /data/adb/ chown root:root /data/adb chmod 0644 /data/adb fi mv ${1} /data/adb/magisk cp /data/adb/magisk/magisk.apk /data/adb/magisk.apk } detect_mode () { [ -f /data/adb/.nanodroid-list ] && mv /data/adb/.nanodroid-list "${NANODROID_LIST}" case "${nanodroid_forcesystem}" in 1 ) MODE_DETECT=forced MODE=SYSTEM ;; 0 | *) MODE_DETECT=detected if [ -f /data/adb/magisk/magisk ]; then MODE=MAGISK elif [ -f /data/.magisk/magisk ]; then migrate_magisk_custom /data/.magisk/ MODE=MAGISK elif [ -f /data/magisk/magisk ]; then migrate_magisk_custom /data/magisk/ MODE=MAGISK else MODE=SYSTEM fi ;; esac ui_print " > Mode | ${MODE} | ${MODE_DETECT}" ui_print " " if [ "${MODE}" = "SYSTEM" ]; then if [ -f "${NANODROID_LIST}" ]; then NANODROID_UPGRADE=1 else NANODROID_UPGRADE=0 fi recovery_actions fi [ "${MODE}" = "MAGISK" ] && magisk_install_setup if [ "${nanodroid_fonts}" -eq 1 ]; then if test -h ${MODPATH}/system/fonts/Roboto-Regular.ttf; then CUSTOM_FONT="$(basename $(readlink ${MODPATH}/system/fonts/Roboto-Regular.ttf) .ttf)" ui_print " << Detected NanoDroid-Font (${CUSTOM_FONT})" fi fi if [ "${MODE}" = "MAGISK" ]; then case ${MODID} in NanoDroid | NanoDroid_microG ) magisk_install_preinst ;; esac rm -rf "${MODPATH}" else unset MODPATH fi if [ "${ROM_NO_XBIN}" -eq 0 ]; then NANODROID_BINDIR="${MODPATH}/system/xbin" else NANODROID_BINDIR="${MODPATH}/system/bin" fi } unpack_zip () { TMPDIR=/dev/tmp TMP_LIBDIR=${TMPDIR}/nanodroid-lib INSTALLER=${TMPDIR}/install rm -rf ${INSTALLER} mkdir -p ${INSTALLER} || error "failed to prepare environment!" ui_print " > prepare installation" unzip -o "${ZIP}" -d "${INSTALLER}" || \ error "failed to prepare environment!" } nanodroid_finalize () { case ${MODID} in NanoDroid | NanoDroid_microG ) if [ "${nanodroid_overlay}" -eq 1 ]; then ui_print " << with /system applications override" ${NANODROID_BINDIR}/nanodroid-overlay --create else ui_print " << without /system applications override" fi ;; esac if [ "${MODE}" = "MAGISK" ]; then magisk_install_finish else install_addond recovery_cleanup sort ${NANODROID_LIST} | uniq > /tmp/nanodroid-list mv /tmp/nanodroid-list ${NANODROID_LIST} fi rm -rf ${INSTALLER} ui_print " " ui_print " Thanks for using NanoDroid " ui_print " " sync nanodroid_storelogs umount -l /system_root 2>/dev/null umount -l /system 2>/dev/null umount -l /vendor 2>/dev/null umount -l /dev/random 2>/dev/null } ########################################################################################## # Architecture detection ########################################################################################## detect_arch () { SDK_VERSION=$(grep_prop ro.build.version.sdk) ABI=$(grep_prop ro.product.cpu.abi | cut -c-3) ABI2=$(grep_prop ro.product.cpu.abi2 | cut -c-3) ABILONG=$(grep_prop ro.product.cpu.abi) ARCH=arm [ "$ABI" = "x86" ] && ARCH=x86 [ "$ABI2" = "x86" ] && ARCH=x86 [ "$ABILONG" = "arm64-v8a" ] && ARCH=arm64 [ "$ABILONG" = "x86_64" ] && ARCH=x86_64 case ${ARCH} in arm ) BIN_ARCH="arm" LIB_ARCHES="armeabi-v7a armeabi" SWIPE_LIBDIR=lib ;; arm64 ) BIN_ARCH="arm" LIB_ARCHES="arm64-v8a armeabi-v7a armeabi" SWIPE_LIBDIR=lib64 ;; x86 ) BIN_ARCH="x86" LIB_ARCHES="x86 armeabi-v7a armeabi" SWIPE_LIBDIR=lib ;; x86_64 ) BIN_ARCH="x86" LIB_ARCHES="x86_64 x86 armeabi-v7a armeabi" SWIPE_LIBDIR=lib64 ;; esac chmod +x "${INSTALLER}/system/xbin/unzip.${BIN_ARCH}" case ${SDK_VERSION} in 19 ) GSYNC_VER=K ;; 21 | 22 ) GSYNC_VER=L ;; 23 ) GSYNC_VER=M ;; 24 | 25 ) GSYNC_VER=N ;; 26 | 27 ) GSYNC_VER=O ;; 28 ) GSYNC_VER=P ;; * ) GSYNC_UNSUPPORTED=1 ;; esac case ${ARCH} in arm ) case ${SDK_VERSION} in 19 | 21 | 22 | 23 | 27 | 28 ) LIBJNI_IME=libjni_latinimegoogle.so_${SDK_VERSION} ;; 24 | 25 | 26 ) LIBJNI_IME=libjni_latinimegoogle.so_23 ;; * ) SWIPE_UNSUPPORTED=1 ;; esac ;; arm64 ) case ${SDK_VERSION} in 21 | 22 | 23 | 27 | 28 ) LIBJNI_IME=libjni_latinimegoogle.so_${SDK_VERSION} ;; 24 | 25 | 26 ) LIBJNI_IME=libjni_latinimegoogle.so_23 ;; * ) SWIPE_UNSUPPORTED=1 ;; esac ;; x86 | x86_64 ) case ${SDK_VERSION} in 19 | 21 | 22 ) SWIPE_UNSUPPORTED=1 ;; 23 | 24 | 25 | 26 | 27 | 28 ) LIBJNI_IME=libjni_latinimegoogle.so ;; * ) SWIPE_UNSUPPORTED=1 ;; esac ;; esac if [[ "${SDK_VERSION}" -lt 21 ]]; then UNFOLD_APP_DIR=1 else UNFOLD_APP_DIR=0 fi if [[ "${SDK_VERSION}" -lt 19 ]]; then ui_print " " ui_print " ++ Installing on pre-KitKat ROM, full" ui_print " ++ compatibility is not garantueed!" ui_print " " fi if [ ! -d /system/xbin ]; then ROM_NO_XBIN=1 echo " ++ ROM has no /system/xbin, using /system/bin instead" else ROM_NO_XBIN=0 fi [ ! -d /data/adb ] && mkdir /data/adb } setup_busybox () { OLD_PATH=${PATH} mkdir -p ${INSTALLER}/busybox ln -s ${INSTALLER}/busybox.${BIN_ARCH} ${INSTALLER}/busybox/busybox chmod 0755 ${INSTALLER}/busybox.${BIN_ARCH} ${INSTALLER}/busybox.${BIN_ARCH} --install -s ${INSTALLER}/busybox/ export PATH="${INSTALLER}/busybox:${PATH}" } # Taken from Magisk, used for System Mode installation recovery_actions () { mv /sbin /sbin_tmp OLD_LD_LIB=$LD_LIBRARY_PATH OLD_LD_PRE=$LD_PRELOAD unset LD_LIBRARY_PATH unset LD_PRELOAD } # Taken from Magisk, used for System Mode installation recovery_cleanup () { mv /sbin_tmp /sbin 2>/dev/null [ -z $OLD_PATH ] || export PATH=$OLD_PATH [ -z $OLD_LD_LIB ] || export LD_LIBRARY_PATH=$OLD_LD_LIB [ -z $OLD_LD_PRE ] || export LD_PRELOAD=$OLD_LD_PRE } ########################################################################################## # Magisk Mode Installation ########################################################################################## magisk_install_setup () { ui_print "******************************" ui_print "Powered by Magisk (@topjohnwu)" ui_print "******************************" ui_print " " ui_print " > setup Magisk environment" MOUNTPATH=${TMPDIR}/magisk_img MAGISKBIN=/data/adb/magisk [ -f ${MAGISKBIN}/util_functions.sh ] || \ error "Magisk version 15.0 or newer is required" . ${MAGISKBIN}/util_functions.sh MIN_VER=$(grep_prop minMagisk ${INSTALLER}/module.prop) [ ! -z ${MAGISK_VER_CODE} -a ${MAGISK_VER_CODE} -ge ${MIN_VER} ] || \ error "Magisk 15.0 or newer is required" IMG=/data/adb/magisk.img MODPATH=${MOUNTPATH}/${MODID} REALPATH=/sbin/.core/img/${MODID} recovery_actions request_size_check "${INSTALLER}" reqSizeM=$((reqSizeM + 200)) mount_magisk_img case ${MODID} in NanoDroid ) # check for sub-modules which are not # supposed to be installed alongside for dir in NanoDroid_microG NanoDroid_FDroid; do if [ -d ${MOUNTPATH}/${dir} ]; then ui_print " !! ${dir} module detected - uninstalling!" rm -rf ${MOUNTPATH}/${dir} NANODROID_UPGRADE=1 fi done ;; NanoDroid_microG | NanoDroid_FDroid ) # check for Full package and abort if found [ -d ${MOUNTPATH}/NanoDroid ] && \ error "${MODID} can't be installed along side the Full package" ;; NanoDroid_BromiteWebView | NanoDroid_OsmAnd ) true ;; * ) error "unknown module intended to be installed!?" ;; esac [ -d ${MODPATH} ] && NANODROID_UPGRADE=1 } magisk_install_preinst () { if [ -f ${MODPATH}/system.prop ]; then ui_print " << backing up module's system.prop" cp ${MODPATH}/system.prop ${TMPDIR}/system.prop fi if [ -f ${MODPATH}/system/framework/services.jar ]; then ui_print " << backing up patched services.jar" cp ${MODPATH}/system/framework/services.jar ${TMPDIR}/services.jar fi } magisk_install_postinst () { if [ -f ${TMPDIR}/system.prop ]; then ui_print " << restoring system.prop" cp ${TMPDIR}/system.prop ${MODPATH}/system.prop fi if [ -f ${TMPDIR}/services.jar ]; then ui_print " << restoring patched services.jar" mkdir -p ${MODPATH}/system/framework cp ${TMPDIR}/services.jar ${MODPATH}/system/framework/services.jar fi } magisk_install_finish () { # Magisk Module files mktouch ${MODPATH}/auto_mount cp -af ${INSTALLER}/module.prop ${MODPATH}/module.prop if [[ -f ${INSTALLER}/common/service.sh ]]; then cp -af ${INSTALLER}/common/service.sh ${MODPATH}/service.sh chmod +x ${MODPATH}/service.sh fi case ${MODID} in NanoDroid | NanoDroid_microG ) magisk_install_postinst ;; esac if [ "${nanodroid_fonts}" -eq 1 -a ! -z ${CUSTOM_FONT} ]; then ui_print " << Restore NanoDroid-Font (${CUSTOM_FONT})" ${NANODROID_BINDIR}/nanodroid-font -s "${CUSTOM_FONT}" fi unmount_magisk_img recovery_cleanup } ########################################################################################## # Generic Installation ########################################################################################## install_microg () { # install microG if requested # respectively force if it's the microG package if [ "${nanodroid_microg}" -ne 0 -o "${MODID}" = "NanoDroid_microG" ]; then # first get rid of conflicting packages for app in ${GOOGLE_APPS}; do ${NANODROID_BINDIR}/nanodroid-overlay --add ${app} rm -rf /data/dalvik-cache/*/system"@priv-app@${app}"[@\.]*@classes.* rm -rf /data/dalvik-cache/*/system"@app@${app}"[@\.]*@classes.* done for app in ${GOOGLE_DATA}; do rm -rf /data/data/${app} rm -rf /data/user/*/${app} rm -rf /data/user_de/*/${app} rm -rf /data/app/${app}-* rm -rf /mnt/asec/${app}-* rm -rf /data/media/0/Android/data/${app} done if [ "${NANODROID_UPGRADE}" -eq 0 ]; then # this removes original Play Services # only if this is a fresh NanoDroid installation rm -rf /data/dalvik-cache/*/system"@priv-app@GmsCore"[@\.]*@classes.* for app in ${GOOGLE_DATA_DIRTY}; do rm -rf /data/data/${app} rm -rf /data/user/*/${app} rm -rf /data/user_de/*/${app} rm -rf /data/app/${app}-* rm -rf /mnt/asec/${app}-* rm -rf /data/media/0/Android/data/${app} done for file in /data/system/users/*/runtime-permissions.xml; do if grep -q "com.google.android" "${file}"; then rm -f "${file}" echo " upgrade: removing ${file}" fi done if [ -f /data/system/packages.list ]; then for app in ${GOOGLE_DATA_DIRTY}; do sed -e "/${app}/d" -i /data/system/packages.list done fi fi NLPBACKEND="nlpBackendNominatim" NLPSTRING="Nominatim" if [ "${nanodroid_nlpbackend:0:1}" -eq 1 ]; then NLPBACKEND="${NLPBACKEND} nlpBackendDejavu" NLPSTRING="${NLPSTRING}, Déjà Vu" fi if [ "${nanodroid_nlpbackend:1:1}" -eq 1 ]; then NLPBACKEND="${NLPBACKEND} nlpBackendIchnaea" NLPSTRING="${NLPSTRING}, Ichnaea" fi if [ "${nanodroid_nlpbackend:2:1}" -eq 1 ]; then NLPBACKEND="${NLPBACKEND} nlpBackendApple" NLPSTRING="${NLPSTRING}, Apple" fi ui_print " << with microg [${NLPSTRING}]" if [ "${nanodroid_gmscore}" -eq 1 ]; then ui_print " ++ Official microG GmsCore" nanodroid_install_apk GmsCore_Official "" GmsCore else ui_print " ++ NanoDroid microG GmsCore" nanodroid_install_apk GmsCore_NanoDroid "" GmsCore fi if [ "${nanodroid_microg}" -ne 2 ]; then for app in GsfProxy DroidGuard; do nanodroid_install_apk ${app} done fi for app in ${NLPBACKEND}; do nanodroid_install_apk ${app} done nanodroid_install_file etc/permissions/features.xml nanodroid_install_file etc/permissions/privapp-permissions-google.xml nanodroid_install_file etc/default-permissions/microg-permissions.xml nanodroid_install_file etc/sysconfig/microg-a5k.xml else ui_print " << without microG" fi } install_mapsv1 () { # install mapsv1 if requested if [ "${nanodroid_mapsv1}" -eq 1 ]; then ui_print " << with Maps API version 1" nanodroid_install_file etc/permissions/com.google.android.maps.xml nanodroid_install_file framework/com.google.android.maps.jar else ui_print " << without Maps API version 1" fi } install_gsync () { # install GSync if requested if [ "${nanodroid_gsync}" -eq 1 ]; then if [ "${GSYNC_UNSUPPORTED}" -eq 1 ]; then ui_print " << Google Sync Adapters are unsupported on SDK ${SDK_VERSION}" else ui_print " << with Google Sync Adapters (${GSYNC_VER})" for app in GoogleCalendarSync GoogleContactsSync GoogleBackupTransport; do nanodroid_install_apk ${app} done nanodroid_install_file etc/default-permissions/contacts-calendar-sync.xml fi else ui_print " << without Google Sync Adapters" fi } install_fdroid () { # install F-Droid if requested # respectively force if it's the F-Droid package if [ "${nanodroid_fdroid}" -eq 1 -o "${MODID}" = "NanoDroid_FDroid" ]; then ui_print " << with F-Droid" nanodroid_install_apk FDroid nanodroid_install_apk FDroidPrivileged nanodroid_install_file etc/permissions/org.fdroid.fdroid.privileged.xml nanodroid_install_file etc/org.fdroid.fdroid/additional_repos.xml else ui_print " << without F-Droid" fi } install_apps () { # install apps if requested if [ "${nanodroid_apps}" -eq 1 ]; then ui_print " << with applications" APP_STRING=" <<>" INSTALL_APPS=$(cat "${cfg_apps}") for app in ${INSTALL_APPS}; do [[ -d "${INSTALLER}/system/app/${app}" ]] && \ APP_STRING="${APP_STRING} ${app}, " done ui_print "${APP_STRING}" for app in ${INSTALL_APPS}; do if [[ ${app} = OmniClock && -d /system/app/OmniClockOSS ]]; then if [ "${nanodroid_override}" -eq 0 ]; then ui_print " <<> app: OmniClock already provided by ROM (as OmniClockOSS)" else nanodroid_install_apk ${app} echo " + removing conflicting OmniClockOSS" ${NANODROID_BINDIR}/nanodroid-overlay --add OmniClockOSS fi elif [[ -d /system/app/${app} && ! -d ${MODPATH}/system/app/${app} ]]; then if [ "${nanodroid_override}" -eq 0 ]; then ui_print " <<> app: ${app} already provided by ROM" else nanodroid_install_apk ${app} fi elif [[ -d "${INSTALLER}/system/app/${app}" ]]; then nanodroid_install_apk ${app} else ui_print " <<>> app: ${app} missing" fi done else ui_print " << without applications" fi } install_store () { STORE_APPNAME="" STORE_CHOICE=${nanodroid_play:0:1} FAKE_STORE=${nanodroid_play:1:1} [ "${FAKE_STORE}" -eq 1 ] && STORE_CONFLICT="Phonesky" || STORE_CONFLICT="" # install Yalp Store or Play Store whichever requested case "${STORE_CHOICE}" in 1 ) ui_print " << with Play Store" STORE_APPNAME="Phonesky" # force unselect Fake Store when user has choosen Play Store STORE_CONFLICT="FakeStore" FAKE_STORE=0 nanodroid_install_file etc/default-permissions/phonesky-permissions.xml ;; 2 ) STORE_APPNAME="YalpStore" ;; 3 ) STORE_APPNAME="AuroraStore" ;; esac if [ ! -z "${STORE_APPNAME}" ]; then ui_print " << with ${STORE_APPNAME}" nanodroid_install_apk "${STORE_APPNAME}" else ui_print " << without App Store" fi if [ "${FAKE_STORE}" -eq 1 ]; then ui_print " << with Fake Store" nanodroid_install_apk FakeStore else ui_print " << without Fake Store" fi if [ ! -z "${STORE_CONFLICT}" ]; then ${NANODROID_BINDIR}/nanodroid-overlay --add ${STORE_CONFLICT} if [ "${NANODROID_UPGRADE}" -eq 0 ]; then rm -rf /data/data/com.android.vending rm -rf /data/user/*/com.android.vending rm -rf /data/user_de/*/com.android.vending rm -rf /data/app/com.android.vending-* fi fi } install_zelda () { # install Zelda Ringtones when requested if [ "${nanodroid_zelda}" -eq 1 ]; then ui_print " << with Zelda sounds" nanodroid_install_dir media else ui_print " << without Zelda sounds" fi } install_bash () { if [ "${nanodroid_bash}" -eq 1 ]; then ui_print " << with GNU Bash Shell" nanodroid_install_file etc/bash_logout nanodroid_install_file etc/bashrc nanodroid_install_file xbin/bash bin nanodroid_install_file xbin/bash.bin.${BIN_ARCH} bin nanodroid_install_file xbin/bashbug.${BIN_ARCH} bin nanodroid_install_file xbin/less bin nanodroid_install_file xbin/less.bin.${BIN_ARCH} bin else ui_print " << without GNU Bash Shell" fi } install_nanodroidscripts () { ui_print " << with NanoDroid Scripts" for script in npem nutl novl \ nanodroid-perm nanodroid-util \ nanodroid-overlay; do nanodroid_install_file xbin/${script} bin done nanodroid_substitute xbin/nanodroid-overlay if [ "${MODE}" = "MAGISK" ]; then for script in nprp nanodroid-prop; do nanodroid_install_file xbin/${script} bin done nanodroid_substitute xbin/nanodroid-prop fi } install_fonts () { if [ "${nanodroid_fonts}" -eq 1 ]; then ui_print " << with Nintendo Fonts" nanodroid_install_file xbin/nanodroid-font bin nanodroid_substitute xbin/nanodroid-font nanodroid_install_file xbin/nfnt bin nanodroid_install_dir fonts fi } install_nano () { if [ "${nanodroid_nano}" -eq 1 ]; then ui_print " << with GNU Nano Terminal Editor" nanodroid_install_dir etc/terminfo nanodroid_install_file xbin/nano bin nanodroid_install_file xbin/nano.bin bin else ui_print " << without GNU Nano Terminal Editor" fi } install_shell_utils () { if [ "${nanodroid_utils}" -eq 1 ]; then ui_print " << with Shell Utilities" # architecture dependend stuff for binary in col colcrt colrm column findfs findmnt \ hexdump lessecho lesskey look lsblk lscpu lsipc \ lslocks lsns ncal setterm unzip whereis; do nanodroid_install_file xbin/${binary}.${BIN_ARCH} bin done else ui_print " << without Shell Utilities" fi } install_initd () { if [ "${nanodroid_init}" -eq 1 ]; then ui_print " << with init scripts" if [ "${MODE}" = "SYSTEM" ]; then INIT_BASE="${MODPATH}/system/etc/init.d" else INIT_BASE="${MODPATH}/init.d" fi mkdir -p "${INIT_BASE}" cp "${INSTALLER}/system/etc/init.d"/* "${INIT_BASE}/" set_perm_bin "${INIT_BASE}" for init in fstrim logcat logscleaner sqlite external_sd; do installinfo_add "/system/etc/init.d/${init}" done else ui_print " << without init scripts" fi } install_bromite_webview () { if [ "${MODID}" = "NanoDroid_BromiteWebView" ]; then ui_print " << with Bromite WebView" case ${ARCH} in arm | arm64 | x86 ) BROMITE_ARCH=${ARCH} ;; x86_64 ) BROMITE_ARCH=x86 ;; esac for app in webview webviewstub Webview WebViewGoogle; do if [ -d /system/app/${app} ]; then if [ "${MODE}" = "SYSTEM" ]; then echo " backing up ${app} to /sdcard/nanodroid_backups/app/${app}" mkdir -p /sdcard/nanodroid_backups/app rm -rf /sdcard/nanodroid_backups/app/${app} mv /system/app/${app} /sdcard/nanodroid_backups/app/ elif [ "${MODE}" = "MAGISK" ]; then echo " creating overlay for ${app}" mkdir -p ${MODPATH}/system/app/${app} touch ${MODPATH}/system/app/${app}/.replace fi fi done if [ "${NANODROID_UPGRADE}" -eq 0 ]; then for app in com.android.webview com.google.android.webview; do rm -rf /data/data/${app} rm -rf /data/user/*/${app} rm -rf /data/user_de/*/${app} rm -rf /data/app/${app}-* rm -rf /mnt/asec/${app}-* rm -rf /data/media/0/Android/data/${app} done fi nanodroid_install_apk BromiteWebView_${BROMITE_ARCH} multilib BromiteWebView fi } install_osmand () { if [ "${MODID}" = "NanoDroid_OsmAnd" ]; then ui_print " << with OsmAnd" nanodroid_install_apk OsmAnd nanodroid_install_apk OsmAnd_ContourLines fi } install_swipe () { if [ "${nanodroid_swipe}" -eq 1 ]; then if [ "${SWIPE_UNSUPPORTED}" -eq 1 ]; then ui_print " << Swipe Libraries are unsupported on SDK ${SDK_VERSION}" else ui_print " << with swipe libraries" SWIPE_SRC="${INSTALLER}/swipe/${ARCH}" SWIPE_DEST="/system/${SWIPE_LIBDIR}" mkdir -p "${MODPATH}${SWIPE_DEST}" cp "${SWIPE_SRC}/libjni_keyboarddecoder.so" "${MODPATH}${SWIPE_DEST}" || \ error "failed to install libjni_keyboarddecoder.so" set_perm_data "${MODPATH}${SWIPE_DEST}/libjni_keyboarddecoder.so" cp "${SWIPE_SRC}/${LIBJNI_IME}" "${MODPATH}${SWIPE_DEST}/libjni_latinimegoogle.so" || \ error "failed to install libjni_latinimegoogle.so" set_perm_data "${MODPATH}${SWIPE_DEST}/libjni_latinimegoogle.so" installinfo_add "${SWIPE_DEST}/libjni_keyboarddecoder.so" installinfo_add "${SWIPE_DEST}/libjni_latinimegoogle.so" fi else ui_print " << without swipe libraries" fi } install_addond () { if [ -d /system/addon.d ]; then ui_print " << System Mode OTA survival" cp "${INSTALLER}/CommonAddon" "/system/addon.d/91-nanodroid.sh" || \ error "failed to install System Mode OTA survival" chmod 0755 "/system/addon.d/91-nanodroid.sh" sed -e "s|@MODID@|${MODID}|g" -i "/system/addon.d/91-nanodroid.sh" else ui_print " << ROM does not have addon.d support" fi } ########################################################################################## # Advanced Installation Functions ########################################################################################## nanodroid_install_dir () { dir="${1}" dest="/system/${dir}" [ ! -d "${INSTALLER}/system/${dir}" ] && \ error "dir: ${dir} not found" echo " installing dir: ${dir}" mkdir -p "${MODPATH}${dest}" cp -r "${INSTALLER}/system/${dir}"/* "${MODPATH}${dest}/" || \ error "failed to install ${dir}" case ${2} in bin ) set_perm_bin -r "${MODPATH}${dest}" ;; * ) set_perm_data -r "${MODPATH}${dest}" ;; esac find "${INSTALLER}/system/${dir}" -type f | \ sed -e "s,^${INSTALLER},,g" | \ installinfo_add } nanodroid_install_apk () { app=${1} multilib=${2} alias=${3} unset prefix unset source for sdir in system/app system/priv-app gsync/${GSYNC_VER}/app gsync/${GSYNC_VER}/priv-app; do if [ -f "${INSTALLER}/${sdir}/${app}/${app}.apk" ]; then source="${INSTALLER}/${sdir}/${app}/${app}.apk" dir=system/$(basename ${sdir}) break fi done [ -z "${source}" ] && error "app ${app} not found" if [ "${UNFOLD_APP_DIR}" -eq 1 ]; then dest="${MODPATH}/${dir}" else if [ -z "${alias}" ]; then dest="${MODPATH}/${dir}/${app}" else dest="${MODPATH}/${dir}/${alias}" fi fi if [ ! -z "${alias}" ]; then dest_apk=${alias}.apk else dest_apk=${app}.apk fi mkdir -p "${dest}" echo " installing app: ${app}" cp "${source}" "${dest}/${dest_apk}" || \ error "failed to install ${source} to ${dest}" installinfo_add "${dest}/${dest_apk}" nanodroid_install_lib "${dest}/${dest_apk}" "${2}" set_perm_data -r "${dest}" } nanodroid_install_file () { dir="$(dirname "${1}")" file="$(basename "${1}")" unset source for sdir in system gsync; do if [ -f "${INSTALLER}/${sdir}/${dir}/${file}" ]; then source="${INSTALLER}/${sdir}/${dir}/${file}" break fi done [ -z "${source}" ] && error "file: ${file} not found" # if /system/xbin does not exist, use /system/bin [ "${dir}" = "xbin" -a "${ROM_NO_XBIN}" -eq 1 ] && xdir="bin" || xdir="${dir}" # strip off .${BIN_ARCH} from final filename (if any) xfile=$(basename ${file} .${BIN_ARCH}) echo " installing file: ${xfile}" mkdir -p "${MODPATH}/system/${xdir}/" cp "${source}" "${MODPATH}/system/${xdir}/${xfile}" || \ error "failed to install ${xfile}" case ${2} in bin ) set_perm_bin "${MODPATH}/system/${xdir}/${xfile}" ;; * ) set_perm_data "${MODPATH}/system/${xdir}/${xfile}" ;; esac installinfo_add "/system/${xdir}/${xfile}" } nanodroid_install_lib () { apk="${1}" dest="$(dirname ${1})" multilib="${2}" unset libd if [ "${UNFOLD_APP_DIR}" -eq 1 ]; then case ${ARCH} in arm | x86 ) libd=${MODPATH}/system/lib ;; arm64 | x86_64 ) libd=${MODPATH}/system/lib64 ;; esac else libd=${dest}/lib fi rm -rf ${TMP_LIBDIR} mkdir -p ${TMP_LIBDIR} unset srcdir "${INSTALLER}/system/xbin/unzip.${BIN_ARCH}" \ -oq "${apk}" "lib/*" -d "${TMP_LIBDIR}" \ 2>/dev/null unzip_return=$? case ${unzip_return} in 0 ) echo " ${app} does have libs" ;; 11 ) echo " ${app} does not have any libs" ;; * ) error " !! installing libs for ${app} failed" ;; esac if [ -d ${TMP_LIBDIR}/lib ]; then for ARCHLIB in ${LIB_ARCHES}; do if [ -d ${TMP_LIBDIR}/lib/${ARCHLIB} ]; then srcdir=${TMP_LIBDIR}/lib/${ARCHLIB} case ${srcdir} in *arm64* ) echo " ${app}: installing arm64 libs" lib_arch=arm64 ;; *arm* ) echo " ${app}: installing arm libs" lib_arch=arm ;; *x86_64* ) echo " ${app}: installing x86_64 libs" lib_arch=x86_64 ;; *x86* ) echo " ${app}: installing x86 libs" lib_arch=x86 ;; esac echo " from: ${srcdir}" echo " into: ${libd}/${lib_arch}" mkdir -p "${libd}/${lib_arch}" for lib in ${srcdir}/*; do echo " library: $(basename ${lib})" cp ${lib} "${libd}/${lib_arch}/" || \ error "installing libraries failed" installinfo_add "/${dir}/${app}/lib/${lib_arch}/$(basename ${lib})" done [ -z "${multilib}" ] && break fi done fi } nanodroid_substitute () { dir="$(dirname "${1}")" file="$(basename "${1}")" # if /system/xbin does not exist, use /system/bin [ "${dir}" = "xbin" -a "${ROM_NO_XBIN}" -eq 1 ] && dir="bin" target="${MODPATH}/system/${dir}/${file}" [ ! -f "${target}" ] && error "file: ${file} not found" if grep -q @ZIPDIR@ "${target}"; then if [[ "${ZIPDIR}" == "/external_sd" ]]; then # /external_sd is already known by `nanodroid-overlay` # no need to add it a second time sed -e 's|@ZIPDIR@||' -i ${target} echo " substitute: remove @ZIPDIR@ in ${target}" else sed -e "s|@ZIPDIR@|${ZIPDIR}|g" -i ${target} echo " substitute: adjust @ZIPDIR@ in ${target}" fi fi if grep -q @MODPATH@ ${target}; then sed -e "s|@MODPATH@|${REALPATH}|g" -i ${target} echo " substitute: adjust @MODPATH@ in ${target}" fi } nanodroid_storelogs () { curdate=$(date +%Y%m%d_%H.%M.%S) nanodroid_logfile="/data/adb/${MODID}_log_${curdate}" nanodroid_twrplog="/data/adb/${MODID}_twrp_${curdate}" echo "\ Installation successful: ${INSTALL_SUCCESS} ### VALUES ### ZIP=${ZIP} ZIPDIR=${ZIPDIR} TMPDIR=${TMPDIR} TMP_LIBDIR=${TMP_LIBDIR} INSTALLER=${INSTALLER} MODID=${MODID} SDK_VERSION=${SDK_VERSION} ARCH=${ARCH} LIB_ARCHES=${LIB_ARCHES} MODPATH=${MODPATH} SWIPE_LIBDIR=${SWIPE_LIBDIR} REALPATH=${REALPATH} MODE=${MODE} MAGISK_VER_CODE=${MAGISK_VER_CODE} CUSTOM_FONT=${CUSTOM_FONT} ROM_NO_XBIN=${ROM_NO_XBIN} NANODROID_UPGRADE=${NANODROID_UPGRADE} NANODROID_BINDIR=${NANODROID_BINDIR} ### SETUP ### " > ${nanodroid_logfile} cat "${cfg_setup}" >> ${nanodroid_logfile} if [ ! -z "${cfg_apps}" ]; then echo " ### APPS ### " >> ${nanodroid_logfile} cat "${cfg_apps}" >> ${nanodroid_logfile} fi if [ ! -z "${cfg_overlay}" ]; then echo " ### OVERLAY ### " >> ${nanodroid_logfile} cat "${cfg_overlay}" >> ${nanodroid_logfile} fi cat /tmp/recovery.log > ${nanodroid_twrplog} ui_print " | storing installation logs in /data/adb/" ui_print " | TWRP log:" ui_print " || $(basename ${nanodroid_twrplog})" ui_print " | NanoDroid log:" ui_print " || ""$(basename ${nanodroid_logfile})" ui_print " " } ########################################################################################## # NanoDroid Configuration File Handling ########################################################################################## # check for configuration files config_locations="/sdcard /external_sd ${ZIPDIR} /data" get_config () { config="" config_exists=0 for path in ${config_locations}; do if test -r "${path}/.nanodroid-${1}"; then config="${path}/.nanodroid-${1}" config_exists=1 return fi done } set_prop () { echo "${1}=${2}" >> "${cfg_setup}" } # check whether '.nanodroid-setup' has all required entries check_cfg_setup () { source "${cfg_setup}" [ -z "${nanodroid_fdroid}" ] && set_prop nanodroid_fdroid 1 [ -z "${nanodroid_microg}" ] && set_prop nanodroid_microg 1 [ -z "${nanodroid_gmscore}" ] && set_prop nanodroid_gmscore 0 [ -z "${nanodroid_apps}" ] && set_prop nanodroid_apps 1 [ -z "${nanodroid_play}" ] && set_prop nanodroid_play 10 # in NanoDroid <= 20.2 nanodroid_play has changed if [ "${#nanodroid_play}" -lt 2 ]; then case "${nanodroid_play}" in 0 ) tmp_prop="00" ;; 1 ) tmp_prop="10" ;; 2 ) tmp_prop="20" ;; 3 ) tmp_prop="01" ;; 4 ) tmp_prop="21" ;; * ) tmp_prop="10" ;; esac sed -e '/^nanodroid_play/d' -i "${cfg_setup}" set_prop nanodroid_play "${tmp_prop}" fi if [ "${MODID}" = "NanoDroid" ]; then [ -z "${nanodroid_overlay}" ] && set_prop nanodroid_overlay 1 else [ -z "${nanodroid_overlay}" ] && set_prop nanodroid_overlay 0 fi [ -z "${nanodroid_zelda}" ] && set_prop nanodroid_zelda 1 [ -z "${nanodroid_mapsv1}" ] && set_prop nanodroid_mapsv1 1 [ -z "${nanodroid_init}" ] && set_prop nanodroid_init 1 [ -z "${nanodroid_gsync}" ] && set_prop nanodroid_gsync 0 [ -z "${nanodroid_forcesystem}" ] && set_prop nanodroid_forcesystem 0 [ -z "${nanodroid_swipe}" ] && set_prop nanodroid_swipe 0 [ -z "${nanodroid_nlpbackend}" ] && set_prop nanodroid_nlpbackend 100 # in NanoDroid <= 20.2 nanodroid_nlpbackend has changed if [ "${#nanodroid_nlpbackend}" -eq 1 ]; then case "${nanodroid_nlpbackend}" in 0 ) tmp_prop="000" ;; 1 ) tmp_prop="100" ;; 2 ) tmp_prop="010" ;; 3 ) tmp_prop="110" ;; * ) tmp_prop="100" ;; esac sed -e '/^nanodroid_nlpbackend/d' -i "${cfg_setup}" set_prop nanodroid_nlpbackend "${tmp_prop}" fi [ -z "${nanodroid_bash}" ] && set_prop nanodroid_bash 1 [ -z "${nanodroid_nano}" ] && set_prop nanodroid_nano 1 [ -z "${nanodroid_utils}" ] && set_prop nanodroid_utils 1 [ -z "${nanodroid_fonts}" ] && set_prop nanodroid_fonts 1 [ -z "${nanodroid_override}" ] && set_prop nanodroid_override 0 source "${cfg_setup}" } # check whether '.nanodroid-apps' is up to date check_cfg_apps () { # <= 16.3 has KeePass DX instead of KeePassDroid, migrate if grep -q KeePassDroid "${cfg_apps}"; then sed -e 's/KeePassDroid/KeePassDX/g' -i "${cfg_apps}" fi # <= 17.0~beta1 && <= 17.2~beta1 has Bucket (LibreSubtratum) instead of Substratum, migrate if grep -q Bucket "${cfg_apps}"; then sed -e 's/Bucket/Substratum/g' -i "${cfg_apps}" fi # <= 18.1 has Orfox instead of TorBrowser, migrate if grep -q Orfox "${cfg_apps}"; then sed -e 's/Orfox/TorBrowser/g' -i "${cfg_apps}" fi # <= 18.4 has Adaway instead of Blockada, migrate if grep -q Adaway "${Blockada}"; then sed -e 's/Adaway/Blockada/g' -i "${cfg_apps}" fi } # check whether '.nanodroid-overlay' is up to date check_cfg_overlay () { return 0 } get_cfg_setup () { get_config setup if [ "$config_exists" -eq 1 ]; then cfg_setup="${config}" check_cfg_setup ui_print " > Config | nanodroid-setup | $(dirname ${cfg_setup})" else cfg_setup="${INSTALLER}/.nanodroid-setup" source "${cfg_setup}" ui_print " > Config | nanodroid-setup | fallback" fi } get_cfg_overlay () { get_config overlay if [ "$config_exists" -eq 1 ]; then cfg_overlay="${config}" check_cfg_overlay ui_print " > Config | nanodroid-overlay | $(dirname ${cfg_overlay})" else cfg_overlay="${INSTALLER}/.nanodroid-overlay" ui_print " > Config | nanodroid-overlay | fallback" fi } get_cfg_apps () { get_config apps if [ "$config_exists" -eq 1 ]; then cfg_apps="${config}" check_cfg_apps ui_print " > Config | nanodroid-apps | $(dirname ${cfg_apps})" else cfg_apps="${INSTALLER}/.nanodroid-apps" ui_print " > Config | nanodroid-apps | fallback" fi }