Files
workphone-sdk/sdk/connect_all.sh

325 lines
10 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

#!/bin/bash
# ================================================================
# 一键恢复脚本 — 5种控制模式全部打通
# 用法: bash connect_all.sh
#
# 执行前提: 设备已完成 USB 调试授权(设备屏幕点击"允许"
# ================================================================
set -e
SDK_DIR="$(cd "$(dirname "$0")" && pwd)"
APP_DIR="$SDK_DIR/app"
SERVER_URL="http://127.0.0.1:8899"
WS_URL="ws://127.0.0.1:8899/ws/device"
AGENT_APK="$SDK_DIR/android-app/app/build/outputs/apk/debug/app-debug.apk"
FRIDA_SERVER="/data/local/tmp/frida-server"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
ok() { echo -e "${GREEN}$1${NC}"; }
warn() { echo -e "${YELLOW}⚠️ $1${NC}"; }
fail() { echo -e "${RED}$1${NC}"; }
info() { echo -e "${BLUE} $1${NC}"; }
PASS=0
FAIL=0
WARN=0
# ================================================================
# 0. 前置检查
# ================================================================
echo ""
echo "=========================================="
echo " 机擎 SDK — 五通道一键恢复"
echo "=========================================="
echo ""
# 检查 ADB
if ! command -v adb &>/dev/null; then
fail "ADB 未安装"
exit 1
fi
# 检查设备
DEVICE_STATUS=$(adb devices | grep -v "List" | grep -v "^$" | head -1)
if [ -z "$DEVICE_STATUS" ]; then
fail "未检测到设备,请连接 USB"
exit 1
fi
SERIAL=$(echo "$DEVICE_STATUS" | awk '{print $1}')
STATUS=$(echo "$DEVICE_STATUS" | awk '{print $2}')
if [ "$STATUS" = "unauthorized" ]; then
fail "设备 $SERIAL 未授权"
echo ""
echo " 请在设备屏幕上:"
echo " 1. 找到「允许USB调试」对话框"
echo " 2. 勾选「始终允许此计算机」"
echo " 3. 点击「确定」"
echo ""
echo " 授权后重新运行此脚本"
exit 1
fi
if [ "$STATUS" != "device" ]; then
fail "设备状态异常: $STATUS"
exit 1
fi
ok "ADB 已连接: $SERIAL ($STATUS)"
PASS=$((PASS+1))
# 获取设备信息
MODEL=$(adb -s "$SERIAL" shell getprop ro.product.model 2>/dev/null | tr -d '\r')
ANDROID=$(adb -s "$SERIAL" shell getprop ro.build.version.release 2>/dev/null | tr -d '\r')
ANDROID_ID=$(adb -s "$SERIAL" shell settings get secure android_id 2>/dev/null | tr -d '\r')
DEVICE_ID=$(echo -n "$ANDROID_ID" | md5 -q 2>/dev/null || echo -n "$ANDROID_ID" | md5sum | awk '{print $1}')
echo " 设备: $MODEL | Android $ANDROID"
echo " 设备ID: $DEVICE_ID"
echo ""
# ================================================================
# 1. 检查/启动 SDK 服务器
# ================================================================
info "检查 SDK 服务器..."
HEALTH=$(curl -s --connect-timeout 3 "$SERVER_URL/health" 2>/dev/null || echo "")
if echo "$HEALTH" | grep -q '"healthy"'; then
ok "SDK 服务器运行中"
PASS=$((PASS+1))
else
warn "SDK 服务器未运行,正在启动..."
lsof -ti :8899 2>/dev/null | xargs kill -9 2>/dev/null || true
sleep 2
cd "$APP_DIR"
nohup python3 -m uvicorn main:app --host 0.0.0.0 --port 8899 --reload > /tmp/sdk_server.log 2>&1 &
sleep 5
HEALTH=$(curl -s --connect-timeout 5 "$SERVER_URL/health" 2>/dev/null || echo "")
if echo "$HEALTH" | grep -q '"healthy"'; then
ok "SDK 服务器已启动"
PASS=$((PASS+1))
else
fail "SDK 服务器启动失败,查看 /tmp/sdk_server.log"
FAIL=$((FAIL+1))
fi
fi
echo ""
# ================================================================
# 2. ADB 反向代理(让设备 127.0.0.1:8899 指向 Mac
# ================================================================
info "设置 ADB 反向代理..."
adb -s "$SERIAL" reverse tcp:8899 tcp:8899 2>/dev/null
if [ $? -eq 0 ]; then
ok "ADB reverse 已设置 (设备 127.0.0.1:8899 → Mac)"
PASS=$((PASS+1))
else
fail "ADB reverse 设置失败"
FAIL=$((FAIL+1))
fi
echo ""
# ================================================================
# 3. 通道一ADB 静默控制验证
# ================================================================
info "验证 ADB 静默控制..."
ADB_SCREENSHOT=$(adb -s "$SERIAL" shell screencap -p /sdcard/test_connect.png 2>&1)
if [ $? -eq 0 ]; then
ok "ADB 控制可用 (截图成功)"
adb -s "$SERIAL" shell rm -f /sdcard/test_connect.png 2>/dev/null
PASS=$((PASS+1))
else
fail "ADB 控制失败: $ADB_SCREENSHOT"
FAIL=$((FAIL+1))
fi
echo ""
# ================================================================
# 4. 通道二Agent WebSocket 验证
# ================================================================
info "验证 Agent WebSocket..."
AGENT_INSTALLED=$(adb -s "$SERIAL" shell pm list packages 2>/dev/null | grep "com.workphone.agent" || echo "")
if [ -z "$AGENT_INSTALLED" ]; then
warn "Agent App 未安装"
if [ -f "$AGENT_APK" ]; then
info "正在安装 Agent App..."
adb -s "$SERIAL" install -r -g "$AGENT_APK" 2>/dev/null
if [ $? -eq 0 ]; then
ok "Agent App 安装成功"
else
fail "Agent App 安装失败"
FAIL=$((FAIL+1))
fi
else
warn "APK 不存在: $AGENT_APK,跳过安装"
WARN=$((WARN+1))
fi
else
ok "Agent App 已安装"
fi
# 启动 Agent App
adb -s "$SERIAL" shell am start -n com.workphone.agent/.MainActivity 2>/dev/null
sleep 3
# 检查 WebSocket 连接
HEALTH2=$(curl -s --connect-timeout 3 "$SERVER_URL/health" 2>/dev/null || echo "")
WS_ONLINE=$(echo "$HEALTH2" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('devices_online',0))" 2>/dev/null || echo "0")
if [ "$WS_ONLINE" -gt 0 ] 2>/dev/null; then
ok "Agent WebSocket 在线 (设备数: $WS_ONLINE)"
PASS=$((PASS+1))
else
warn "Agent WebSocket 未连接 (可能需要在App中手动连接)"
WARN=$((WARN+1))
fi
echo ""
# ================================================================
# 5. 通道三Hook / Frida 验证
# ================================================================
info "验证 Hook / Frida..."
IS_ROOTED=$(adb -s "$SERIAL" shell "su -c 'id' 2>/dev/null" | tr -d '\r')
if echo "$IS_ROOTED" | grep -q "uid=0"; then
ok "Root 权限可用"
FRIDA_RUNNING=$(adb -s "$SERIAL" shell "su -c 'ps -ef | grep frida-server | grep -v grep'" 2>/dev/null | tr -d '\r')
if [ -n "$FRIDA_RUNNING" ]; then
ok "Frida Server 运行中"
PASS=$((PASS+1))
else
FRIDA_EXISTS=$(adb -s "$SERIAL" shell "su -c 'ls $FRIDA_SERVER'" 2>/dev/null | tr -d '\r')
if echo "$FRIDA_EXISTS" | grep -q "frida-server"; then
info "启动 Frida Server..."
adb -s "$SERIAL" shell "su -c 'chmod 755 $FRIDA_SERVER && $FRIDA_SERVER -D &'" 2>/dev/null &
sleep 3
FRIDA_CHECK=$(adb -s "$SERIAL" shell "su -c 'ps -ef | grep frida-server | grep -v grep'" 2>/dev/null)
if [ -n "$FRIDA_CHECK" ]; then
ok "Frida Server 已启动"
PASS=$((PASS+1))
else
warn "Frida Server 启动失败(可能需要 Magisk 授权)"
WARN=$((WARN+1))
fi
else
warn "Frida Server 未部署到设备"
WARN=$((WARN+1))
fi
fi
else
warn "Root 权限不可用(需要 Magisk 授权 Shell"
WARN=$((WARN+1))
fi
echo ""
# ================================================================
# 6. 通道四AI Agent 验证
# ================================================================
info "验证 AI Agent..."
AI_STATUS=$(curl -s --connect-timeout 3 "$SERVER_URL/api/v3/ai/status" 2>/dev/null || echo "")
if echo "$AI_STATUS" | grep -q '"available"'; then
ok "AI 引擎可用"
PASS=$((PASS+1))
else
AI_AVAIL=$(echo "$AI_STATUS" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('available',''))" 2>/dev/null || echo "")
if [ "$AI_AVAIL" = "True" ] || [ "$AI_AVAIL" = "true" ]; then
ok "AI 引擎可用"
PASS=$((PASS+1))
else
warn "AI 引擎不可用(需配置 DEEPSEEK_API_KEY 或 Ollama"
WARN=$((WARN+1))
fi
fi
echo ""
# ================================================================
# 7. 通道五scrcpy 验证
# ================================================================
info "验证 scrcpy..."
if command -v scrcpy &>/dev/null; then
ok "scrcpy 已安装"
PASS=$((PASS+1))
info "可运行: scrcpy -s $SERIAL --max-size 1024"
else
warn "scrcpy 未安装 (brew install scrcpy)"
WARN=$((WARN+1))
fi
echo ""
# ================================================================
# 8. 心跳监控验证
# ================================================================
info "验证 AI 心跳监控..."
HB_DASH=$(curl -s --connect-timeout 3 "$SERVER_URL/api/v3/heartbeat/dashboard" 2>/dev/null || echo "")
if echo "$HB_DASH" | grep -q '"total_devices"'; then
TOTAL=$(echo "$HB_DASH" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('total_devices',0))" 2>/dev/null || echo "0")
AVG=$(echo "$HB_DASH" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('avg_score',0))" 2>/dev/null || echo "0")
ok "心跳监控在线 (设备: $TOTAL, 平均健康分: $AVG)"
PASS=$((PASS+1))
else
warn "心跳监控数据暂无(等待首次心跳)"
WARN=$((WARN+1))
fi
echo ""
# ================================================================
# 9. 注册设备映射
# ================================================================
info "注册设备映射..."
REGISTER_RESULT=$(curl -s -X POST --connect-timeout 3 "$SERVER_URL/api/v3/devices/$DEVICE_ID/connection-modes" 2>/dev/null || echo "")
if [ -n "$REGISTER_RESULT" ]; then
ok "连接模式已评估"
PASS=$((PASS+1))
fi
echo ""
# ================================================================
# 总结
# ================================================================
echo "=========================================="
echo " 恢复结果"
echo "=========================================="
echo ""
echo -e " ${GREEN}通过: $PASS${NC}"
echo -e " ${YELLOW}警告: $WARN${NC}"
echo -e " ${RED}失败: $FAIL${NC}"
echo ""
if [ $FAIL -eq 0 ]; then
echo -e "${GREEN}所有关键通道已就绪!${NC}"
else
echo -e "${RED}$FAIL 个通道需要修复${NC}"
fi
echo ""
echo " 控制台: $SERVER_URL"
echo " API文档: $SERVER_URL/docs"
echo " 设备ID: $DEVICE_ID"
echo " ADB序列号: $SERIAL"
echo ""