Files
Artemis-Eapil/docs/plans/2026-11-02-native-actions-validation.md
T

68 lines
8.1 KiB
Markdown
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.
# 安卓原生动作验证记录
对应 [实现计划](2026-11-02-native-actions.md) 与 [能力说明](../android-native-actions.md)。主程序基于 2.5.0 的 main 开发,未改变主程序版本或第三方依赖;助手独立升级为 1.3.0 / protocol 3 / versionCode 15。
## 已验证的基础能力
| 层次 | 实际验证 | 结果与边界 |
| --- | --- | --- |
| 默认确定性测试 | `uv run --no-sync pytest -q` | 3824 passed、2 skipped、8 deselected;299.20s;使用最终 Python 实现,未依赖设备或私有服务 |
| 静态质量 | Ruff format/check、质量基线、核心 Pyright | 均通过;核心类型检查 0 错误、0 警告;未放宽质量基线 |
| Java 状态机 | 编译生产 TouchGestures/GestureController,模拟 Android 回调 | 694 项通过;覆盖取消注册竞态、迟到回调、所有权及提前完成的静止段;不代替真实触摸交付 |
| Java 窗口解析 | 编译生产 ControlWindowRoots/NativeControls,模拟窗口与节点 | 57 场景、361 项通过;涵盖真实选区工具栏形状、联合遮挡、区域空洞、旧 API、枚举失败、全局唯一与预算、取消及编辑后禁用 |
| 独立原生 Activity | 生产 helper → driver → actuator,5 轮完整回归 | 321 项通过;包含范围设值、唯一/缺失/歧义选择、UTF-16 编辑/光标/IME、等待、双指缩放/旋转、连续停留,以及两轮容器内往返滚动 |
| 真实设备取消 | 提前取消、重复取消、双指接触后取消 Python task、原始非法参数 | 30 项通过;仅一笔原手势及一笔取消;取得中断回执并释放,返回后 500ms 没有新增触点 |
| 普通 Pro 只读 | `9430c6fd-966d-4f00-94c8-79b91be320ee` | passed;模型与最终 Checker 均收到真实 range、文本与选区回执 |
| Flash 原生编辑 | `a3149abd-326b-40fd-99b9-816cf6a0299d` | passed;范围 42、emoji 选区替换、光标和一次 IME 提交由 APP 状态证明;保留一次错误包名查询的 NOT_FOUND |
| 普通 Pro 连续触摸 | `0955486c-38b0-4eb9-9e41-bafaa4caaefe` | passed;三次真实首 MOVE−DOWN 为 280/266/266ms,UP−DOWN 为 760/752/757ms,工具 elapsed 为 763/755/771ms;每次一次 DOWN/UP、无 CANCEL、同一 pointer |
真实设备报告保存在本次本地 `artifacts/native-actions-fixture/` 下,未将 APK 夹具、设备输出或模型请求正文提交源码。主程序分发所需的既有助手 APK 与 manifest 同步更新;其 SHA256 为 `544c38d5c135518fe6796aa4e03f804e87342687125a383ff3244952c8160d1f`。
## 失败样本与修正
- 旧助手中,中间静止路径的 Android callback 会提前完成:750ms 计划曾实际约 509ms,不能按回调成功视为时长正确。现在按 uptime 保持该段的最早结束时间,再续接下一段;真实 APP 事件及三次正式 Pro 任务均验证了修正。
- 原生滚动仅表示接受动画,200ms 后继续滚动曾产生错误的 NO_PROGRESS。现在等待容器和目标状态连续停稳;目标超出容器签名的有界采样时,也独立跟踪目标可见性及身份,避免短暂进入视口就成功。
- 一次编辑框位置异步变化使新读 token 与派发时 token 不符,返回 STALE_TARGET / not_started,未输入。夹具改为在后续编辑前显式等待该控件稳定,没有放宽 token 或隐式重发,随后 5 轮全部通过。
- 多窗口写入检查最初把任何高层窗口交叠都当作遮挡,真实选区工具栏及手柄只遮住编辑框边缘,也会错误阻止选区替换。保留 code14 失败证据;改为扣除高层覆盖后仍须存在可见区域,不按包名或工具栏类名豁免,多个窗口共同完全遮挡仍拒绝。
- 窗口退出期间曾短暂返回 READ_FAILED,等待工具原先也立即退出。现在仅对 READ_FAILED/UNAVAILABLE 在原始截止时间内继续只读轮询,并重置稳定计时;失败不证明消失,歧义、非法参数等仍立即拒绝。新增确定性回归后,原生执行器 72 项通过;夹具编辑前后显式等待稳定,最终助手的 5 轮 321 项全部通过。
- 取消脚本最初把 IME 内部 mIsInputViewShown 当作屏幕键盘可见,错误阻塞测试。现在使用系统唯一 mInputShown 状态并保留窗口覆盖检查;失败报告保留。
- 早期夹具运行还保留了坐标空间拼写、UTF-8 解码、已有焦点不再支持 focus,以及键盘遮挡导致 APP 未收到触摸的样本。参数拒绝、Android 输入完成和 APP 接收分别判定,没有将这些运行记为完整通过。
## Checker 证据规则
原历史任务 `4794dc4b-8164-4996-b489-2a2899bb4078` 保持原来的 inconclusive,未改写历史。使用完整 final prompt、真实 `run_final_check`、当前配置的 `gpt-6.1-terra / medium` 与完整报告解析器,独立验证:
- 真实暂停状态中,绑定当前选时的常驻 17:41:59 读数、重复停稳观测及粗指针一致:两次均 passed。
- 五个离线候选反例:事件卡片、水印、短暂浮层、读数/指针真实冲突、缺少稳定或暂停证据,均 inconclusive;理由明确引用各自缺口。
- 资格集 7 次均单请求、无传输重试,保存实际请求/服务端 ID、原始完整输出及解析结果,system prompt 字节完全一致。
两次正例复用同一历史暂停状态,五类反例为离线候选,不能冒充设备定位成功率。审计不完整的首组记录及候选作用域不充分的反例也保留,共 19 次实际模型运行;仅上述 7 次计入资格集。
## 目标 APP 实测
探索 `a51b55d8-46da-436e-a5f1-7288e3b9a6a0` 已通过。当前摄像头监控回看时间轴没有暴露原生 range/actions,不能用 set_progress 直接设置秒数;播放按钮和常驻选时则有独立节点。
- 小跨度 120→160px:工具完成,但实际刻度未见可辨变化,未计作 APP 缩放成功。
- 同一区域 100→400px:10 分钟刻度约 120–122→211px,实际约放大 1.73–1.76 倍;说明需要读取 APP 刻度,不能把手指跨度倍数直接当作比例尺。
- 日期面板选择 17:00 可到目标小时,但会自动播放;通过实际播放按钮转为三角形后确认暂停。
Flash 的三次独立缩放与精确定位验收全部 passed:
| 独立任务 | 目标 | 暂停后稳定读数 | 误差 |
| --- | --- | --- | --- |
| `af8c38b7-6a6b-435a-86da-6820c3843242` | 17:42:00 | 17:41:57 | −3s |
| `ca5a5cb9-351f-4639-940e-41880af95766` | 17:43:00 | 17:42:57 | −3s |
| `7d809bff-a529-4174-8cc7-d5494cb2a267` | 17:42:00 | 17:42:01 | +1s |
每次均有真实刻度变化、常驻选时与固定指针一致、三角形暂停状态及至少 1 秒后的独立稳定观测。三次都在 ±5s 内,不代表所有设备或后续任意输入的保证。
收尾的无输入复验又发现多窗口问题:APP 的空壳窗口被 Android 标为 active,而完整播放器在同包上层窗口;观察接口看得见的日期与播放按钮,在只搜索 active 的原生接口中返回 NOT_FOUND。已修复为有界前台窗口解析、跨根全局唯一以及每次写入前的精确区域遮挡检查;枚举不完整明确失败,旧系统保留已说明的矩形近似。修复前后的只读证据均保留,最终 code15 的夹具与取消回归已通过。
最终普通 Flash 任务 `54115cf7-4332-41fe-8c25-3daef8a82a18` passed:修正到暂停 17:42:00 后,在同一 action_sequence 原生 click→等待 1000ms→原生 click,两次均完成,selected 依次 false→true→false。常驻选时推进至 17:42:01,约 6.9 秒后独立截图仍为同一读数与三角形暂停状态。收尾再次从原生接口读取日期、播放节点与前台包名,确认保持此状态,仅卸载本次独立夹具,未清空或停止用户 APP。
## 验证环境与范围
本机 Python 3.14.0;Android 模拟器上实际执行。助手以 JDK 21.0.8、Android SDK/build-tools 36 构建,Java 8 目标。未把本次单一设备结果外推到所有 Android/OEM;多段/多指手势最低 API 26,工具仍按助手实际能力声明启用。
未进行主程序发版或最终 ZIP 的空 npm 缓存安装构建;本次没有前端输入或第三方锁文件改动。正式发版仍须单独通过仓库发布门槛。