#!/bin/sh
set -e
CWD=$(pwd)
print_usage () {
echo "Usage: $0 {list|backup PACKAGE|restore FILENAME}"
echo "Example: $0 backup org.videolan.vlc"
echo "Example: $0 restore org.videolan.vlc_backup.tar"
}
list () {
adb shell pm list package -3 | sed 's/^package://' | sort
}
backup () {
PKG="$1"
adb root
adb shell test -d "data/data/$PKG" || return 1
mkdir -p "/tmp/$PKG/data"
cd "/tmp/$PKG/data" || return 1
adb shell tar -cvzf "/tmp/${PKG}_data.tar.gz" "data/data/$PKG"
adb pull "/tmp/${PKG}_data.tar.gz" .
adb shell rm -f "/tmp/${PKG}_data.tar.gz"
adb shell tar -cvzf "/storage/emulated/0/${PKG}_Android.tar.gz" \
"storage/emulated/0/Android/data/$PKG" \
"storage/emulated/0/Android/media/$PKG" \
"storage/emulated/0/Android/obb/$PKG" \
|| true
adb pull "/storage/emulated/0/${PKG}_Android.tar.gz" .
adb shell rm -f "/storage/emulated/0/${PKG}_Android.tar.gz"
mkdir -p "/tmp/$PKG/app"
cd "/tmp/$PKG/app" || return 1
PKGPATHS=$(adb shell pm path "$PKG" | sed 's/^package://')
for PKGPATH in $PKGPATHS; do
adb pull "$PKGPATH"
BASENAME=$(basename "$PKGPATH")
mv "$BASENAME" "${PKG}_${BASENAME}"
done
cd "/tmp/$PKG"
tar -cf "${CWD}/${PKG}_backup.tar" app data
cd "$CWD"
rm -rf "/tmp/$PKG"
}
restore () {
FILENAME=$(realpath "$1")
adb root
PKG=$(tar -tf "$FILENAME" data \
| grep '_data.tar.gz' \
| sed 's#^data/\(.*\)_data.tar.gz$#\1#')
if [ -z "$PKG" ]; then
return 1
fi
mkdir -p "/tmp/$PKG"
cd "/tmp/$PKG" || return 1
tar -xf "$FILENAME"
adb install app/*.apk
USER_APP=$(adb shell stat -c '%U' "/data/data/$PKG")
adb push "data/${PKG}_data.tar.gz" /tmp
adb shell tar -xvf "/tmp/${PKG}_data.tar.gz"
adb shell rm -f "/tmp/${PKG}_data.tar.gz"
adb shell chown -R "${USER_APP}:${USER_APP}" "/data/data/$PKG"
adb shell chown -R "${USER_APP}:${USER_APP}_cache" "/data/data/$PKG/cache"
adb shell chown -R "${USER_APP}:${USER_APP}_cache" "/data/data/$PKG/code_cache"
adb shell restorecon -DR "/data/data/$PKG"
adb push "data/${PKG}_Android.tar.gz" /storage/emulated/0
adb shell tar -xvf "/storage/emulated/0/${PKG}_Android.tar.gz"
adb shell rm -f "/storage/emulated/0/${PKG}_Android.tar.gz"
adb shell chown -R "$USER_APP" "/storage/emulated/0/Android/data/$PKG" \
|| true
adb shell chown -R "$USER_APP" "/storage/emulated/0/Android/media/$PKG" \
|| true
adb shell chown -R "$USER_APP" "/storage/emulated/0/Android/obb/$PKG" \
|| true
cd "$CWD"
rm -rf "/tmp/$PKG"
}
case "$1" in
'list')
list
;;
'backup')
backup "$2"
;;
'restore')
restore "$2"
;;
*)
print_usage
esac