bash code/startServer/start-adb-server.sh启动时先完成 Codex 登录检查,再启动服务。Agent 运行期间每 2 秒检查所选手机的
ADB 反向端口映射,仅重建缺失或指向错误端口的映射,不重复绑定正常映射。
拔插 USB、手机切换 USB 模式、ADB daemon 重启可能使映射消失,即使 adb devices
已显示 device,应用仍然无法连接,守护线程会在设备恢复授权后自动修复。
默认控制口为 17890,APK 下载口为 17891。只有这两个映射由当前服务管理。
程序广场在每次手机应用进程启动后的首次连接成功时发送一次 catalog_check。
服务端返回可下载程序列表及完成标记;手机按任务 ID 和 APK 摘要与本地已安装文件比较。
云端存在本地缺少的程序或版本时显示“同步”,否则隐藏;检查本身不下载程序。
点击同步下载启动检查得到的差异以及本地任务已完成的待同步版本,全部成功后隐藏按钮。
重连、切换页面不会重新检查全量目录;同一进程中新发布的无关程序在下次启动后参与比较。
本地有制作中、待同步或下载未完成的任务时,每次连接成功发送 task_check,只按这些任务 ID
查询最新状态,补回断线期间遗漏的完成通知。完成状态只更新卡片与同步按钮,不自动下载。
客户端与服务端需同时更新。
首次只有一台已授权设备时自动选中并固定设备;之后不会随另一台设备上线而切换。 多设备环境显式选择:
ANDROID_SERIAL=<手机序列号> bash code/startServer/start-adb-server.sh直接运行 Python 时可选择启用相同功能:
python3 code/agent/main.py --adb-reverse --adb-serial <手机序列号>服务退出时守护线程结束;下次启动仍先完成 Codex 登录。正在运行的旧版服务需重启, 才能启用新增的映射维护功能。手机 0.1.3 起,自动连接不再达到次数上限后停止: 短暂失败先快速重试,连续失败后每 30 秒重试;手动「断开」仍会停止重试。
adb devices -l
adb -s <手机序列号> reverse --list
lsof -nP -iTCP:17890 -iTCP:17891 -sTCP:LISTEN
adb -s <手机序列号> reverse tcp:17890 tcp:17890
adb -s <手机序列号> reverse tcp:17891 tcp:17891adb devices为unauthorized:先在手机确认 USB 调试授权。- 设备在线但
reverse --list为空:恢复上面的两个映射。 - 映射正常但电脑没有监听:启动电脑端服务。
- 使用旧版手机应用且自动重试已停止:映射恢复后点「重试连接」。
- 下载日志
HTTP 200说明对应请求的 HTTP 响应正常,不表示控制连接一直正常,也不能单独证明 APK 已安装成功。
现场初始状态:设备已授权在线、电脑 17890/17891 均监听,但 adb reverse --list 为空。
恢复两条映射并安装 phone_agent 0.1.3 后,手机显示「已连接」,控制 socket 为 ESTABLISHED。
重启服务加载守护线程后,手机自动重新连接;再手动删除两条映射,服务日志输出
adb reverse: restored ports 17890, 17891,两条映射自动恢复且控制连接保持正常。
此处模拟的是映射丢失,没有物理拔插 USB。
回归:映射维护 7 项、启动认证/集成 10 项、控制通道 10 项 Python 测试通过; Android 连接模块 7 项单元测试通过,APK 构建通过,Lint 0 错误、33 警告。
客户端的「已连接」从 TCP 建连成功改为应用层握手确认:
- 新连接立即发送
{"type":"ping","text":"<随机探针>"};服务端回复pong并原样返回探针。 - 最多等待 5 秒完成首次确认,未收到匹配回复保持连接中,超时失败并重试。
- 确认后每 5 秒发送一次探针,距上次有效回复超过 15 秒则关闭连接并自动重连。 EOF/读写错误被发现时直接断开,不必等满 15 秒。
ping/pong不出现在对话里,不调用 LLM,也不经过业务任务队列。- 心跳超时检查与发送分开运行,阻塞写入不会阻塞超时检测。
- 每次重试使用独立 TCP 连接,旧连接回调不能改变新连接的状态;重试操作串行清理。
必须同时更新客户端与 PC 服务。旧服务不支持 pong,新版客户端会明确判定未确认,
不会为了兼容旧版而回退为仅凭 TCP 显示已连接。心跳判断的是控制服务可达,不是 LLM/编译任务已完成。
0.1.4 回归结果:连接模块 14 项 JVM 单元测试、服务端心跳 3 项及控制通道 10 项 Python 回归通过;构建与 Lint 通过(0 错误、33 警告)。真机已安装 0.1.4:
- 暂停服务进程响应 18 秒:从「已连接」变为「连接中」,恢复进程后自动回到「已连接」。
- 真正结束服务并确认控制端口不再监听:手机变为「重试连接」。
- 重启服务:自动完成新握手并回到「已连接」。
首次退出测试因手机自动锁屏未能读取对话页;解锁后已重新完成上述退出与恢复验证。
手机连接后自动检查音频 API、媒体音量、默认引擎的离线英文 TTS,并静默合成固定样本。
日志 phone capabilities 会给出状态与原因;完整实测记录在 code/agent/out/phone-capabilities.json。
该文件仅作诊断,LLM 使用当前连接中不超过 60 秒的探测结果;连接更换后失效。
状态 unknown/超时不是不支持,也不应转成询问用户“能否发音”。
完整协议与决策规则见 自动音频能力验证。