#!/bin/sh

# adb_pull_apk.sh
# 2024-12-06
# by Gernot Walzl

# Downloads Android Packages (APKs) via the Android Debug Bridge (ADB).
# The downloaded APK file is equal to the APK file used for installation.
# https://developer.android.com/tools/adb

# To use ADB, USB debugging needs to be enabled in System > Developer Options.
# To show Developer Options, tap the Build Number seven times under About.
# https://developer.android.com/studio/debug/dev-options

set -e

list_packages () {
  local LST_PKG_VER_S  # system packages
  local LST_PKG_VER_3  # third party packages
  LST_PKG_VER_S=$(adb shell pm list packages -s --show-versioncode \
    | sed 's/^package:\(.*\) versionCode:\(.*\)$/\1;\2;s/')
  if [ -z "$LST_PKG_VER_S" ]; then
    return 1
  fi
  LST_PKG_VER_3=$(adb shell pm list packages -3 --show-versioncode \
    | sed 's/^package:\(.*\) versionCode:\(.*\)$/\1;\2;3/')
  echo "$LST_PKG_VER_S
$LST_PKG_VER_3" | sort
}

package () {
  echo "$1" | cut -d';' -f1
}

version () {
  echo "$1" | cut -d';' -f2
}

LST_PKG_VER=$(list_packages)

# Select packages to pull
LST_PKG_VER_PULL=''
if [ -n "$1" ]; then
  LST_PKG_VER_PULL=$(echo "$LST_PKG_VER" | grep "^$1;")
else
  LST_PKG_VER_WHIPTAIL=''
  for PKG_VER in $LST_PKG_VER; do
    LST_PKG_VER_WHIPTAIL="$LST_PKG_VER_WHIPTAIL $PKG_VER "
    if echo "$PKG_VER" | grep -q ';3$'; then
      LST_PKG_VER_WHIPTAIL="$LST_PKG_VER_WHIPTAIL on "
    else
      LST_PKG_VER_WHIPTAIL="$LST_PKG_VER_WHIPTAIL off "
    fi
  done
  LST_PKG_VER_PULL=$(whiptail \
    --title "ADB pull APK" \
    --checklist "Which Android Packages (APKs) do you want to download?" \
    22 76 15 \
    $LST_PKG_VER_WHIPTAIL \
    --noitem \
    --separate-output \
    3>&1 1>&2 2>&3)
fi

# Pull selected packages
for PKG_VER in $LST_PKG_VER_PULL; do
  PKG=$(package "$PKG_VER")
  VER=$(version "$PKG_VER")
  PKGPATHS=$(adb shell pm path "$PKG" | sed 's/^package://')
  for PKGPATH in $PKGPATHS; do
    adb pull "$PKGPATH"
    BASENAME=$(basename "$PKGPATH")
    if [ "$BASENAME" = "base.apk" ]; then
      mv -v "$BASENAME" "${PKG}_${VER}.apk"
    else
      mv -v "$BASENAME" "${PKG}_${VER}_${BASENAME}"
    fi
  done
done