From ec7705fd17275ee299d3591fd37a287e7856cede Mon Sep 17 00:00:00 2001 From: chengma Date: Fri, 7 Aug 2026 14:42:37 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=BD=92=E6=A1=A3=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?#25?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/task/25-usb-android-设备转-wifi-adb.md | 73 +++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 docs/task/25-usb-android-设备转-wifi-adb.md diff --git a/docs/task/25-usb-android-设备转-wifi-adb.md b/docs/task/25-usb-android-设备转-wifi-adb.md new file mode 100644 index 0000000..7fd2a3b --- /dev/null +++ b/docs/task/25-usb-android-设备转-wifi-adb.md @@ -0,0 +1,73 @@ +# 25 将勾选的 USB Android 设备转为 Wi-Fi ADB + +- 类型:需求 +- 父级大工单:#1 +- 所属 MVP / 版本:#2 / MVP +- 状态:已实现,待验收 +- 日期:2026-08-07 +- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/25 + +## 背景与目标 + +用户原来需要在终端手工读取手机 IP、开启 5555、拔掉 USB 并重新执行 `adb connect`。此次在设置页增加“转为 Wi-Fi”按钮,引导用户把勾选的 USB 设备转换为拔线后仍可使用的 Wi-Fi ADB 设备。 + +## 最终方案 + +- “转为 Wi-Fi”只在勾选状态正常的 USB 设备时可用。 +- 服务使用带设备号的 ADB 命令读取 `ip route`,优先从默认路由对应接口的 `src` 字段解析 IPv4,不写死 `wlan0`。 +- 对指定 USB 设备执行 `adb tcpip 5555`,尝试准备 Wi-Fi 通道,并在状态区提示用户拔掉 USB。 +- 后台每 0.5 秒检查一次 USB 通道,连续两次消失才继续,避免把 `adbd` 短暂重启误判为拔线;默认等待 60 秒。 +- 检测到拔线后再次执行 `adb connect IP:5555`,并确认该设备状态为 `device`。 +- 成功后刷新设备列表并勾选 Wi-Fi 设备;不会自动写入 SQLite,用户仍需点击“保存”。 +- ADB 命令、等待和轮询全部在 `QObject + moveToThread` Worker 中执行;页面关闭后停止后续步骤并忽略迟到结果。 +- 失败时保留原列表、原勾选和已保存配置,并在原状态区提供原因和重试建议。 +- 不修改数据库、Admin 接口、PDD 自动化和第三方依赖。 + +这是设置页的局部按钮和状态补全,按 `windows-ui-ux` 的长任务规则使用稳定状态区反馈,未制作 HTML 原型。 + +## 改了哪些 + +- `client/src/android_device_service.py`:IP 解析、开启 5555、拔线检测、Wi-Fi 重连和最终验证。 +- `client/src/settings_ui.py`:增加 Fluent“转为 Wi-Fi”按钮、工具提示和无障碍名称。 +- `client/src/settings_ui_event.py`:增加转换 Worker、进度反馈、按钮互斥和关闭保护。 +- `client/test/test_android_device_service.py`:覆盖路由解析、命令顺序、拔线超时、错误设备和状态验证。 +- `client/test/test_settings_ui_event.py`:覆盖按钮状态、成功刷新、不自动保存、失败保留、主线程响应和关闭安全。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 仅勾选正常 USB 设备时按钮可用 | 通过 | +| 从默认路由对应接口解析有效 Wi-Fi IPv4 | 通过 | +| ADB 命令明确使用 USB 序列号或 Wi-Fi 地址 | 通过 | +| 开启 5555、提示拔线并检测 USB 稳定消失 | 通过 | +| 拔线后重新连接并验证 Wi-Fi 状态 | 自动测试通过,待真机完整流程验收 | +| 成功后刷新并勾选 Wi-Fi 设备 | 通过 | +| 转换成功不自动保存当前设备 | 通过 | +| 失败保留列表、勾选和已保存配置 | 通过 | +| 防止重复提交,Qt 主线程保持响应 | 通过 | +| 页面关闭后忽略迟到结果 | 通过 | +| 不修改数据库、Admin、PDD 和依赖 | 通过 | +| 全量测试、语法检查和差异检查 | 通过 | + +## 测试 + +- 执行的命令: + +```powershell +# client 目录 +C:/Python310/python.exe -m py_compile src/android_device_service.py src/settings_ui.py src/settings_ui_event.py test/test_android_device_service.py test/test_settings_ui_event.py +$env:QT_QPA_PLATFORM="offscreen" +C:/Python310/python.exe -m unittest discover -s test -p "test_*.py" +C:/Python310/python.exe -c "from src.ui_main import MainWindow; from PyQt5.QtWidgets import QApplication; app=QApplication([]); w=MainWindow(); print('OK'); w.close(); app.quit()" +``` + +- 结果:Client 全量 85 项测试通过;语法检查、离屏窗口冒烟和 `git diff --check` 通过。 +- 真机只读核对:`192.168.0.173:5555` 在线,实际 `ip route` 输出包含 `wlan0 ... src 192.168.0.173`,解析规则匹配。 +- **没验证到的部分**:为避免改变用户当前已连接的 Wi-Fi ADB 会话,没有自动执行真机的“重新插 USB、点击转换、等待拔线、重连”完整流程;等待用户在可见窗口中验收。尚未验证打包后的 exe、Narrator、高对比度和 200% 缩放。 + +测试环境仍会输出现有 PyQt5 字体目录缺失和 SIP API 弃用警告,不影响测试结果。 + +## 相关提交 + +- `d478e69` `feat: 支持 USB 设备转 Wi-Fi ADB (#25)`