1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 03:18:32 +03:00
Files
android_cast/scripts/adb-reconnect.sh
2026-06-11 14:55:46 +02:00

227 lines
6.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Wireless adb discovery + reconnect helpers (sourced by rebuild.sh).
# Discovers endpoints via: connected devices, adb mdns, HTTP :5039/adb.json, cache, static hints.
: "${ADB_CONNECT_RETRIES:=4}"
: "${ADB_CONNECT_DELAY_SEC:=2}"
: "${DEV_ADB_HTTP_PORT:=5039}"
: "${ADB_CONNECT_CACHE:=$ROOT/.adb_connect_cache}"
: "${ADB_RECONNECT_POKE_DELAY_SEC:=2}"
declare -gA CONNECTIONS_LIST_HINTS
adb_reconnect_init_hints() {
CONNECTIONS_LIST_HINTS["192_168_33_153"]="[A13] Android Projector"
CONNECTIONS_LIST_HINTS["192_168_33_39"]="[A16] Doogee Tab G6 Max / P8_EEA"
CONNECTIONS_LIST_HINTS["192_168_33_106"]="[A11] BlackView BL6000Pro / BL6000Pro_EEA"
CONNECTIONS_LIST_HINTS["192_168_33_173"]="[A11] BlackView BL6000Pro / BL6000Pro"
}
adb_hint_key_for_ip() {
local ip=${1}
ip="$(echo "${ip}" | sed -e 's@\.@_@g' -e 's@:.*@@' | tr -d '\n')"
printf '%s' "${ip}"
}
adb_ip_for_hint_key() {
local ip=${1}
ip="$(echo "${ip}" | sed -e 's/@_@/./g' -e 's/:.*//' | tr -d '\n')"
printf '%s' "${ip}"
}
adb_hint_for_endpoint() {
local endpoint=${1}
local key
key="$(adb_hint_key_for_ip "${endpoint}")"
printf '%s' "${CONNECTIONS_LIST_HINTS[${key}]:-}"
}
adb_collect_candidate_ips() {
local ip endpoint key
if [[ -f "$ADB_CONNECT_CACHE" ]]; then
while IFS= read -r endpoint; do
[[ -z "$endpoint" ]] && continue
ip="${endpoint%%:*}"
[[ -n "$ip" ]] && printf '%s\n' "$ip"
done < "$ADB_CONNECT_CACHE"
fi
for key in "${!CONNECTIONS_LIST_HINTS[@]}"; do
adb_ip_for_hint_key "$key"
done
adb devices -l 2>/dev/null | awk '/^[^ ]+ +device/ { print $1 }' | while read -r serial; do
[[ "$serial" == *:* ]] || continue
printf '%s\n' "${serial%%:*}"
done
}
adb_json_connect_lines() {
local json=${1}
[[ -n "$json" ]] || return 0
printf '%s' "$json" | python3 -c '
import json, sys
raw = sys.stdin.read()
if not raw.strip():
raise SystemExit(0)
try:
data = json.loads(raw)
except json.JSONDecodeError:
raise SystemExit(0)
for item in data.get("connect") or []:
if item:
print(item)
for item in data.get("commands") or []:
if isinstance(item, str) and item.startswith("adb connect "):
print(item[len("adb connect "):])
' 2>/dev/null || true
}
adb_fetch_http_endpoints() {
local ip json
for ip in $(adb_collect_candidate_ips | sort -u); do
[[ -z "$ip" ]] && continue
json="$(curl -m 3 -sf "http://${ip}:${DEV_ADB_HTTP_PORT}/adb.json" 2>/dev/null || true)"
[[ -z "$json" ]] && continue
adb_json_connect_lines "$json"
done
}
adb_discover_mdns_endpoints() {
local line name service hostport
while IFS= read -r line; do
[[ "$line" == *"_adb._tcp"* ]] || continue
hostport="$(awk '{print $NF}' <<<"$line")"
[[ "$hostport" == *:* ]] || continue
printf '%s\n' "$hostport"
done < <(adb mdns services 2>/dev/null || true)
}
adb_pull_device_json_endpoints() {
local serial json tmp
while IFS= read -r serial; do
[[ -z "$serial" ]] && continue
tmp="$(mktemp)"
if adb -s "$serial" exec-out run-as com.foxx.androidcast cat files/dev/adb_connect.json \
>"$tmp" 2>/dev/null; then
json="$(cat "$tmp")"
rm -f "$tmp"
adb_json_connect_lines "$json"
else
rm -f "$tmp"
fi
done < <(adb devices 2>/dev/null | awk 'NR > 1 && $2 == "device" { print $1 }')
}
adb_discover_endpoints() {
local endpoint
declare -A seen=()
local -a ordered=()
add_endpoint() {
local e=${1}
[[ -z "$e" ]] && return 0
[[ -n "${seen[$e]:-}" ]] && return 0
seen["$e"]=1
ordered+=("$e")
}
while IFS= read -r endpoint; do
add_endpoint "$endpoint"
done < <(adb_discover_mdns_endpoints)
while IFS= read -r endpoint; do
add_endpoint "$endpoint"
done < <(adb_fetch_http_endpoints)
while IFS= read -r endpoint; do
add_endpoint "$endpoint"
done < <(adb_pull_device_json_endpoints)
if [[ -f "$ADB_CONNECT_CACHE" ]]; then
while IFS= read -r endpoint; do
add_endpoint "$endpoint"
done < "$ADB_CONNECT_CACHE"
fi
local key ip
for key in "${!CONNECTIONS_LIST_HINTS[@]}"; do
ip="$(adb_ip_for_hint_key "$key")"
add_endpoint "${ip}:5555"
add_endpoint "${ip}"
done
printf '%s\n' "${ordered[@]}"
}
adb_poke_refresh_broadcast() {
local serial
while IFS= read -r serial; do
[[ -z "$serial" ]] && continue
adb -s "$serial" shell am broadcast \
-a com.foxx.androidcast.dev.REFRESH_ADB_WIFI \
-n com.foxx.androidcast/.dev.DevAdbWifiReceiver >/dev/null 2>&1 || true
done < <(adb devices 2>/dev/null | awk 'NR > 1 && $2 == "device" { print $1 }')
}
adb_reconnect_endpoint() {
local endpoint="$1"
[[ -z "$endpoint" ]] && return 1
local attempt out hint
hint="$(adb_hint_for_endpoint "${endpoint}")"
[[ -n "${hint}" ]] && hint="(${hint})"
echo " adb connect ${endpoint} ${hint}"
adb disconnect "$endpoint" >/dev/null 2>&1 || true
for (( attempt = 1; attempt <= ADB_CONNECT_RETRIES; attempt++ )); do
out="$(adb connect "$endpoint" 2>&1)" || true
if grep -qiE 'connected|already' <<<"$out"; then
if adb -s "$endpoint" get-state 2>/dev/null | grep -q '^device$'; then
echo " ${endpoint} — ready"
return 0
fi
fi
if [[ "$attempt" -lt "$ADB_CONNECT_RETRIES" ]]; then
sleep "$ADB_CONNECT_DELAY_SEC"
fi
done
echo " ${endpoint} — not reachable (${out})" >&2
return 1
}
adb_update_connect_cache() {
local serial
mkdir -p "$(dirname "$ADB_CONNECT_CACHE")"
: >"$ADB_CONNECT_CACHE"
while IFS= read -r serial; do
[[ "$serial" == *:* ]] || continue
echo "$serial" >>"$ADB_CONNECT_CACHE"
done < <(adb devices 2>/dev/null | awk 'NR > 1 && $2 == "device" { print $1 }')
}
adb_reconnect_all() {
echo "==> Reconnecting wireless adb targets"
adb start-server >/dev/null 2>&1 || true
adb reconnect offline >/dev/null 2>&1 || true
adb_poke_refresh_broadcast
if [[ "${ADB_RECONNECT_POKE_DELAY_SEC:-0}" -gt 0 ]]; then
sleep "$ADB_RECONNECT_POKE_DELAY_SEC"
fi
local endpoint connected=0
while IFS= read -r endpoint; do
[[ -z "$endpoint" ]] && continue
if adb_reconnect_endpoint "$endpoint"; then
connected=$((connected + 1))
fi
done < <(adb_discover_endpoints)
adb_update_connect_cache
adb devices -l
if [[ "$connected" -gt 0 ]]; then
return 0
fi
return 1
}
adb_count_ready_devices() {
adb devices 2>/dev/null | awk 'NR > 1 && $2 == "device" { c++ } END { print c+0 }'
}