#!/sbin/sh

VERSION=22.8.20200901
NANODROID_UPGRADE=0
INSTALL_SUCCESS=TRUE
NANODROID_LIST=/data/adb/NanoDroid_FileList

STORAGE=/data/media/0
curdate=$(date +%Y%m%d_%H.%M.%S)
nanodroid_logfile="${STORAGE}/nanodroid_logs/${MODID}_${VERSION}_log_${curdate}.log"

print_google_apps()
{
cat <<EOF
AMAPNetworkLocation
BaiduNetworkLocation
BlankStore
ConfigUpdater
GCS
GmsCoreSetupPrebuilt
GmsCore_update
GoogleFeedback
GoogleLoginService
GoogleOneTimeInitializer
GoogleServicesFramework
GoogleConnectivityServices
GoogleTTS
LegacyNetworkLocation
MarketUpdater
MarkupGoogle
NetworkLocation
Phonesky
PlayGames
PlayStore
PrebuiltGmsCore
PrebuiltGmsCorePi
PrebuiltGmsCorePix
UnifiedNlp
Velvet
Vending
WhisperPush
EOF
}

print_google_data ()
{
cat <<EOF
com.amap.android.location
com.baidu.location
com.google.android.location
org.microg.nlp
org.microg.unifiednlp
EOF
}

print_google_data_dirty ()
{
cat <<EOF
com.android.vending
com.google.android.gms
com.google.android.gsf
com.google.android.gsf.login
com.google.android.feedback
com.mgoogle.android.gms
EOF
}

##########################################################################################
# Misc. Functions
##########################################################################################

decho () {
	mkdir -p "${STORAGE}/nanodroid_logs"

	if ${BOOTMODE}; then
		echo "$@" >> "${nanodroid_logfile}"
	else
		echo "$@"
	fi
}

check_space () {
	space_required=524288
	space_available=$(df /dev 2>/dev/null | awk '/tmpfs/{print $4}')

	decho "  required space : ${space_required}"
	decho "  available space: ${space_available}"

	if [ ${space_available} -lt ${space_required} ]; then
		error "Less than 512 MB free space availabe from TWRP!"
	fi
}

detect_bootmode () {
	[ -z ${BOOTMODE} ] && ps | grep zygote | grep -qv grep && BOOTMODE=true
	[ -z ${BOOTMODE} ] && ps -A 2>/dev/null | grep zygote | grep -qv grep && BOOTMODE=true
	[ -z ${BOOTMODE} ] && BOOTMODE=false
}

print_info () {
	if ${BOOTMODE}; then
		echo "${@}"
		decho "${@}"
	else 
		echo -n -e "ui_print ${@}\n" >> /proc/self/fd/${OUTFD}
		echo -n -e "ui_print\n" >> /proc/self/fd/${OUTFD}
	fi
}

show_progress() {
	${BOOTMODE} || echo "progress ${1} ${2}" >> /proc/self/fd/${OUTFD}
}

set_progress() {
	${BOOTMODE} || echo "set_progress ${1}" >> /proc/self/fd/${OUTFD}
}

grep_prop() {
	sed -n "s/^${1}=//p" ${build_props} | 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 () {
	grep -q "$(readlink -f ${1})" /proc/mounts 2>/dev/null
	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
		decho "    perm: data [recursive] {${2}}"
		set_perm_recursive ${2} 0 0 0755 0644
	else
		decho "    perm: data [single] {${1}}"
		set_perm ${1} 0 0 0644
	fi
}

set_perm_bin () {
	if [ "${1}" = "-r" ]; then
		decho "    perm: exec [recursive] {${2}}"
		set_perm_recursive ${2} 0 0 0755 0755
	else
		decho "    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 () {
	print_info " "
	print_info "*****************************"
	print_info " NanoDroid                   "
	case ${MODID} in
		NanoDroid )
			print_info " > Full package              "
		;;
		NanoDroid_microG )
			print_info " > microG package            "
		;;
		NanoDroid_FDroid )
			print_info " > F-Droid package           "
		;;
		NanoDroid_BromiteWebView )
			print_info " > Bromite WebView package   "
		;;
		NanoDroid_OsmAnd )
			print_info " > OsmAnd package            "
		;;
		NanoDroid_Google )
			print_info " > Google package            "
		;;
	esac

	if [ "${ZIP}" == *${VERSION}* ]; then
		print_info " ${VERSION}                  "
	else
		print_info " ${VERSION} (snapshot)       "
	fi

	print_info "*****************************"
	print_info " "
}

error () {
	print_info " !!"
	print_info "${@}"
	print_info " !!"

	if is_mounted /data; then
		[ "${MODE}" = "MAGISK" ] && rm -rf "${MODPATH}"

		recovery_cleanup_env

		INSTALL_SUCCESS=FALSE
		nanodroid_storelogs
	fi

	exit 1
}

# taken from Magisk, with modifications for NanoDroid
mount_apex_loop () {
	local number=0
	local minorx=1
	local loop

	[ -e /dev/block/loop1 ] && minorx=$(stat -Lc '%T' /dev/block/loop1)

	apex_mount="${1}"

	echo " *** mount_apex_loop [apex_mount]: ${apex_mount}"

	while [ ${number} -lt 64 ]; do
		loop=/dev/block/loop${number}
		[ -e ${loop} ] || mknod ${loop} b 7 $((number * minorx))

		if losetup "${loop}" /apex/apex_payload.img 2>/dev/null; then
			echo " *** mount_apex_loop [loop]: ${loop}"
			if mount -text4 -oro,noatime "${loop}" "${apex_mount}"; then
				rm -f /apex/apex_payload.img
				break
			fi
		fi

		number=$((number + 1))
	done
}

# taken from Magisk, with modifications for NanoDroid
mount_apex () {
	APEX_LD=/apex/com.android.runtime

	mkdir -p /apex

	for apex in /system/apex/*; do
		apex_mount="/apex/$(basename ${apex} .apex)"
		apex_loop="/dev/loop_apex_$(basename ${apex} .apex)"

		[ "${apex_mount}" == /apex/com.android.runtime.release ] && apex_mount=/apex/com.android.runtime
		[ "${apex_mount}" == /apex/com.android.runtime.debug ] && apex_mount=/apex/com.android.runtime

		mkdir -p "${apex_mount}"

		if [ -f "${apex}" ]; then
			unzip -oq "${apex}" apex_payload.img -d /apex
			mount_apex_loop "${apex_mount}" || error "APEX loop setup failed!"
		elif [ -d "${apex}" ]; then
			mount -o bind "${apex}" "${apex_mount}"
		fi
	done

	export ANDROID_RUNTIME_ROOT=/apex/com.android.runtime
	export ANDROID_TZDATA_ROOT=/apex/com.android.tzdata

	echo " INFO: #10 [APEX_LD] ${APEX_LD}"
	echo " INFO: #11 [APEX [ALL]] $(ls /system/apex/*)"
}

# taken from Magisk, with minor modifications for NanoDroid
mount_partitions () {
	if ${BOOTMODE}; then
		APEX_LD=/apex/com.android.runtime
		build_props=$(find /system /system_root /vendor -type f -name build.prop)
	else
		DEVICE_AB=FALSE
		VENDOR_COMPAT=FALSE
		SYSTEM_AS_ROOT=FALSE

		SLOT=$(grep_cmdline androidboot.slot_suffix)
		echo " INFO: #1 [SLOT] ${SLOT}"
		if [ -z ${SLOT} ]; then
			SLOT=$(grep_cmdline androidboot.slot)
			echo " INFO: #2 [SLOT] ${SLOT}"
			if [ ! -z ${SLOT} ]; then
				SLOT=_${SLOT}
				echo " INFO: #3 [SLOT] ${SLOT}"
				DEVICE_AB=TRUE
			fi
		fi

		system_tmp=$(find /dev/block \( -type b -o -type c -o -type l \) -name system${SLOT} | head -n 1)
		echo " INFO: #4 [system_tmp] ${system_tmp}"
		SYSTEM_BLOCK=$(readlink -f ${system_tmp})
		echo " INFO: #5 [SYSTEM_BLOCK] ${SYSTEM_BLOCK}"

		is_mounted /data || mount /data || error "failed to mount /data!"

		mount -o bind /dev/urandom /dev/random
		! is_mounted /system && mount -o rw /system
		! is_mounted /system && mount -o rw ${SYSTEM_BLOCK} /system
		! is_mounted /system && error "failed to mount /system!"

		if [ -f /system/init.rc ]; then
			SYSTEM_AS_ROOT=true
			[ -L /system_root ] && rm -f /system_root
			mkdir /system_root 2>/dev/null
			mount --move /system /system_root
			mount -o bind /system_root/system /system
		fi

		vendor_tmp=$(find /dev/block \( -type b -o -type c -o -type l \) -name vendor${SLOT} | head -n 1)
		echo " INFO: #6 [vendor_tmp] ${vendor_tmp}"
		VENDOR_BLOCK=$(readlink -f ${vendor_tmp})
		echo " INFO: #7 [VENDOR_BLOCK] ${VENDOR_BLOCK}"

		! is_mounted /vendor && mount -o ro /vendor || mount -o ro ${VENDOR_BLOCK} /vendor

		if [ -d /system/vendor ]; then
			### XXX work-around required for some ROMs
			VENDOR_COMPAT=TRUE
			ln -sf /system/vendor /vendor >/dev/null
		fi

		echo " "
		mount | sed -e '/magisk/d' | awk '{print $1 " on " $3 " params: " $6}'
		echo " "

		echo " INFO: #8 [prop]"
		ls -l /system/*.prop

		build_props=$(find /system /system_root /vendor -type f -name build.prop)
		echo " INFO: #9 [build_props] ${build_props}"

		[ -z "${build_props}" ] && error "failed to mount /system (unsupported A/B device?)"

		[ -d /system/apex ] && mount_apex
	fi
}

umount_partitions () {
	umount -l /system_root 2>/dev/null
	umount -l /system 2>/dev/null
	umount -l /system/vendor 2>/dev/null
	umount -l /vendor 2>/dev/null
	umount -l /dev/random 2>/dev/null

	mount | awk '/ \/apex/{print $3}' | while read apex_mount; do
		umount -l "${apex_mount}" 2>/dev/null
	done

	mount | awk '/ \/apex/{print $1}' | while read apex_loop; do
		losetup -d "${apex_loop}" 2>/dev/null
	done

	rm -rf /apex

	unset ANDROID_RUNTIME_ROOT
	unset ANDROID_TZDATA_ROOT
}

detect_mode () {
	case "${nanodroid_forcesystem}" in
		1 )
			MODE_DETECT=forced
			MODE=SYSTEM
		;;

		0 | *)
			MODE_DETECT=detected
			MODE=SYSTEM

			if [ -f /data/adb/magisk/util_functions.sh ]; then
				. /data/adb/magisk/util_functions.sh

				if [ ${MAGISK_VER_CODE} -ge 19000 ]; then
					MODE=MAGISK
				else
					print_info " "
					print_info "Magisk 19.0 or newer is required!"
					print_info "falling back to /system installation!"
					print_info " "
					MODE=SYSTEM
				fi
			fi
		;;
	esac

	print_info " > Mode   | ${MODE}            | ${MODE_DETECT}"
	print_info " "

	case ${MODE} in
		SYSTEM )
			recovery_setup_env
			unset MODPATH

			[ -f "${NANODROID_LIST}" ] &&  NANODROID_UPGRADE=1
		;;

		MAGISK )
			magisk_install_setup

			case ${MODID} in
				NanoDroid | NanoDroid_microG )
					magisk_install_preinst
				;;
			esac
		;;
	esac

	[ "${ROM_NO_XBIN}" -eq 1 ] && \
		NANODROID_BINDIR="${MODPATH}/system/bin" || \
		NANODROID_BINDIR="${MODPATH}/system/xbin"
}

detect_migrate_microg () {
	GMSCORE_PATH=$(find /data/app -type d -name 'com.google.android.gms-*' 2>/dev/null)

	if [ ! -z ${GMSCORE_PATH} ]; then
		if [ -n "${1}" ]; then
			if ! ${UNZIP} -l "${GMSCORE_PATH}/base.apk" | grep META-INF/NANOLX.RSA 2>/dev/null; then
				decho "    + Removing Official microG GmsCore in favor of NanoDroid microG GmsCore"
				rm -rf "${GMSCORE_PATH}"

				decho "    + Resetting GCM/FCM connection of all apps to allow re-registration"
				find /data/data/*/shared_prefs -name com.google.android.gms.*.xml -delete
			fi
		else
			if ${UNZIP} -l "${GMSCORE_PATH}/base.apk" | grep META-INF/NANOLX.RSA 2>/dev/null; then
				decho "    + Removing NanoDroid microG GmsCore in favor of Official microG GmsCore"
				rm -rf "${GMSCORE_PATH}"

				decho "    + Resetting GCM/FCM connection of all apps to allow re-registration"
				find /data/data/*/shared_prefs -name com.google.android.gms.*.xml -delete
			fi
		fi
	fi
}

detect_migrate_droidguard () {
	DROIDGUARD_PATH=$(find /data/app -type d -name 'org.microg.gms.droidguard-*' 2>/dev/null)

	if [ ! -z ${DROIDGUARD_PATH} ]; then
		if [ -n "${1}" ]; then
			if ! ${UNZIP} -l "${DROIDGUARD_PATH}/base.apk" | grep META-INF/NANOLX.RSA 2>/dev/null; then
				decho "    + Removing Official DroidGuard in favor of NanoDroid DroidGuard"
				rm -rf "${DROIDGUARD_PATH}"
			fi
		else
			if ${UNZIP} -l "${DROIDGUARD_PATH}/base.apk" | grep META-INF/NANOLX.RSA 2>/dev/null; then
				decho "    + Removing NanoDroid DroidGuard in favor of Official DroidGuard"
				rm -rf "${DROIDGUARD_PATH}"
			fi
		fi
	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!"

	print_info " > prepare installation"
	unzip -oq "${ZIP}" -d "${INSTALLER}" || \
		error "failed to prepare environment!"

	rm -rf ${TMPDIR}/framework-res
	rm -f ${TMPDIR}/*.xml
	rm -f ${TMPDIR}/*.list

	chmod 0755 ${INSTALLER}/*.*
}

reset_runtime_permissions () {
	# required on Android 10, else all apps bundled with NanoDroid will not
	# show a permission prompt for android.permission.WRITE_EXTERNAL_STORAGE
	if [ "${SDK_VERSION}" -ge 29 -a "${NANODROID_UPGRADE}" -eq 0 ]; then
		find /data/system/users -type f -name 'runtime-permissions.xml' 2>/dev/null | while read file; do
			rm -f "${file}"
			decho "  ++ resetting permissions: ${file}"
		done
	fi
}

nanodroid_finalize () {
	case ${MODID} in
		NanoDroid | NanoDroid_microG )
			if [ "${nanodroid_overlay}" -eq 1 ]; then
				print_info " << with /system applications overlays"
				${NANODROID_BINDIR}/nanodroid-overlay --create
			else
				print_info " << without /system applications overlays"
			fi
		;;
	esac

	if [ "${MODE}" = "MAGISK" ]; then
		magisk_install_finish
	else
		install_addond
		sync
		nanodroid_storelogs

		sort ${NANODROID_LIST} | uniq > /tmp/nanodroid-list
		mv /tmp/nanodroid-list ${NANODROID_LIST}

		recovery_cleanup_env
	fi

	reset_runtime_permissions

	print_info " "
	print_info " Thanks for using NanoDroid "
	print_info " "

	${BOOTMODE} || umount_partitions

	rm -rf ${INSTALLER}
}

##########################################################################################
# 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

	UNZIP="${INSTALLER}/unzip.${BIN_ARCH}"
	chmod +x "${UNZIP}"

	AAPT="${INSTALLER}/aapt.${BIN_ARCH}"
	chmod +x "${AAPT}"

	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	;;
		29 )		GSYNC_VER=Q	;;
		* )	GSYNC_UNSUPPORTED=1	;;
	esac


	case ${ARCH} in
		arm )
			case ${SDK_VERSION} in
				29 )
					LIBJNI_IME=libjni_latinimegoogle.so_28
				;;
				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
				29 )
					LIBJNI_IME=libjni_latinimegoogle.so_28
				;;
				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 | 29 )
					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
		print_info " "
		print_info " ++ Installing on pre-KitKat ROM, full"
		print_info " ++ compatibility is not garantueed!"
		print_info " "
	fi

	if [ ! -d /system/xbin ]; then
		ROM_NO_XBIN=1
		decho " ++ ROM has no /system/xbin, using /system/bin instead"
	else	ROM_NO_XBIN=0
	fi

	[ ! -d /data/adb ] && mkdir /data/adb
}

setup_busybox () {
	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/
}

# Taken from Magisk, used for System Mode installation
recovery_setup_env () {
	if ${BOOTMODE}; then
		PATH=${INSTALLER}/busybox:/system/bin:/vendor/bin
	else
		OLD_PATH=${PATH}
		OLD_LD_LIB=${LD_LIBRARY_PATH}
		OLD_LD_PRE=${LD_PRELOAD}
		OLD_LD_CFG=${LD_CONFIG_FILE}
		unset LD_LIBRARY_PATH
		unset LD_PRELOAD
		unset LD_CONFIG_FILE
		PATH=${INSTALLER}/busybox:/system/bin:/vendor/bin
	fi
}

# Taken from Magisk, used for System Mode installation
recovery_cleanup_env () {
	if ${BOOTMODE}; then
		[ -n ${OLD_PATH} ] && PATH=${OLD_PATH}
	else
		[ -n ${OLD_PATH} ] && PATH=${OLD_PATH}
		[ -n ${OLD_LD_LIB} ] && LD_LIBRARY_PATH=${OLD_LD_LIB}
		[ -n ${OLD_LD_PRE} ] && LD_PRELOAD=${OLD_LD_PRE}
		[ -n ${OLD_LD_CFG} ] && LD_CONFIG_FILE=${OLD_LD_CFG}
	fi
}

##########################################################################################
# Magisk Mode Installation
##########################################################################################

magisk_install_setup () {
	print_info " "
	print_info "******************************"
	print_info "Powered by Magisk (@topjohnwu)"
	print_info "******************************"
	print_info " "
	print_info " > setup Magisk environment"

	MAGISKBASE=/data/adb
	recovery_setup_env

	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 ${MAGISKBASE}/modules/${dir} ]; then
					print_info " !! ${dir} module detected - uninstalling!"
					rm -rf ${MAGISKBASE}/modules/${dir}
					NANODROID_UPGRADE=1
				fi

				if [ -d ${MAGISKBASE}/modules_update/${dir} ]; then
					print_info " !! ${dir} module detected - uninstalling!"
					rm -rf ${MAGISKBASE}/modules_update/${dir}
				fi
			done
		;;

		NanoDroid_microG | NanoDroid_FDroid )
			# check for Full package and abort if found
			[ -d ${MAGISKBASE}/modules/NanoDroid -o -d ${MAGISKBASE}/modules_update/NanoDroid ] && \
				error "${MODID} can't be installed along side the Full package"
		;;

		NanoDroid_OsmAnd | NanoDroid_Google | NanoDroid_BromiteWebView )
			true
		;;

		* )
			error "unknown module intended to be installed!?"
		;;
	esac

	[ -d ${MODPATH} ] && NANODROID_UPGRADE=1

	if [ "${NANODROID_UPGRADE}" -eq 1 ]; then
		MODPATH=${MAGISKBASE}/modules_update/${MODID}
		rm -rf ${MODPATH}
	else
		MODPATH=${MAGISKBASE}/modules/${MODID}
	fi
}

magisk_install_preinst () {
	if [ -f ${MODPATH}/system.prop ]; then
		print_info " << backing up module's system.prop"
		cp ${MODPATH}/system.prop ${TMPDIR}/system.prop
	fi

	if [ -d ${MODPATH}/logs ]; then
		print_info " << backing up init.d script logs"
		cp -r ${MODPATH}/logs ${TMPDIR}/logs
	fi

	if [ -d ${MODPATH}/logcats ]; then
		print_info " << backing up logcats"
		cp -r ${MODPATH}/logcats ${TMPDIR}/logcats
	fi
}

magisk_install_postinst () {
	if [ -f ${TMPDIR}/system.prop ]; then
		print_info " << restoring system.prop"
		cp ${TMPDIR}/system.prop ${MODPATH}/system.prop
	fi

	if [ "${nanodroid_microg}" -ne 0 -o "${MODID}" = "NanoDroid_microG" ]; then
		if [ ! -z $(grep_prop ro.setupwizard.mode) ]; then
			echo "ro.setupwizard.mode=DISABLED" >> ${MODPATH}/system.prop
		fi
	fi

	if [ -d ${TMPDIR}/logs ]; then
		print_info " << restoring init.d script logs"
		cp -r ${TMPDIR}/logs ${MODPATH}/logs
	fi

	if [ -d ${TMPDIR}/logcats ]; then
		print_info " << restoring logcats"
		cp -r ${TMPDIR}/logcats ${MODPATH}/logcats
	fi
}

magisk_install_finish () {
	# Magisk Module files
	cp -af ${INSTALLER}/module.prop ${MODPATH}/module.prop

	if [ -f ${INSTALLER}/service.sh ]; then
		cp -af ${INSTALLER}/service.sh ${MODPATH}/service.sh
		chmod +x ${MODPATH}/service.sh
	fi

	case ${MODID} in
		NanoDroid | NanoDroid_microG )
			magisk_install_postinst
		;;
	esac

	if ${BOOTMODE}; then
		touch "${MAGISKBASE}/modules/${MODID}/update" 2>/dev/null
		cp -af "${INSTALLER}/module.prop" "${MAGISKBASE}/modules/${MODID}/module.prop" 2>/dev/null
	fi

	sync
	nanodroid_storelogs
	recovery_cleanup_env
}

##########################################################################################
# Destroy all GApps!
##########################################################################################

gapps_solve_conflicts () {
	# first get rid of conflicting packages
	print_google_apps | while read app; do
		decho " ++ removing app: ${app} [google_apps]"
		${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

	print_google_data | while read app; do
		decho " ++ removing data for: ${app} [google_data]"
		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 ${STORAGE}/Android/data/${app}
	done
}

gapps_destroy_artifacts () {
	# this removes original Play Services
	# only if this is a fresh NanoDroid installation
	if [ "${NANODROID_UPGRADE}" -eq 0 ]; then
		rm -rf /data/dalvik-cache/*/system"@priv-app@GmsCore"[@\.]*@classes.*

		print_google_data_dirty | while read app; do
			decho " ++ removing data for: ${app} [google_data_dirty]"
			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 ${STORAGE}/Android/data/${app}
		done

		find /data/system* -type f -name 'accounts*db' 2>/dev/null | while read database; do
			decho "  ++ deleting Google Accounts from ${database} (if any)"
			${INSTALLER}/sqlite3.${BIN_ARCH} ${database} \
				"DELETE FROM accounts WHERE type='com.google';"
		done

		find /data/system/users -type f -name 'runtime-permissions.xml' 2>/dev/null | while read file; do
			if grep -q "com.google.android" "${file}"; then
				decho "  ++ resetting permissions: ${file}"
				rm -f "${file}"
			fi
		done

		if [ -f /data/system/packages.list ]; then
			print_google_data_dirty | while read app; do
				decho "  ++ de-registering app: ${app} (if installed)"
				sed -e "/${app}/d" -i /data/system/packages.list
			done
		fi
	fi
}

##########################################################################################
# check if ROM has native fake signature spoofing support
# origingally by @ale5000 - revised by me
##########################################################################################

check_fake_package_signature () {
	PERMISSION=android.permission.FAKE_PACKAGE_SIGNATURE
	PERMISSION_OD=$(echo -n "${PERMISSION}" | od -A n -t x1 | tr -d '\n' | sed -e 's/^ //g;s/ /00/g')
	HAS_FAKESIGN=false
	FRAMEWORKRES_PATCH=false
	SERVICESJAR_PATCH=false

	mkdir -p ${TMPDIR}/sigcheck

	# natively patched ROM: only framework-res.apk patched (old)
	# natively patched ROM: both framework-res.apk and services.jar patched (new)
	# self patched ROM: only services.jar patched

	# check framework-res.apk for the patch
	unzip -oq /system/framework/framework-res.apk -d "${TMPDIR}/sigcheck" \
		|| error "failed to unpack framework-res.apk"

	if grep -qF "${PERMISSION}" "${TMPDIR}"/sigcheck/AndroidManifest.xml; then
		HAS_FAKESIGN=true
		FRAMEWORKRES_PATCH=true
	fi

	if od -A n -t x1 "${TMPDIR}"/sigcheck/AndroidManifest.xml | tr -d ' \n' | grep -qF "${PERMISSION_OD}"; then
		HAS_FAKESIGN=true
		FRAMEWORKRES_PATCH=true
	fi

	# check services.jar for the patch
	unzip -oq /system/framework/services.jar -d "${TMPDIR}/sigcheck" \
		|| error "failed to unpack services.jar"

	if grep -qF "${PERMISSION}" "${TMPDIR}"/sigcheck/*.dex; then
		HAS_FAKESIGN=true
		SERVICESJAR_PATCH=true
	fi

	if od -A n -t x1 "${TMPDIR}"/sigcheck/*.dex | tr -d ' \n' | grep -qF "${PERMISSION_OD}"; then
		HAS_FAKESIGN=true
		SERVICESJAR_PATCH=true
	fi

	# we don't use this anywhere (except in SysTest log),
	# but may still come in hand in the future
	if ${FRAMEWORKRES_PATCH} && ! ${SERVICESJAR_PATCH}; then
		PATCH_TYPE="native_old"
	elif ${FRAMEWORKRES_PATCH} && ${SERVICESJAR_PATCH}; then
		PATCH_TYPE="native_new"
	elif ! ${FRAMEWORKRES_PATCH} && ${SERVICESJAR_PATCH}; then
		PATCH_TYPE="self_patched"
	fi

	${HAS_FAKESIGN} && return 0 || return 1
}


##########################################################################################
# check if Bromite System WebView is supported
##########################################################################################

check_bromite_webview_support () {
	WEBVIEW_PKG="com.android.webview"
	HAS_WEBVIEW=false

	${AAPT} dump xmltree /system/framework/framework-res.apk res/xml/config_webview_packages.xml | \
		tr -d '\n' | sed -e 's/webviewprovider/\n/g' | grep com.android.webview | \
		grep -q 'E: signature' || HAS_WEBVIEW=true

	${HAS_WEBVIEW} && return 0 || return 1
}

##########################################################################################
# privapp permission whitelist generation
##########################################################################################

dump_system_privapp_permissions () {
	SYS_LIST="${TMPDIR}/privapp-permissions.list"

	# XXX this looks shitty
	"${AAPT}" dump xmltree /system/framework/framework-res.apk AndroidManifest.xml | \
		tr -d '\n' | sed -e 's/E:/\n/g' | \
		grep '(type 0x11)0x[137]2' | \
		awk -F\" '{print $2}' | sort > "${SYS_LIST}"

	"${AAPT}" dump xmltree /system/framework/framework-res.apk AndroidManifest.xml | \
		tr -d '\n' | sed -e 's/E:/\n/g' | \
		grep '(type 0x11)0xc212' | \
		awk -F\" '{print $2}' | sort >> "${SYS_LIST}"

	"${AAPT}" dump xmltree /system/framework/framework-res.apk AndroidManifest.xml | \
		tr -d '\n' | sed -e 's/E:/\n/g' | \
		grep '(type 0x11)0x[02]' | \
		awk -F\" '{print $2}' | sort >> "${SYS_LIST}"

	"${AAPT}" dump xmltree /system/framework/framework-res.apk AndroidManifest.xml | \
		tr -d '\n' | sed -e 's/E:/\n/g' | \
		grep '(type 0x11)0x[13]02' | \
		awk -F\" '{print $2}' | sort >> "${SYS_LIST}"

	"${AAPT}" dump xmltree /system/framework/framework-res.apk AndroidManifest.xml | \
		tr -d '\n' | sed -e 's/E:/\n/g' | \
		grep '(type 0x11)0x1[01]2' | \
		awk -F\" '{print $2}' | sort >> "${SYS_LIST}"

	"${AAPT}" dump xmltree /system/framework/framework-res.apk AndroidManifest.xml | \
		tr -d '\n' | sed -e 's/E:/\n/g' | \
		grep '(type 0x11)0x1001' | \
		awk -F\" '{print $2}' | sort >> "${SYS_LIST}"

	# XXX pre-patched custom ROM
	check_fake_package_signature && \
		echo "android.permission.FAKE_PACKAGE_SIGNATURE" >> "${SYS_LIST}"
}

create_privapp_permissions_whitelist () {
	APK="${MODPATH}/system/priv-app/${1}/${1}.apk"
	APK_NAME="$("${AAPT}" dump badging "${APK}" | awk -F \' '/^package: name/{print $2}')"
	APK_LIST="${TMPDIR}/${APK_NAME}.list"

	SYS_LIST="${TMPDIR}/privapp-permissions.list"

	APP_WHITELIST="${TMPDIR}/${APK_NAME}.xml"
	INST_WHITELIST="/system/etc/permissions/${APK_NAME}.xml"

	[ ! -f "${SYS_LIST}" ] && dump_system_privapp_permissions

	"${AAPT}" dump permissions "${APK}" | \
		awk -F \' '/^uses-permission:/{print $2}' | \
		sort > "${APK_LIST}"

	echo '<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <privapp-permissions package="'${APK_NAME}'">' > "${APP_WHITELIST}"

	cat "${APK_LIST}" | while read perm; do
		if grep -q "${perm}" "${SYS_LIST}"; then
			decho "  ++ package ${APK_NAME} needs privapp-whitelist ${perm}"
			echo '        <permission name="'${perm}'" />' >> "${APP_WHITELIST}"
		fi
	done

	echo '    </privapp-permissions>
</permissions>' >> "${APP_WHITELIST}"

	mkdir -p "${MODPATH}/system/etc/permissions/"
	cp "${APP_WHITELIST}" "${MODPATH}/${INST_WHITELIST}"
	set_perm_data "${MODPATH}/${INST_WHITELIST}"
	installinfo_add "${INST_WHITELIST}"
}

##########################################################################################
# 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

		gapps_solve_conflicts
		gapps_destroy_artifacts

		NLPBACKEND="nlpBackendNominatim"

		print_info " << with microg"
		print_info "   ++ Nominatim geocoder backend"
		${NANODROID_BINDIR}/nanodroid-overlay --add NominatimGeocoderBackend
		${NANODROID_BINDIR}/nanodroid-overlay --add NominatimNlpBackend

		if [ "${nanodroid_nlpbackend:0:1}" -eq 1 ]; then
			NLPBACKEND="${NLPBACKEND} nlpBackendDejavu"
			print_info "   ++ Déjà Vu location backend"
			${NANODROID_BINDIR}/nanodroid-overlay --add DejaVuNlpBackend
			${NANODROID_BINDIR}/nanodroid-overlay --add DejaVuBackend
		fi

		if [ "${nanodroid_nlpbackend:1:1}" -eq 1 ]; then
			NLPBACKEND="${NLPBACKEND} nlpBackendIchnaea"
			print_info "   ++ Ichnaea location backend"
			${NANODROID_BINDIR}/nanodroid-overlay --add IchnaeaNlpBackend
			${NANODROID_BINDIR}/nanodroid-overlay --add MozillaNlpBackend
		fi

		if [ "${nanodroid_nlpbackend:2:1}" -eq 1 ]; then
			NLPBACKEND="${NLPBACKEND} nlpBackendApple"
			print_info "   ++ Apple location backend"
		fi

		if [ "${nanodroid_nlpbackend:3:1}" -eq 1 ]; then
			NLPBACKEND="${NLPBACKEND} nlpBackendRadiocell"
			print_info "   ++ Radiocell location backend"
		fi

		# migrate from Nanolx microG GmsCore to Official microG GmsCore
		detect_migrate_microg

		# migrate from Official DroidGuard to Nanolx DroidGuard
		detect_migrate_droidguard reverse

		print_info "   ++ microG GmsCore"
		nanodroid_install_apk GmsCore

		if [ "${nanodroid_microg}" -ne 2 ]; then
			for app in GsfProxy DroidGuard; do
				nanodroid_install_apk ${app}
			done

			${NANODROID_BINDIR}/nanodroid-overlay --add GmsDroidGuard
		fi

		for app in ${NLPBACKEND}; do
			nanodroid_install_apk ${app}
		done

		create_privapp_permissions_whitelist GmsCore

		nanodroid_install_file etc/permissions/features.xml
		nanodroid_install_file etc/sysconfig/microg-a5k.xml

		# android.permission.ACCESS_BACKGROUND_LOCATION only on SDK 29+
		if [ "${SDK_VERSION}" -lt 29 ]; then
			sed -e '/android.permission.ACCESS_BACKGROUND_LOCATION/d' \
			-i "${INSTALLER}/system/etc/default-permissions/microg-permissions.xml"
		fi
		nanodroid_install_file etc/default-permissions/microg-permissions.xml

	else	print_info " << without microG"
	fi
}

install_mapsv1 () {
	# install mapsv1 if requested
	if [ "${nanodroid_mapsv1}" -eq 1 ]; then
		print_info " << 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	print_info " << without Maps API version 1"
	fi
}

install_gsync () {
	# install GSync if requested
	if [ "${nanodroid_gsync}" -eq 1 ]; then
		if [ "${GSYNC_UNSUPPORTED}" -eq 1 ]; then
			print_info " << Google Sync Adapters are unsupported on SDK ${SDK_VERSION}"
		else
			print_info " << with Google Sync Adapters (${GSYNC_VER})"

			for app in GoogleCalendarSync GoogleContactsSync GoogleBackupTransport; do
				nanodroid_install_apk ${app}
			done

			create_privapp_permissions_whitelist GoogleBackupTransport
			nanodroid_install_file etc/default-permissions/google-sync-permissions.xml
		fi
	else	print_info " << without Google Sync Adapters"
	fi
}

install_fdroid_aurora () {
	print_info " << with Aurora Droid"
	nanodroid_install_apk AuroraDroid
	nanodroid_install_apk AuroraServices
	create_privapp_permissions_whitelist AuroraServices
}

install_fdroid_fdroid () {
	print_info " << with F-Droid"
	nanodroid_install_apk FDroid
	nanodroid_install_apk FDroidPrivileged

	${NANODROID_BINDIR}/nanodroid-overlay --add FDroidPriv

	create_privapp_permissions_whitelist FDroidPrivileged
	nanodroid_install_file etc/org.fdroid.fdroid/additional_repos.xml
}

install_fdroid () {
	# install F-Droid if requested
	# respectively force if it's the F-Droid package

	if [ "${nanodroid_fdroid}" -eq 3 ]; then
		install_fdroid_fdroid
		install_fdroid_aurora
	elif [ "${nanodroid_fdroid}" -eq 2 ]; then
		install_fdroid_aurora
	elif [ "${nanodroid_fdroid}" -eq 1 -o "${MODID}" = "NanoDroid_FDroid" ]; then
		install_fdroid_fdroid
	else	print_info " << without F-Droid"
	fi
}

install_apps () {
	# install apps if requested
	if [ "${nanodroid_apps}" -eq 1 ]; then
		print_info " << with applications"
		APP_STRING=" <<>"

		INSTALL_APPS=$(cat "${cfg_apps}")
		for app in ${INSTALL_APPS}; do
			if [[ -d /system/app/${app} && ! -d ${MAGISKBASE}/modules/${MODID}/system/app/${app} ]]; then
				print_info "   ++ app: ${app} already provided by ROM"
			elif [[ -d "${INSTALLER}/system/app/${app}" ]]; then
				print_info "   ++ ${app}"
				nanodroid_install_apk ${app}
			else	print_info "   ++ app: ${app} missing"
			fi
		done
	else	print_info " << without applications"
	fi
}

install_store_play () {
	# force unselect Fake Store when user has choosen Play Store
	STORE_CONFLICT="FakeStore"
	FAKE_STORE=0

	print_info " << with Play Store"
	nanodroid_install_apk Phonesky

	create_privapp_permissions_whitelist Phonesky

	nanodroid_install_file etc/default-permissions/phonesky-permissions.xml
}

install_store_aurora () {
	print_info " << with Aurora Store"
	nanodroid_install_apk AuroraStore
	nanodroid_install_apk AuroraServices
	create_privapp_permissions_whitelist AuroraServices
}

install_store () {
	STORE_CHOICE=${nanodroid_play:0:1}
	FAKE_STORE=${nanodroid_play:1:1}

	[ "${FAKE_STORE}" -eq 1 ] && STORE_CONFLICT="Phonesky" || STORE_CONFLICT=""

	# install Aurora and/or Play Store whichever requested
	case "${STORE_CHOICE}" in
		1 )
			install_store_play
		;;

		2 )
			install_store_aurora
		;;

		3 )
			install_store_play
			install_store_aurora
		;;

		* )
			print_info " << without App Store"
		;;
	esac

	# Only install Fake Store if requested and Play Store is not installed
	if [ "${FAKE_STORE}" -eq 1 ]; then
		print_info " << with Fake Store"
		nanodroid_install_apk FakeStore

		create_privapp_permissions_whitelist FakeStore
	else 	print_info " << 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_bash () {
	if [ "${nanodroid_bash}" -eq 1 ]; then
		print_info " << 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	print_info " << without GNU Bash Shell"
	fi
}

install_nanodroidscripts () {
	print_info " << with NanoDroid Scripts"

	for script in npem nutl novl \
		nanodroid-perm nanodroid-util \
		nanodroid-overlay; do
		nanodroid_install_file xbin/${script} bin
	done

	nanodroid_install_file xbin/column.${BIN_ARCH} bin
	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_shell_utils () {
	if [ -n "${nanodroid_utils}" ]; then
		print_info " << with Shell Utilities"

		for binary in ${nanodroid_utils}; do
			if [ -f "${INSTALLER}/system/xbin/${binary}.${BIN_ARCH}" ]; then
				nanodroid_install_file xbin/${binary}.${BIN_ARCH} bin
			else
				ui_print " -- ${binary} is not a known shell util"
			fi
		done
	else	print_info " << without Shell Utilities"
	fi
}

install_initd () {
	if [ -n "${nanodroid_init}" ]; then
		print_info " << 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}"

		for script in ${nanodroid_init}; do
			if [ -f "${INSTALLER}/system/etc/init.d/${script}" ]; then
				cp "${INSTALLER}/system/etc/init.d/${script}" "${INIT_BASE}/"
				set_perm_bin "${INIT_BASE}/${script}"
				installinfo_add "/system/etc/init.d/${init}"
			else
				ui_print " -- ${script} is not a known init script"
			fi
		done
	else	print_info " << without init scripts"
	fi
}

install_bromite_webview () {
	if [ "${MODID}" = "NanoDroid_BromiteWebView" ]; then
		if ! check_bromite_webview_support; then
			error "ROM does not support Bromite WebView installation!"
		else
			print_info " << with Bromite WebView"

			case ${ARCH} in
				arm | arm64 | x86 ) BROMITE_ARCH=${ARCH} ;;
				x86_64 ) BROMITE_ARCH=x86 ;;
			esac

			WEBVIEW_REPLACE=BromiteWebView
			WEBVIEW_DIR=""
			BACKUP_PATH="${STORAGE}/nanodroid_backups/$(grep_prop ro.build.flavor)_$(grep_prop ro.build.id)"

			for app in webview webviewstub WebViewStub Webview; do
				if [ -d /system/app/${app} ]; then
					if [ "${MODE}" = "SYSTEM" ]; then
						decho "    backing up ${app} to ${BACKUP_PATH}/app/${app}"
						mkdir -p "${BACKUP_PATH}/app"
						rm -rf "${BACKUP_PATH}/app/${app}"
						mv /system/app/${app} "${BACKUP_PATH}/app/"
					fi

					WEBVIEW_REPLACE=${app}
					break
				fi

				if [ -d /system/product/app/${app} ]; then
					if [ "${MODE}" = "SYSTEM" ]; then
						decho "    backing up ${app} to ${BACKUP_PATH}/product/app/${app}"
						mkdir -p "${BACKUP_PATH}/product/app"
						rm -rf "${BACKUP_PATH}/product/app/${app}"
						mv /system/product/app/${app} "${BACKUP_PATH}/product/app/"
					fi

					WEBVIEW_REPLACE=${app}
					WEBVIEW_DIR="product/app"
					break
				fi
			done

			if [ "${NANODROID_UPGRADE}" -eq 0 ]; then
				for app in com.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 ${STORAGE}/Android/data/${app}
				done
			fi

			nanodroid_install_apk BromiteWebView_${BROMITE_ARCH} multilib ${WEBVIEW_REPLACE} ${WEBVIEW_DIR}
		fi
	fi
}

install_osmand () {
	if [ "${MODID}" = "NanoDroid_OsmAnd" ]; then
		print_info " << 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
			print_info " << Swipe Libraries are unsupported on SDK ${SDK_VERSION}"
		else
			print_info " << with swipe libraries"

			SWIPE_SRC="${INSTALLER}/swipe/${ARCH}"
			SWIPE_DEST="/system/${SWIPE_LIBDIR}"

			APPL_IME="/system/app/LatinIME/${SWIPE_LIBDIR}/${ARCH}"
			PRODL_IME="/system/product/app/LatinIME/${SWIPE_LIBDIR}/${ARCH}"

			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"

			if [ -f "${APPL_IME}/libjni_latinime.so" ]; then
				decho " swipe: symlinking libjni_latinimegoogle as libjni_latinime in ${APPL_IME}"

				mkdir -p "${MODPATH}${APPL_IME}"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_latinimegoogle.so" "${MODPATH}${APPL_IME}/libjni_latinime.so"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_keyboarddecoder.so" "${MODPATH}${APPL_IME}/libjni_keyboarddecoder.so"

				installinfo_add "${MODPATH}${APPL_IME}/libjni_latinime.so"
				installinfo_add "${MODPATH}${APPL_IME}/libjni_keyboarddecoder.so"
			elif [ -f "${APPL_IME}/libjni_latinimegoogle.so" ]; then
				decho " swipe: symlinking libjni_latinimegoogle as libjni_latinimegoogle in ${APPL_IME}"

				mkdir -p "${MODPATH}${APPL_IME}"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_latinimegoogle.so" "${MODPATH}${APPL_IME}/libjni_latinimegoogle.so"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_keyboarddecoder.so" "${MODPATH}${APPL_IME}/libjni_keyboarddecoder.so"

				installinfo_add "${MODPATH}${APPL_IME}/libjni_latinimegoogle.so"
				installinfo_add "${MODPATH}${APPL_IME}/libjni_keyboarddecoder.so"
			fi

			if [ -f "${PRODL_IME}/libjni_latinime.so" ]; then
				decho " swipe: symlinking libjni_latinimegoogle as libjni_latinime in ${PRODL_IME}"

				mkdir -p "${MODPATH}${PRODL_IME}"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_latinimegoogle.so" "${MODPATH}${PRODL_IME}/libjni_latinime.so"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_keyboarddecoder.so" "${MODPATH}${PRODL_IME}/libjni_keyboarddecoder.so"

				installinfo_add "${MODPATH}${PRODL_IME}/libjni_latinime.so"
				installinfo_add "${MODPATH}${PRODL_IME}/libjni_keyboarddecoder.so"
			elif [ -f "${PRODL_IME}/libjni_latinimegoogle.so" ]; then
				decho " swipe: symlinking libjni_latinimegoogle as libjni_latinimegoogle in ${PRODL_IME}"

				mkdir -p "${MODPATH}${PRODL_IME}"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_latinimegoogle.so" "${MODPATH}${PRODL_IME}/libjni_latinimegoogle.so"
				ln -sfn "${MODPATH}${SWIPE_DEST}/libjni_keyboarddecoder.so" "${MODPATH}${PRODL_IME}/libjni_keyboarddecoder.so"

				installinfo_add "${MODPATH}${PRODL_IME}/libjni_latinimegoogle.so"
				installinfo_add "${MODPATH}${PRODL_IME}/libjni_keyboarddecoder.so"
			fi
		fi
	else	print_info " << without swipe libraries"
	fi
}

install_addond () {
	if [ -d /system/addon.d ]; then
		print_info " << 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
		print_info " << ROM does not have addon.d support"
	fi
}

##########################################################################################
# Advanced Installation Functions
##########################################################################################

nanodroid_install_dir () {
	dir="${1}"
	[ -n "${2}" ] && dest="${2}" || 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.gz" ]; then
			source="${INSTALLER}/${sdir}/${app}/${app}.apk"
			dir=system/$(basename ${sdir})
			break
		fi
	done

	[ -n "${4}" ] && dir="system/${4}"

	[ -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}"

	decho "    installing app: ${app}"
	decho "      from: ${source}"
	decho "      into: ${dest} [${dest_apk}]"
	cp "${source}.gz" "${dest}/${dest_apk}.gz" || \
		error "failed to install ${source} to ${dest}"

	gzip -fd "${dest}/${dest_apk}.gz" || \
		error "failed to decompress ${dest}/${dest_apk}.gz"

	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})

	decho "    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

	"${UNZIP}" -oq "${apk}" "lib/*" -d "${TMP_LIBDIR}" \
		2>/dev/null
	unzip_return=$?

	case ${unzip_return} in
		0  ) decho "      ${app} does have libs" ;;
		11 ) decho "      ${app} does not have any libs" ;;
		50 ) error "  not enough space available!" ;;
		*  ) error "  unpacking libs for ${app} failed [${unzip_return}]" ;;
	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*  ) decho "      ${app}: installing arm64 libs"
						   lib_arch=arm64 ;;
					*arm*	 ) decho "      ${app}: installing arm libs"
						   lib_arch=arm ;;
					*x86_64* ) decho "      ${app}: installing x86_64 libs"
						   lib_arch=x86_64 ;;
					*x86*	 ) decho "      ${app}: installing x86 libs"
						   lib_arch=x86 ;;
				esac

				decho "        from: ${srcdir}"
				decho "        into: ${libd}/${lib_arch}"
				mkdir -p "${libd}/${lib_arch}"

				for lib in ${srcdir}/*; do
					decho "        library: $(basename ${lib})"
					cp ${lib} "${libd}/${lib_arch}/" || \
						error "  installing libs for ${app} failed"

					installinfo_add "${libd}/${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 @MODPATH@ ${target}; then
		sed -e "s|@MODPATH@|${MODPATH}|g" -i ${target}
		decho "    substitute: adjust @MODPATH@ in ${target}"
	fi

	if grep -q @MODID@ ${target}; then
		sed -e "s|@MODID@|${MODID}|g" -i ${target}
		decho "    substitute: adjust @MODID@ in ${target}"
	fi

	if grep -q @MODE@ ${target}; then
		sed -e "s|@MODE@|${MODE}|g" -i ${target}
		decho "    substitute: adjust @MODE@ in ${target}"
	fi
}

nanodroid_storelogs () {
	mkdir -p "${STORAGE}/nanodroid_logs"

	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}
MODE=${MODE}
MAGISK_VER_CODE=${MAGISK_VER_CODE}
ROM_NO_XBIN=${ROM_NO_XBIN}
NANODROID_UPGRADE=${NANODROID_UPGRADE}
NANODROID_BINDIR=${NANODROID_BINDIR}
HAS_FAKESIGN=${HAS_FAKESIGN}
HAS_WEBVIEW=${HAS_WEBVIEW}

### MOUNTED PARTITIONS ###
" >> ${nanodroid_logfile}

mount | awk '{print $1 " on " $3 " params: " $6}' \
	>> ${nanodroid_logfile}

echo "
### PARTITION INFORMATION ###

DEVICE_AB=${DEVICE_AB}
VENDOR_COMPAT=${VENDOR_COMPAT}
SYSTEM_AS_ROOT=${SYSTEM_AS_ROOT}
SYSTEMBLOCK=${SYSTEMBLOCK}
VENDORBLOCK=${VENDORBLOCK}

### DISK USAGE ###
" >> ${nanodroid_logfile}

df 2>/dev/null | sed '/^\//d' >> ${nanodroid_logfile}

if [ ! -z "${cfg_setup}" ]; then

echo "
### SETUP ###

configuration: ${cfg_setup}
" >> ${nanodroid_logfile}

cat "${cfg_setup}" >> ${nanodroid_logfile}

fi

if [ ! -z "${cfg_apps}" ]; then

echo "
### APPS ###

configuration: ${cfg_apps}
" >> ${nanodroid_logfile}

cat "${cfg_apps}" >> ${nanodroid_logfile}

fi

if [ ! -z "${cfg_overlay}" ]; then

echo "
### OVERLAY ###

configuration: ${cfg_overlay}
" >> ${nanodroid_logfile}

cat "${cfg_overlay}" >> ${nanodroid_logfile}

fi

chown root:sdcard_rw ${nanodroid_logfile}
chmod 0644 ${nanodroid_logfile}

print_info " | storing installation logs in ${STORAGE}/nanodroid_logs/"
print_info " | NanoDroid log:"
print_info " || ""$(basename ${nanodroid_logfile})"

	if [ -d /twres ]; then
		nanodroid_twrplog="${STORAGE}/nanodroid_logs/${MODID}_${VERSION}_twrp_${curdate}.log"

		cat /tmp/recovery.log > ${nanodroid_twrplog}

		chown root:sdcard_rw ${nanodroid_twrplog}
		chmod 0644 ${nanodroid_twrplog}

		print_info " | TWRP log:"
		print_info " || $(basename ${nanodroid_twrplog})"
		print_info " "
	fi

}

##########################################################################################
# NanoDroid Configuration File Handling
##########################################################################################

# check for configuration files
config_locations="${STORAGE} /external_sd /sdcard1 ${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 () {
	# see https://gitlab.com/Nanolx/NanoDroid/-/issues/147
	dos2unix "${cfg_setup}" &>/dev/null

	source "${cfg_setup}"

	[ -z "${nanodroid_fdroid}" ] && set_prop nanodroid_fdroid 1
	[ -z "${nanodroid_microg}" ] && set_prop nanodroid_microg 1
	[ -z "${nanodroid_apps}" ] && set_prop nanodroid_apps 1

	[ -z "${nanodroid_play}" ] && set_prop nanodroid_play 10

	# in NanoDroid 20.3 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

	# in NanoDroid 22.5 nanodroid_play has changed
	if [ "${nanodroid_play}" -gt 30 ]; then
		sed -e '/^nanodroid_play/d' -i "${cfg_setup}"
		set_prop nanodroid_play 20
	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_mapsv1}" ] && set_prop nanodroid_mapsv1 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_bash}" ] && set_prop nanodroid_bash 1

	[ -z "${nanodroid_nlpbackend}" ] && set_prop nanodroid_nlpbackend 1000

	# in NanoDroid 20.3 nanodroid_nlpbackend has changed
	if [ "${#nanodroid_nlpbackend}" -eq 1 ]; then
		case "${nanodroid_nlpbackend}" in
			0 ) tmp_prop="0000" ;;
			1 ) tmp_prop="1000" ;;
			2 ) tmp_prop="0100" ;;
			3 ) tmp_prop="1100" ;;
			* ) tmp_prop="1000" ;;
		esac

		sed -e '/^nanodroid_nlpbackend/d' -i "${cfg_setup}"
		set_prop nanodroid_nlpbackend "${tmp_prop}"
	fi

	# in NanoDroid 20.5 nanodroid_nlpbackend has changed (again)
	if [ "${#nanodroid_nlpbackend}" -eq 3 ]; then
		tmp_prop="${nanodroid_nlpbackend}0"
		sed -e '/^nanodroid_nlpbackend/d' -i "${cfg_setup}"
		set_prop nanodroid_nlpbackend "${tmp_prop}"
	fi

	nanodroid_all_init='"10_sqlite 20_fstrim 30_logcat 40_external_sd 50_logscleaner"'

	[ -z "${nanodroid_init}" ] && set_prop nanodroid_init "${nanodroid_all_init}"

	# in NanoDroid 22.7 nanodroid_init has changed
	if [ "${#nanodroid_init}" -eq 1 ]; then
		sed -e '/^nanodroid_init/d' -i "${cfg_setup}"
		set_prop nanodroid_init "${nanodroid_all_init}"
	fi

	nanodroid_all_utils='"findfs findmnt hexdump lessecho lesskey lsblk lscpu lsipc lslocks lsns ncal whereis"'

	[ -z "${nanodroid_utils}" ] && set_prop nanodroid_utils "${nanodroid_all_utils}"

	# in NanoDroid 22.7 nanodroid_util has changed
	if [ "${#nanodroid_utils}" -eq 1 ]; then
		sed -e '/^nanodroid_utils/d' -i "${cfg_setup}"
		set_prop nanodroid_utils "${nanodroid_all_utils}"
	fi

	# in NanoDroid 21.0.90 nanodroid_override was dropped
	sed -e '/^nanodroid_override/d' -i "${cfg_setup}"

	# in NanoDroid 22.5 nanodroid_fonts was dropped
	sed -e '/^nanodroid_fonts/d' -i "${cfg_setup}"

	# in NanoDroid 22.6 nanodroid_nano was dropped
	sed -e '/^nanodroid_nano/d' -i "${cfg_setup}"

	# in NanoDroid 22.6 nanodroid_zelda was dropped
	sed -e '/^nanodroid_zelda/d' -i "${cfg_setup}"

	source "${cfg_setup}"
}

# check whether '.nanodroid-apps' is up to date
check_cfg_apps () {
	# see https://gitlab.com/Nanolx/NanoDroid/-/issues/147
	dos2unix "${cfg_apps}" &>/dev/null

	# <= 16.3 has KeePass DX instead of KeePassDroid, migrate
	grep -q KeePassDroid "${cfg_apps}" && sed -e 's/KeePassDroid/KeePassDX/g' -i "${cfg_apps}"

	# <= 17.7 has Substratum instead of Bucket (LibreSubtratum), migrate
	grep -q Bucket "${cfg_apps}" && sed -e 's/Bucket/Substratum/g' -i "${cfg_apps}"

	# <= 18.1 has Orfox instead of TorBrowser, migrate
	grep -q Orfox "${cfg_apps}" && sed -e 's/Orfox/TorBrowser/g' -i "${cfg_apps}"

	# <= 18.4 has Adaway instead of Blockada, migrate
	grep -q Adaway "${cfg_apps}" && sed -e 's/Adaway/Blokada/g' -i "${cfg_apps}"

	# >= 20.7.92 no longer ships YahooWeatherProvider, remove
	grep -q YahooWeatherProvider "${cfg_apps}" && sed -e '/YahooWeatherProvider/d' -i "${cfg_apps}"

	# >= 20.8.90 no longer ships OmniJAWS, remove
	grep -q OmniJAWS "${cfg_apps}" && sed -e '/OmniJAWS/d' -i "${cfg_apps}"

	# >= 21.0.90 has Alarmio instead of OmniClock, migrate
	grep -q OmniClock "${cfg_apps}" && sed -e 's/OmniClock/Alarmio/g' -i "${cfg_apps}"

	# >= 21.0.90 no longer ships OpenWeatherMapProvider, remove
	grep -q OpenWeatherMapProvider "${cfg_apps}" && sed -e '/OpenWeatherMapProvider/d' -i "${cfg_apps}"

	# >= 21.0.90 has Lightning instead of Privacy Browser, migrate
	grep -q Lightning "${cfg_apps}" && sed -e 's/Lightning/PrivacyBrowser/g' -i "${cfg_apps}"

	# >= 21.0.90 has Hacker's Keyboard instead of BeHeKeyboard, migrate
	grep -q BeHeKeyboard "${cfg_apps}" && sed -e 's/BeHeKeyboard/HackersKeyboard/g' -i "${cfg_apps}"

	# >= 22.1 has SmartPack-Kernel-Manager instead of Kernel Adiutor, migrate
	grep -q KernelAdiutor "${cfg_apps}" && sed -e 's/KernelAdiutor/SmartPackKernelManager/g' -i "${cfg_apps}"

	# >= 22.6 has Frost instead of FaceSlim, migrate
	grep -q FaceSlim "${cfg_apps}" && sed -e 's/FaceSlim/Frost/g' -i "${cfg_apps}"

	# >= 22.6 no longer ships Substratum, remove
	grep -q Substratum "${cfg_apps}" && sed -e '/Substratum/d' -i "${cfg_apps}"

	# >= 22.6 no longer ship Orbot, remove
	grep -q Orbot "${cfg_apps}" && sed -e '/Orbot/d' -i "${cfg_apps}"

	# >= 22.7 has OAndBackupX instead of Oandbackup
	grep -q Oandbackup "${cfg_apps}" && sed -e 's/Oandbackup/OAndBackupX/g' -i "${cfg_apps}"

}

# check whether '.nanodroid-overlay' is up to date
check_cfg_overlay () {
	# see https://gitlab.com/Nanolx/NanoDroid/-/issues/147
	dos2unix "${cfg_overlay}" &>/dev/null

	# 22.0 flagged the following for overlay creation which caused issues
	grep -q "^GmsCore$" "${cfg_overlay}" && sed '/^GmsCore$/d' -i "${cfg_overlay}"
	grep -q "^GsfProxy$" "${cfg_overlay}" && sed '/^GsfProxy$/d' -i "${cfg_overlay}"
	grep -q "^DroidGuard$" "${cfg_overlay}" && sed '/^DroidGuard$/d' -i "${cfg_overlay}"
}

get_cfg_setup () {
	get_config setup
	if [ "$config_exists" -eq 1 ]; then
		cfg_setup="${config}"
		check_cfg_setup
		print_info " > Config | nanodroid-setup   | $(dirname ${cfg_setup})"
	else
		cfg_setup="${INSTALLER}/.nanodroid-setup"
		source "${cfg_setup}"
		print_info " > Config | nanodroid-setup   | fallback"
	fi
}

get_cfg_overlay () {
	get_config overlay
	if [ "$config_exists" -eq 1 ]; then
		cfg_overlay="${config}"
		check_cfg_overlay
		print_info " > Config | nanodroid-overlay | $(dirname ${cfg_overlay})"
	else
		cfg_overlay="${INSTALLER}/.nanodroid-overlay"
		print_info " > Config | nanodroid-overlay | fallback"
	fi
}

get_cfg_apps () {
	get_config apps
	if [ "$config_exists" -eq 1 ]; then
		cfg_apps="${config}"
		check_cfg_apps
		print_info " > Config | nanodroid-apps    | $(dirname ${cfg_apps})"
	else
		cfg_apps="${INSTALLER}/.nanodroid-apps"
		print_info " > Config | nanodroid-apps    | fallback"
	fi
}
