公开研究副本:本地绝对路径、实验主机地址已脱敏。NA 保留,完整可执行库存恢复为 0。角色与功能关联是可审核离线推断,未经人工金标或独立外部审查。历史代表截图不认证当次控件对齐。原件 SHA 只认证原件,公开字节 SHA 见发布清单。
APE 真实动作库存与选择机制审计
审计当前HEAD 9a5b577b77a6a87efcd8e6e218693af6faed17ce。以下路径均相对 native/src/com/android/commands/monkey/;含行号摘录与SHA用于复核,不凭旧论文或最终UTG推导运行机制。
实际调用链
MonkeySourceApe.generateEvents:425–474 获取 top Activity 与 Accessibility root(源码承认不是原子观察) → ApeAgent.updateState:278–292 → StatefulAgent.buildAndValidateNewState:537–543 → GUITreeBuilder/Naming/State → validateAllNewActions:833–837 → adjustActionsByGUITree:859–860 → SataAgent.selectNewActionInRound:399–473 → Graph.markVisited(输入前) → ApeAgent.checkInput:175–185 → MonkeySourceApe.generateEventsForAction:548–565 → 注入回执 → JevRuntime.inputSummary:764–793 → 下一GUI观察形成 NATIVE_TRANSITION。
- 保留树与理论GUI不同。
tree/GUITreeBuilder:480–516根据excludeInvisibleNode/excludeEmptyChild/alwaysIgnoreWebView剪枝;263–285,309–351应用XPathlets、父子click补丁、图像文本和WebView策略。Config:79–104给默认值,不代表每个归档覆盖配置均已记录。可见但未暴露交互属性、被剪除或未映射的控件不自动成为动作;图像生成文本会改变原生Naming。 - State模型动作。
model/State:50–65,210–216从 StateKey widgets 的NamerFactory.decodeActions建ModelAction[],并加无target Back。naming/ActionPatchNamer:51–77对 clickable/checkable 建Click、longClickable建LongClick、scrollType建各方向Scroll;构造动作类型本身不先过滤disabled。Naming.addNamedNode:212–242可过滤空/屏外节点。输入框没有独立的全字符串动作全集。 - 每动作的控件匹配成员。
tree/GUITree:198–209在当前Naming缓存currentNames/currentNodes中查Name,得到节点数组;State.resolveAction:346–358从数组随机选一个代表。ModelAction:35–43,208–228保存resolvedNodes、resolvedNode、resolvedTree、timestamp和单个GUITreeAction。所以不是“直到选中才第一次解析”:每个新模型动作会先解析,但也不是“所有Concrete已逐项验证”。 - 有效性、enabled、优先级。
StatefulAgent.validateNewAction:813–830可能复用同timestamp缓存,否则重解析随机代表;委托MonkeySourceApe.validateResolvedAction:338–375对该代表检查非空、与root相交(不是完整hit-test或业务成功);Back有效。AgentActionScorer:48–94依据代表节点设置enabled与priority,结合unvisited、别名数量及图上后继。Action:59–86存enabled/valid,二者不是每个兄弟节点的表。未验证成员应记UNKNOWN,而不是复制代表valid。 - 选择是一串策略,不是一个Concrete清单。
SataAgent:399–473按buffer、Activity返回、早期/局部greedy、远程greedy、trivial、backward、epsilon、fallback尝试。ActionFilter包含enabled-valid-unvisited/unsaturated集合。SataAgent.getGreedyActions:599–621在useActionDiffer时调用model/StateActionDiffer:43–110,比较相邻State的Name/Type和饱和;否则Graph.isActionUnvisitedByName:177–193查同Activity+抽象Name+Type历史。后者并非精确Concrete历史。档案未逐轮保存这些完整中间名单/未选原因,不能声称enabled-valid中的每个成员当轮都有被所有策略选择的机会。 - 输入参数后置。
ApeAgent.checkInput:175–185在模型动作选出后可能随机从StringCache选择输入文本;XPathlet也可预设(GUITreeBuilder:129–145)。MonkeySourceApe:480–522用代表bounds生成click/longclick/scroll/Back;MonkeySourceApeInput:80–130清文本、直接sendText、失败后key fallback。一次控件动作可包含多条低层事件/文本参数,不能按输入事件条数算Concrete执行,不能枚举无限文本组合为完整覆盖分母。
必须分开的五层集合
| 集合 | 运行时载体 | 有无完整性 | 归档可证范围 |
|---|---|---|---|
| GUI理论交互控件 | Accessibility tree,经Native预处理后保留GUITree | 仅保留树完整,不是全部App交互 | 2,280抽样树;不认证模型资格 |
| State识别的ModelAction | State.actions[] + Back |
当前State完整模型名单 | 23,971次有总数;2,131次可从unvisited IDs∪selected ID恢复全部ID,仍缺全属性 |
| 当前解析Concrete成员 | 各ModelAction.resolvedNodes,tree/timestamp必须一致 |
已解析成员数组,需标识缓存新鲜度 | 仅选中node及选中动作成员数量;全数组未记录 |
| 已验证有效Concrete | 每动作的resolvedNode与action.valid/enabled |
仅随机代表验证,无逐成员有效性全集 | 已确认选中输入事实,不是其他成员资格 |
| 策略实际可选动作 | 各策略局部列表、路径、当前代表绑定 | 顺序/随机/阶段相关,无统一物化全Concrete集合 | 仅选中策略/计数,没有每个未选动作的理由 |
因此,回答Q1是:有有限的模型动作与匹配控件缓存;没有一个可直接读出的“全部有效、策略可选、含全部输入实例”的完整Concrete库存。 对控件层可做更好的被动采集,但仍须分别解释模型成员、缓存代表与策略实际触达。
历史与身份
GraphElement:25–88的visitedAt计数;Graph.markVisited:508–527管理已访问ModelAction集合;StatefulAgent:562在输入前加计数。Model.appendToActionHistory:135–140是生成路径记录,不能仅凭它认证注入成功。ModelAction.resolveAt:220–227:单节点饱和由ModelAction是否visited决定;多节点为min(1, visitedCount/min(nodes.length,saturatedVisitedThreshold))。这不是逐Concrete覆盖,更不是各参数/结果分支覆盖。JevRuntime.inputSummary:764–793只有确认输入才进confirmedInputs;执行成功不证明业务成功。JevRegistry.confirmedHistory:311–341以当前映射的State/ModelAction组织历史,refinement会更改树/动作归属,须核对version与mapping完整性。- 精确Concrete是
ConcreteActionIdentity(actionType,JevIdentity.fullName(node));JevIdentity:63–70只归一化有来源标记的图像hash文本,保留真实文本、祖先、index及交互patch。动态值会拆分,兄弟行语义又未必入fullName。 JevRegistry.hasExactExecution:359–366是当前State/action与Concrete;hasRelatedConcreteExecution:369–386为同Activity+精确Concrete存在性,不能认证所有同业务入口或结果。旧的页面history池、related index与原生nameToActions是不同机制,不能混说为通用语义共享。
现有日志为何仍不够
JevRuntime.stateTelemetry:1022–1062 记录各类数量、unvisited IDs;recordSelectionDecision:848–872 记录选中类型/visit/饱和/fingerprint及resolvedNodeCount。JevEvidenceAudit:203–239 只对满足抽样条件的source/target保留树图;input_event_inventory 的“inventory”是单个选中输入的低层事件数组,不是当前页面动作库存。Pure未运行Region/审核候选机制,其context缺失不能靠决策组日志冒补。