diff --git a/android/termux-setup/50_mod_adb.sh b/android/termux-setup/50_mod_adb.sh index 99185c5..26d5d9d 100644 --- a/android/termux-setup/50_mod_adb.sh +++ b/android/termux-setup/50_mod_adb.sh @@ -4,6 +4,92 @@ # ------------------------- # ADB wireless pair/connect wizard # ------------------------- + +# Local stamp so we can detect "connect-only" misuse after reinstall/clear-data. +ADB_PAIRED_STAMP="${ADB_STATE_DIR}/stamp.adb_paired" + +adb_hostkey_fingerprint() { + # Returns a stable fingerprint for THIS Termux install's adb host key. + local pub="${HOME}/.android/adbkey.pub" + [[ -r "$pub" ]] || return 1 + if have sha256sum; then + sha256sum "$pub" | awk '{print $1}' + elif have shasum; then + shasum -a 256 "$pub" | awk '{print $1}' + elif have openssl; then + openssl dgst -sha256 "$pub" 2>/dev/null | awk '{print $2}' + elif have md5sum; then + md5sum "$pub" | awk '{print $1}' + else + return 1 + fi +} + +adb_stamp_write() { + # args: mode serial + local mode="$1" serial="$2" fp="" + fp="$(adb_hostkey_fingerprint 2>/dev/null || true)" + { + echo "ts=$(date -Is 2>/dev/null || date || true)" + echo "mode=${mode}" + echo "host=${HOST}" + echo "serial=${serial}" + echo "connect_port=${CONNECT_PORT:-}" + echo "hostkey_fp=${fp}" + } >"$ADB_PAIRED_STAMP" 2>/dev/null || true + chmod 600 "$ADB_PAIRED_STAMP" 2>/dev/null || true +} + +adb_stamp_read_fp() { + [[ -r "$ADB_PAIRED_STAMP" ]] || return 1 + sed -n 's/^hostkey_fp=//p' "$ADB_PAIRED_STAMP" 2>/dev/null | head -n 1 +} + +adb_warn_connect_only_if_suspicious() { + # Called only in connect-only flows. + local cur_fp old_fp + cur_fp="$(adb_hostkey_fingerprint 2>/dev/null || true)" + old_fp="$(adb_stamp_read_fp 2>/dev/null || true)" + + if [[ ! -f "$ADB_PAIRED_STAMP" ]]; then + warn "connect-only assumes THIS Termux install has been paired before." + warn "No local pairing stamp found ($ADB_PAIRED_STAMP)." + warn "If you reinstalled Termux / cleared data / changed user, you must re-pair (run: --adb-only)." + [[ -n "$cur_fp" ]] && warn "Current ADB hostkey fingerprint: ${cur_fp:0:12}..." + return 0 + fi + + if [[ -n "$old_fp" && -n "$cur_fp" && "$old_fp" != "$cur_fp" ]]; then + warn_red "ADB host key changed since last pairing stamp." + warn "Old fingerprint: ${old_fp:0:12}... Current: ${cur_fp:0:12}..." + warn "Android Wireless debugging -> Paired devices: remove the old entry, then run: --adb-only" + fi +} + +adb_connect_verify() { + # args: serial (HOST:PORT) + local serial="$1" out rc start now state + set +e + out="$(adb connect "$serial" 2>&1)" + rc=$? + set -e + + # Always verify via `adb devices` (adb may exit 0 even on failure). + start="$(date +%s)" + while true; do + state="$(adb_device_state "$serial" || true)" + [[ "$state" == "device" ]] && { printf '%s\n' "$out"; return 0; } + now="$(date +%s)" + (( now - start >= 5 )) && break + sleep 1 + done + + warn_red "adb connect did not result in a usable device entry for: $serial (state='${state:-none}')." + warn "adb connect output: ${out:-}" + warn "If you recently reinstalled Termux/cleared data, the phone may show an OLD paired device. Remove it and re-pair." + return 1 +} + cleanup_offline_loopback() { local keep_serial="$1" # e.g. 127.0.0.1:41313 local serial state rest @@ -28,6 +114,7 @@ adb_pair_connect() { adb start-server >/dev/null 2>&1 || true if [[ "$ONLY_CONNECT" == "1" ]]; then + adb_warn_connect_only_if_suspicious if [[ -n "$CONNECT_PORT" ]]; then CONNECT_PORT="${CONNECT_PORT//[[:space:]]/}" [[ "$CONNECT_PORT" =~ ^[0-9]{5}$ ]] || die "Invalid CONNECT PORT (must be 5 digits): '$CONNECT_PORT'" @@ -39,7 +126,7 @@ adb_pair_connect() { local serial="${HOST}:${CONNECT_PORT}" adb disconnect "$serial" >/dev/null 2>&1 || true echo "[*] adb connect $serial" - adb connect "$serial" >/dev/null || die "adb connect failed to $serial. Verify Wireless debugging is enabled and CONNECT PORT is correct." + adb_connect_verify "$serial" >/dev/null || die "adb connect failed to $serial. Verify Wireless debugging is enabled, and pairing exists for THIS Termux install." if [[ "$CLEANUP_OFFLINE" == "1" ]]; then cleanup_offline_loopback "$serial" @@ -50,6 +137,7 @@ adb_pair_connect() { echo "[*] ADB check (shell):" adb -s "$serial" shell sh -lc 'echo "it worked: adb shell is working"; id' || true + adb_stamp_write "connect-only" "$serial" cleanup_notif ok "ADB connected (connect-only): $serial" @@ -79,7 +167,7 @@ adb_pair_connect() { printf '%s\n' "$code" | adb pair "${HOST}:${pair_port}" || die "adb pair failed. Verify PAIR PORT and PAIR CODE (and that the pairing dialog is showing)." echo "[*] adb connect $serial" - adb connect "$serial" >/dev/null || die "adb connect failed after pairing. Re-check CONNECT PORT and Wireless debugging." + adb_connect_verify "$serial" >/dev/null || die "adb connect failed after pairing. Re-check CONNECT PORT and Wireless debugging." if [[ "$CLEANUP_OFFLINE" == "1" ]]; then cleanup_offline_loopback "$serial" @@ -90,6 +178,7 @@ adb_pair_connect() { echo "[*] ADB check (shell):" adb -s "$serial" shell sh -lc 'echo "it worked: adb shell is working"; getprop ro.product.model; getprop ro.build.version.release' || true + adb_stamp_write "paired" "$serial" cleanup_notif ok "ADB connected: $serial"