Files
workphone-sdk/sdk/scripts/connection_keeper_daemon.sh

211 lines
6.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# 宿主机连接守护ADB + WS Agent 常驻保活(处理长任务时也不断链)
# 用法:
# bash sdk/scripts/connection_keeper_daemon.sh # 前台
# bash sdk/scripts/connection_keeper_daemon.sh --bg # 后台
# bash sdk/scripts/connection_keeper_daemon.sh --once # 只跑一轮稳定化
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SDK_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
LAN_ENV="${SDK_ROOT}/config/lan.env"
REQUESTED_ADB_PORT="${ANDROID_ADB_SERVER_PORT:-}"
[[ -f "${LAN_ENV}" ]] && source "${LAN_ENV}" || true
[[ -n "${REQUESTED_ADB_PORT}" ]] && export ANDROID_ADB_SERVER_PORT="${REQUESTED_ADB_PORT}"
SDK_PORT="${WORKPHONE_SDK_PORT:-8899}"
INTERVAL="${KEEPER_INTERVAL:-15}"
FAST_INTERVAL="${KEEPER_FAST_INTERVAL:-8}"
DEVICE_SERIAL="${DEVICE_SERIAL:-}"
DEVICE_ID="${DEVICE_ID:-xgfe65eimrrofyws}"
export ANDROID_ADB_SERVER_PORT="${ANDROID_ADB_SERVER_PORT:-5037}"
ADB=(adb -P "${ANDROID_ADB_SERVER_PORT}")
LOG="${SDK_ROOT}/logs/connection_keeper.log"
PID_FILE="${SDK_ROOT}/logs/connection_keeper.pid"
mkdir -p "${SDK_ROOT}/logs"
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; }
is_phone_serial() {
local s="$1"
local brand
brand=$("${ADB[@]}" -s "$s" shell getprop ro.product.brand 2>/dev/null | tr -d '\r')
[[ "$brand" != "haier" ]]
}
pick_serial() {
if [[ -n "$DEVICE_SERIAL" ]]; then
if "${ADB[@]}" -s "$DEVICE_SERIAL" get-state 2>/dev/null | grep -qx device && is_phone_serial "$DEVICE_SERIAL"; then
echo "$DEVICE_SERIAL"
return
fi
fi
local s
while IFS= read -r s; do
[[ -z "$s" ]] && continue
is_phone_serial "$s" || continue
echo "$s"
return
done < <("${ADB[@]}" devices 2>/dev/null | awk '/\tdevice$/{print $1}')
}
usb_xiaomi_present() {
ioreg -p IOUSB -l 2>/dev/null | grep -q "Xiaomi" 2>/dev/null
}
try_wireless_ports() {
local host="${1:-192.168.1.12}"
if usb_xiaomi_present; then
log "USB Xiaomi detected → skip wireless port scan (优先等 MTP/授权)"
return 1
fi
ping -c 1 -W 2 "$host" >/dev/null 2>&1 || return 1
"${ADB[@]}" reconnect offline >/dev/null 2>&1 || true
local p open_port="" hits=0
for p in 5555 $(seq 37000 37005); do
if nc -z -G 1 "$host" "$p" 2>/dev/null; then
hits=$((hits + 1))
[[ "$hits" -gt 3 ]] && break
log "wireless port open ${host}:${p} → adb connect"
( "${ADB[@]}" connect "${host}:${p}" & pid=$!; sleep 3; kill $pid 2>/dev/null; wait $pid 2>/dev/null ) || true
if "${ADB[@]}" -s "${host}:${p}" get-state 2>/dev/null | grep -qx device; then
DEVICE_SERIAL="${host}:${p}"
echo "$DEVICE_SERIAL"
return 0
fi
"${ADB[@]}" disconnect "${host}:${p}" >/dev/null 2>&1 || true
fi
done
return 1
}
ws_online_count() {
curl -s "http://127.0.0.1:${SDK_PORT}/api/v3/connection/status" 2>/dev/null | \
python3 -c "import sys,json;d=json.load(sys.stdin).get('data',{});print(d.get('online_ws_count',0))" 2>/dev/null || echo 0
}
u2_online() {
curl -s "http://127.0.0.1:${SDK_PORT}/api/v3/devices/${DEVICE_ID}" 2>/dev/null | \
python3 -c "import sys,json;d=json.load(sys.stdin).get('data',{});print('1' if d.get('quick_status',{}).get('u2') else '0')" 2>/dev/null || echo 0
}
ensure_adb_server() {
if nc -z 127.0.0.1 "${ANDROID_ADB_SERVER_PORT}" 2>/dev/null; then
return 0
fi
"${ADB[@]}" start-server 2>/dev/null || true
sleep 1
}
adb_devices_safe() {
( "${ADB[@]}" devices "$@" & pid=$!; sleep 8; kill "$pid" 2>/dev/null; wait "$pid" 2>/dev/null ) 2>/dev/null || true
}
keeper_once() {
ensure_adb_server
ws="$(ws_online_count)"
u2_ok="$(u2_online)"
if [[ "$ws" -ge 1 && "$u2_ok" == "1" ]]; then
log "ok ws_online=${ws} u2=1"
return 0
fi
if [[ "$ws" -ge 1 ]]; then
log "ws_online=${ws} but u2=${u2_ok} → continue adb/u2 recovery"
fi
serial="$(pick_serial || true)"
if [[ -z "$serial" ]]; then
if usb_xiaomi_present; then
log "USB 已插入但未 adb device → 请在手机选「传输文件」并允许 USB 调试;或开启无线调试"
# USB 未授权时仍尝试无线 ADB与 USB 并行)
for ip in ${WIRELESS_IPS:-192.168.110.80 192.168.3.1}; do
if serial="$(try_wireless_ports "$ip" || true)" && [[ -n "$serial" ]]; then
log "wireless adb ok ${serial}"
break
fi
done
serial="$(pick_serial || true)"
else
for ip in ${WIRELESS_IPS:-192.168.110.80 192.168.110.60 192.168.110.197 192.168.3.1 192.168.1.12}; do
if serial="$(try_wireless_ports "$ip" || true)" && [[ -n "$serial" ]]; then
break
fi
( "${ADB[@]}" connect "${ip}:5555" & pid=$!; sleep 3; kill "$pid" 2>/dev/null; wait "$pid" 2>/dev/null ) || true
done
serial="$(pick_serial || true)"
fi
fi
if [[ -z "$serial" ]]; then
log "no adb device — 若手机 Termux Agent 已配置 NAS/frp 寻服,可忽略;否则 USB 授权一次做 OTA"
bash "${SCRIPT_DIR}/sdk_connection_watcher.sh" --once >>"$LOG" 2>&1 || true
ws="$(ws_online_count)"
[[ "$ws" -ge 1 ]] && log "sdk_watcher recovered ws=${ws}" && return 0
return 1
fi
state="$("${ADB[@]}" -s "$serial" get-state 2>/dev/null || echo offline)"
if [[ "$state" == "unauthorized" ]]; then
log "adb unauthorized serial=${serial} → 请在手机点「允许 USB 调试」"
return 1
fi
if [[ "$state" != "device" ]]; then
log "adb not ready serial=${serial} state=${state}"
return 1
fi
ws="$(ws_online_count)"
if [[ "$ws" -ge 1 ]]; then
log "ok serial=${serial} ws_online=${ws}"
return 0
fi
log "adb ok but ws=0 → termux/on-device agent serial=${serial}"
DEVICE_SERIAL="$serial" DEVICE_ID="${DEVICE_ID:-xgfe65eimrrofyws}" \
bash "${SCRIPT_DIR}/termux_push_and_start_agent.sh" >>"$LOG" 2>&1 || true
ws="$(ws_online_count)"
if [[ "$ws" -ge 1 ]]; then
log "termux/oneclick ok ws_online=${ws}"
return 0
fi
log "still ws=0 after termux_push"
return 1
}
keeper_loop() {
log "connection_keeper start interval=${INTERVAL}s fast=${FAST_INTERVAL}s port=${SDK_PORT} lan=${WORKPHONE_LAN_IP:-auto}"
while true; do
if keeper_once; then
sleep "$INTERVAL"
else
sleep "$FAST_INTERVAL"
fi
done
}
case "${1:-}" in
--once)
keeper_once
;;
--bg)
if [[ -f "$PID_FILE" ]] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
echo "已在运行 PID $(cat "$PID_FILE")"
exit 0
fi
nohup bash "$0" >>"$LOG" 2>&1 &
echo $! >"$PID_FILE"
echo "connection_keeper 后台 PID $(cat "$PID_FILE") log=$LOG"
;;
--stop)
if [[ -f "$PID_FILE" ]]; then
kill "$(cat "$PID_FILE")" 2>/dev/null || true
rm -f "$PID_FILE"
echo "已停止"
fi
;;
*)
keeper_loop
;;
esac