|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Install Projectivy Launcher on an Android TV device and select it as home. |
| 3 | +# Uses ADB_CONTAINER (default: androidtv.internal) when running, otherwise adb. |
| 4 | + |
| 5 | +set -euo pipefail |
| 6 | + |
| 7 | +readonly PROJECTIVY_PACKAGE="com.spocky.projectivylauncher" |
| 8 | +readonly PROJECTIVY_HOME="${PROJECTIVY_PACKAGE}/com.spocky.projectivylauncher.MainActivity" |
| 9 | +readonly ADB_CONTAINER="${ADB_CONTAINER:-androidtv.internal}" |
| 10 | + |
| 11 | +usage() { |
| 12 | + cat >&2 <<EOF |
| 13 | +Usage: $0 <device-host> [<apk-path>|--launcher-only|--backup <file>|--restore <file>] |
| 14 | +
|
| 15 | +The device must expose ADB over TCP and trust the selected ADB client key. |
| 16 | +Set ADB_CONTAINER to use a running container other than androidtv.internal. |
| 17 | +EOF |
| 18 | + exit 2 |
| 19 | +} |
| 20 | + |
| 21 | +[[ $# -ge 1 ]] || usage |
| 22 | +readonly DEVICE_HOST="$1" |
| 23 | +readonly DEVICE_TARGET="${DEVICE_HOST}:5555" |
| 24 | +APK_PATH="${2:-$(dirname "$0")/projectivy.apk}" |
| 25 | +LAUNCHER_ONLY=false |
| 26 | +RESTORE_PATH="" |
| 27 | +BACKUP_PATH="" |
| 28 | + |
| 29 | +case "${2:-}" in |
| 30 | + --launcher-only) LAUNCHER_ONLY=true ;; |
| 31 | + --restore) |
| 32 | + LAUNCHER_ONLY=true |
| 33 | + RESTORE_PATH="${3:?--restore needs a path}" |
| 34 | + ;; |
| 35 | + --backup) |
| 36 | + LAUNCHER_ONLY=true |
| 37 | + BACKUP_PATH="${3:?--backup needs a path}" |
| 38 | + ;; |
| 39 | +esac |
| 40 | + |
| 41 | +declare -a adb_cmd |
| 42 | +if command -v docker >/dev/null 2>&1 \ |
| 43 | + && docker ps --format '{{.Names}}' 2>/dev/null | grep -Fxq "$ADB_CONTAINER"; then |
| 44 | + adb_cmd=(docker exec "$ADB_CONTAINER" adb) |
| 45 | + printf 'Using ADB from container %s\n' "$ADB_CONTAINER" |
| 46 | +elif command -v adb >/dev/null 2>&1; then |
| 47 | + adb_cmd=(adb) |
| 48 | + printf 'Using host ADB\n' |
| 49 | +else |
| 50 | + printf 'ERROR: no running ADB container and no host adb executable\n' >&2 |
| 51 | + exit 1 |
| 52 | +fi |
| 53 | + |
| 54 | +run_adb() { |
| 55 | + "${adb_cmd[@]}" "$@" |
| 56 | +} |
| 57 | + |
| 58 | +cleanup() { |
| 59 | + run_adb disconnect "$DEVICE_TARGET" >/dev/null 2>&1 || true |
| 60 | +} |
| 61 | +trap cleanup EXIT |
| 62 | + |
| 63 | +printf 'Connecting to %s\n' "$DEVICE_TARGET" |
| 64 | +run_adb connect "$DEVICE_TARGET" >/dev/null |
| 65 | +run_adb -s "$DEVICE_TARGET" wait-for-device |
| 66 | + |
| 67 | +device_name="$(run_adb -s "$DEVICE_TARGET" shell getprop ro.product.model 2>/dev/null | tr -d '\r' || true)" |
| 68 | +printf 'Connected: %s\n' "${device_name:-unknown}" |
| 69 | + |
| 70 | +if [[ "$LAUNCHER_ONLY" == false ]]; then |
| 71 | + [[ -f "$APK_PATH" ]] || { |
| 72 | + printf 'ERROR: APK not found at %s; use --launcher-only after store installation\n' "$APK_PATH" >&2 |
| 73 | + exit 1 |
| 74 | + } |
| 75 | + run_adb -s "$DEVICE_TARGET" install -r -g "$APK_PATH" |
| 76 | +fi |
| 77 | + |
| 78 | +if ! run_adb -s "$DEVICE_TARGET" shell pm list packages 2>/dev/null \ |
| 79 | + | grep -Fq "package:${PROJECTIVY_PACKAGE}"; then |
| 80 | + printf 'ERROR: Projectivy is not installed; install it first or provide an APK\n' >&2 |
| 81 | + exit 1 |
| 82 | +fi |
| 83 | + |
| 84 | +if [[ -n "$RESTORE_PATH" ]]; then |
| 85 | + [[ -f "$RESTORE_PATH" ]] || { |
| 86 | + printf 'ERROR: restore file not found: %s\n' "$RESTORE_PATH" >&2 |
| 87 | + exit 1 |
| 88 | + } |
| 89 | + printf 'Restoring Projectivy configuration; confirm the prompt on the TV\n' |
| 90 | + run_adb -s "$DEVICE_TARGET" restore "$RESTORE_PATH" |
| 91 | +fi |
| 92 | + |
| 93 | +if [[ -n "$BACKUP_PATH" ]]; then |
| 94 | + printf 'Backing up Projectivy configuration; confirm the prompt on the TV\n' |
| 95 | + run_adb -s "$DEVICE_TARGET" backup -f "$BACKUP_PATH" -noapk "$PROJECTIVY_PACKAGE" |
| 96 | + printf 'Backup written: %s bytes\n' "$(stat -c %s "$BACKUP_PATH" 2>/dev/null || echo missing)" |
| 97 | + exit 0 |
| 98 | +fi |
| 99 | + |
| 100 | +printf 'Setting Projectivy as the default launcher\n' |
| 101 | +run_adb -s "$DEVICE_TARGET" shell cmd package set-home-activity "$PROJECTIVY_HOME" |
| 102 | +printf 'Done. Press Home on the TV to verify Projectivy launches.\n' |
0 commit comments