终止未经许可的应用跳转
Jump Terminator 是一款面向普通 Android 用户的跨应用跳转控制工具。用户可以保护指定来源应用;当来源应用使另一个应用、浏览器、应用商店、安装器或快应用服务框架进入前台时,Jump Terminator 根据用户定义的确定性规则记录、允许或撤销这次跳转。
本项目不宣称普通无 Root 模式能够在 startActivity() 执行前拦截 Intent。基础模式的准确定位是:
在系统产生前台窗口变化后,以尽可能低的延迟发现不符合用户规则的跨应用切换,并安全撤销本次切换。
| 项目 | 内容 |
|---|---|
| 文档版本 | v1.1 |
| 文档日期 | 2026-08-09 |
| 项目状态 | Standard S0 No-Go;Advanced S0.2-S0.8 执行面、生命周期、最小授权、调试入口、韧性、设备状态与 PiP 窗口拓扑 PoC 门通过:仅授权继续架构与安全验证,不代表消费者版 Go |
| 首要适配平台 | Redmi/Xiaomi,MIUI 14 |
| 稳定版目标平台 | Android 9-Android 16 |
| 前瞻兼容轨道 | Android 17 Beta/正式版兼容测试 |
| SDK 基线 | minSdk 28、compileSdk 36、targetSdk 36 |
| 默认网络行为 | 不联网,不申请 INTERNET 权限 |
| 基础权限 | 无障碍服务、使用情况访问;前台服务通知,以及 OEM 后台运行引导 |
| 增强能力 | Shizuku,可选且不得影响基础模式 |
2026-08-01 启动 S0 技术可行性验证。仓库现已包含可编译的主诊断 App、测试来源 App、测试目标 App、无障碍与 UsageStats 双时间线、一次性 Back/Home 验证链、延迟真值、JSONL 导出、统计脚本和实体设备测试矩阵。Android 工程使用 Kotlin;当前诊断版本为 v0.0.12-s0。
2026-08-02 在首要适配设备 Redmi 23078RKD5C(Android 13、MIUI 14)完成正式武装自动 100 次。实时目标事件获取和候选识别均为 92/100,低于计划 v1.1 的 ≥95% 与 ≥93% 硬门槛;事件最终为 100/100,说明 8 次不是测试目标没有打开,而是观察进程解冻后才收到陈旧事件。能够及时识别的 92 次均只执行一次 Back,最终离开目标 92/92,没有 Home 或安全违规;候选、首次动作、离开目标 P95 分别为 118、243、307 ms。见正式武装 100 次报告。
同一武装模式下,设置 5 次、Chrome 5 次、桌面 5 次均未触发动作,误阻止 0/15、安全违规 0;样本量仍不足以单独证明 ≤2%,见武装负样本报告。单次安全返回链也已通过,见手动单次报告。
设备日志把漏处理与 MIUI Greeze 直接关联:观察 App UID 被列入冻结集合,随后出现 60 秒 S0_TRUTH 广播超时、解冻和 ANR。电池无限制、自启动、用户启动的前台服务及 device-idle 白名单仍会复现;实验性 Partial WakeLock 复测为 25/33,MIUI 最近任务锁复测为 26/42,两者都失败,且已回退/解除。详见 MIUI Greeze 调查记录。
因此,S0 对“普通消费者 App + 公开 API + MIUI 14 上可靠撤销跳转”的当前架构判定为 No-Go,原计划 S1 不自动启动。这不等于 Android 上所有实现路径都不可行;项目需要先改走 OEM/设备管理/特权伴侣架构,或把产品承诺降为尽力而为的记录与提醒,再开启新的可行性门。报告工具因完整跨设备样本矩阵未齐会显示 NOT_READY,该机器字段不覆盖本次基于硬门槛失败作出的人工 No-Go。运行与复核方法见 S0 运行手册,正式决策见 S0 Go/No-Go 记录。
2026-08-03 完成 S0.2 特权伴侣重开门验证。ADB/shell 上界实验先以 100 次固定测试跳转和 15 次允许流程通过门槛;随后使用 Kotlin + Shizuku UserService 在独立 shell UID 进程中重复同一边界,得到目标检测、单次 Back、离开目标、返回来源均 100/100,允许流程误动作 0/15,安全违规、超时和失败事件均为 0。Shizuku 路径的 P95 保守上界为检测/Back 125 ms、离开目标 214 ms,机器判定为 SHIZUKU_POC_FEASIBLE。见 S0.2 运行与证据、S0.2 门槛决策和聚合报告。
该结果只证明“固定测试来源 → 固定测试目标 → 至多一次 Back”的特权执行面在这台 MIUI 14 设备上可行。它不推翻 Standard S0 No-Go,也不授权消费者发布。
2026-08-03 随后完成 S0.3 生命周期、断连与重启故障注入。v2 首轮七类场景覆盖 7/7,但 force-stop 后 shell 伴侣仍发送 1 次 Back,因此先判定 STOP_UNTIL_FORCE_STOP_FAIL_SAFE。0.0.3-s03 将监控会话绑定到控制进程 Binder,在 owner 死亡及每次 Back 前复核对应用户下的包 stopped 状态:force-stop 新样本记录 owner_package_stopped、伴侣 PID 归零、后续 Back 为 0;普通崩溃只保留 10 秒宽限并在当前单次会话后退出。重新执行 UI 崩溃、force-stop、Shizuku 正常结束/强制断连、断连恢复、重启冷启动和解锁后恢复后,证据、安全、恢复与总门全部通过,机器决策为 LIFECYCLE_GATE_PASSED。
v3 又完成 owner-bound 正样本 100 次与允许流程 15 次回归:检测、Back、离开目标、返回来源均 100/100,允许流程误动作 0/15;检测、Back、离开目标 P95 分别为 116、139、211 ms,机器判定继续为 SHIZUKU_POC_FEASIBLE。见 S0.3 运行与证据、S0.3 当前决策、生命周期通过报告和v3 性能报告。该结果只解除当前 PoC 的 force-stop 硬阻塞,不授权真实第三方应用控制、L3-L5 持久动作或消费者发布。
2026-08-08 完成 S0.4 最小授权协议。0.0.4-s04 删除客户端声明的 owner UID,由 UserService 在 Binder 入口派生真实 UID、固定包映射和当前签名;每个会话绑定独立随机能力、不可变规则快照和单调租约,并把最终 stopped/前台复核、授权判定及 input 启动收进同一进程内串行化边界。实体身份探针确认 Binder UID 10418 与控制包 UID 一致,签名解析成功且事件未记录能力明文。
v4 正样本 100 次的检测、Back、离开目标和返回来源均为 100/100,允许流程误动作 0/15;检测、Back、离开目标 P95 为 116/158/233 ms。七类生命周期场景再次 7/7 通过,六个非重启会话的 S0.4 身份证据门全部通过;机器决策为 S04_AUTHORIZATION_GATE_PASSED 和 LIFECYCLE_GATE_PASSED。见 S0.4 运行与证据、S0.4 最终决策、授权报告和生命周期报告。当前工程的 Android 单元测试为 46 项,Python 报告测试为 24 项,完整 Gradle build/lint 通过。
2026-08-08 完成 S0.5 调试自动化入口收口。修复前,公开导出的 MainActivity 会解析 jt_s02_* extras;在控制包已获 Shizuku 权限时,外部调用者可借该入口驱动 UserService,形成受限但真实的 confused-deputy 路径。0.0.5-s05 让公开 Launcher 永远拒绝自动化 extras;自动化 Activity 只存在于 debug 构建,并由平台 android.permission.DUMP 保护,release 构建中完全不存在。ADB shell(UID 2000、持有 DUMP)仍可运行测试,普通测试应用 UID 10417 实测收到 SecurityException,且两条拒绝路径均没有产生特权 ready 事件。
S0.2 block1 观察回归与 S0.3 ui-force-stop 生命周期回归均通过;后者再次记录 owner_package_stopped 撤权且后续 Back 为 0。当前工程共有 Android 单元测试 48 项、Python 测试 28 项,完整 Gradle build/lint 通过。见 S0.5 运行与证据、S0.5 决策和结构化报告。
2026-08-08 完成 S0.6 韧性压力与权限撤销验证。首次冒烟发现 0.0.5-s05 只信任 Shizuku 的正向授权缓存:Android 运行时权限已经撤销时,新的调试会话仍可能产生 ready。0.0.6-s06 将连接门改为 Android 运行时权限与 Shizuku 授权视图同时为真;原失败样例不再复现,正常已授权路径保持可用。
正式矩阵中,普通 UI 崩溃生命周期 5/5、固定目标检测/Back/离开/返回 10/10、平台权限撤销 ready=0 与恢复后 ready=1 均为 3/3,安全违规、超时和失败事件为 0,机器决策为 S06_RESILIENCE_STRESS_PASSED。当前工程共有 Android 单元测试 52 项、Python 测试 35 项,完整 Gradle build/lint 通过。见 S0.6 运行与证据、S0.6 决策和聚合报告。
2026-08-09 完成 S0.7 设备状态与多窗口上下文失效验证。修复前 0.0.6-s06 只读取第一条 topResumedActivity,在来源与目标同时 resumed 的真实分屏中误产生 1 次检测和 1 次 Back。0.0.7-s07 改为解析完整前台集合:多前台、息屏或锁屏立即使来源上下文失效,最终动作同时复核交互状态、锁屏状态和前台歧义;仅 MIUI 普通切换中的瞬时前台空洞采用 500 ms 持续门。
正式矩阵中,最近任务 5/5、分屏 5/5、息屏/安全锁屏恢复 1/1 均为目标检测 0、Back 0;全屏正向对照的检测、Back、离开目标和返回来源均为 10/10。11 个零动作会话 ID 唯一,证据警告、安全违规、超时和失败事件均为 0,机器决策为 S07_DEVICE_STATE_GATE_PASSED。当前工程共有 Android 单元测试 63 项、Python 测试 41 项,完整 Gradle build/lint 通过。见 S0.7 运行与证据、S0.7 决策和聚合报告。
2026-08-09 完成 S0.8 画中画窗口拓扑失效安全验证。修复前 0.0.7-s07 仍只保留 top-resumed 组件集合:目标已稳定进入 PiP 后再建立来源上下文并展开目标,会误产生 1 次检测和 1 次 Back。0.0.8-s08 同时解析 active pinned/PiP 状态;任意 PiP 都进入显式 picture_in_picture fail-closed 状态,已有来源立即失效,最终动作授权也会再次复核该状态。
正式矩阵中,目标预先 PiP 后展开 5/5、来源 PiP 露出目标 5/5 均由系统 mode=pinned 快照确认,目标检测和 Back 均为 0;全屏正向对照的检测、Back、离开目标和返回来源均为 10/10。10 个 PiP 会话 ID 唯一,readiness gap、证据警告和安全违规均为 0,机器决策为 S08_PIP_CONTEXT_GATE_PASSED。当前工程共有 Android 单元测试 67 项、Python 测试 60 项,完整 Gradle build/lint 通过。见 S0.8 运行与证据、S0.8 决策和聚合报告。
Android 无障碍服务可以接收窗口状态、窗口集合和界面交互事件,并执行返回、主页等系统级全局动作。基础引擎可以:
- 识别当前活动窗口所属应用;
- 发现前台包或活动窗口集合发生变化;
- 将新的前台状态与最近的受保护来源上下文进行时序关联;
- 按来源、目标、用户身份和当前模式匹配规则;
- 执行一次返回;
- 返回未生效时执行一次主页动作;
- 使用 TYPE_ACCESSIBILITY_OVERLAY 显示结果,无需把普通悬浮窗权限作为基础权限;
- 记录证据、决策、耗时、动作结果和最终前台状态。
基础模式默认不读取完整窗口节点树,不保存窗口文本,也不执行 Shell 命令。
公开 API 不提供“调用者包名、目标包名、原始 Intent”组成的完整调用链。来源与目标的关系来自无障碍事件、UsageStats、用户交互、活动窗口和时间顺序的综合归因。
因此:
- 日志中的“来源应用”必须标注归因等级;
- 产品文案不得把时序归因描述为系统提供的权威调用关系;
- 无法确定时不得执行 L3-L5 动作;
- 首次询问时不能重放原始 Intent;
- “允许一次”只能允许用户随后重新触发的一次匹配跳转。
MVP 不使用不透明的恶意评分模型。严格模式采用用户可理解的静态规则:
当用户选定的受保护应用处于有效来源上下文中时,除安全豁免和用户允许项外,新的第三方目标默认阻止。
- Android 9(API 28)使用 UsageEvents.Event.MOVE_TO_FOREGROUND 和 MOVE_TO_BACKGROUND;
- Android 10 及以上使用 ACTIVITY_RESUMED 和 ACTIVITY_PAUSED;
- 两组常量必须归一化为项目内部事件,不允许业务逻辑直接依赖版本常量;
- UsageEvents 时间戳来自墙上时钟,AccessibilityEvent 主要使用开机后时间;归一化层必须同时保存两种时钟并检测系统时间跳变;
- Android 17 在本计划编写时已进入平台稳定后的最后测试阶段,必须进入兼容轨道,但 v1.1 暂不要求 targetSdk 37;
- 若 Android 17 正式版早于 RC 发布,则 Android 17 自动升级为一级兼容测试平台。
Google Play 从 2026 年 8 月 31 日起要求新应用和更新面向 Android 16(API 36)或更高,因此首版使用 targetSdk 36。
正式的设备策略挂起能力面向 Device Owner、Profile Owner 或被委托的管理应用。普通第三方应用不能把该能力作为基础功能。
Device Owner 模式保留给后续企业版或专用设备版,不属于大众版 v1。
Shizuku 在 Android 11 及以上可通过无线调试启动,无需 Root 或长期连接电脑,但重启后通常需要重新启动服务。不同 Android 和 OEM 对 shell 身份的能力限制不同。
S0.2 已在 Redmi 23078RKD5C(Android 13、MIUI 14)验证 Kotlin UserService 能以 shell UID 独立监测固定测试 Activity 并发送一次 Back;此证据只覆盖非持久、测试包限定的 L1 动作,不覆盖 L3-L5。
S0.3 先证明 force-stop 不会自动终止旧 UserService 授权,随后由 owner Binder、per-user stopped 复核、10 秒崩溃宽限和确定性退出修复;v3 七类生命周期场景全部通过。该结论仍限于固定测试包和一台 MIUI 14 设备。
S0.4 进一步把 owner 身份改为 Binder 服务端派生,加入一次性能力、进程内重放拒绝、规则快照、单调租约和最终动作串行化;同一设备上的安全、性能与生命周期回归通过。重放状态仍不跨 UserService 重启,系统外部竞态、多用户与真实应用仍未覆盖。
S0.5 将测试命令入口从公开 Launcher 移到仅 debug 构建存在、受 android.permission.DUMP 保护的独立 Activity;公开 Launcher 同时保留默认拒绝作为纵深防御,release 构建不包含自动化组件。该边界只保护本地开发自动化,不构成消费者授权界面。
S0.6 以 5 次普通 UI 崩溃、10 次重复目标和 3 次平台权限撤销/恢复验证有界会话的收尾、重复执行与 fail-closed。客户端现在同时核对 Android 运行时权限和 Shizuku 授权视图,避免正向授权缓存掩盖直接撤权;该修复不改变 UserService v5 的固定规则或合法已授权行为。
S0.7 将动作授权扩展到完整 top-resumed 集合、设备交互状态和安全锁屏状态。最近任务、分屏歧义、息屏或锁屏都会撤销来源上下文;前台集合、设备状态或锁屏状态未知时最终动作拒绝。v7 在同一设备上的 5/5 最近任务、5/5 分屏和 1/1 锁屏恢复零动作门通过,同时保留 10/10 全屏固定目标行为。
S0.8 进一步保留 active pinned/PiP 拓扑,不再把“唯一 top-resumed”误当作“唯一可交互窗口”。任何 PiP 都使来源上下文失效并在最终动作门拒绝;v8 的两个 PiP 场景各 5/5 保持零检测、零 Back,同时保留全屏固定目标 10/10。正式证据只有真实内置 displayId=0,所以多显示器仍未通过硬门。
增强模式必须遵守:
- 连接与授权是可选项;
- 未连接或重启失效时基础模式继续运行;
- 不根据品牌或版本假定命令可用;
- 能力探测只能使用专用测试包,不得在用户应用或系统组件上试探;
- 每次真实操作仍需验证目标用户、目标包、操作权限和当前状态;
- disable、suspend 等持久状态修改必须先写恢复账本;
- 无独立恢复路径时,不得发布 L5 能力。
小米快应用和小游戏运行在快应用服务框架中,因此:
- 基础模式主要识别“来源应用 -> 快应用服务框架”;
- 结束宿主会影响当前快应用环境;
- 禁用宿主会影响全部快应用、小游戏及依赖入口;
- 不保证识别宿主内部具体运行的快应用;
- 只有包名、签名、组件等组合特征通过验证后,才显示为“已验证的小米快应用服务框架”;
- 无法识别内部应用时必须显示“未识别”。
项目是否进入完整开发,由 S0 的真实设备结果决定。S0 必须同时证明候选识别、允许流程、动作撤销、低误判和可解释日志,而不是只证明“能够收到一个事件”。
G1:阻止来源明确的跨应用跳转
用户为应用 A 开启保护后,不符合用户规则的 A -> B 前台切换应被及时撤销。
G2:专项阻止快应用拉起
识别小米快应用服务框架,并支持按不同来源应用建立规则。
G3:面向普通用户
基础模式不要求 Root、电脑、ADB 命令或 Shizuku。
G4:行为可解释
每次决策至少说明来源、目标、用户身份、时间、证据、归因等级、命中规则、动作、结果和耗时。
G5:不破坏正常系统功能
不得因一次跳转默认永久禁用浏览器、应用商店、支付应用、安装器或系统组件。
G6:本地优先和隐私最小化
默认不联网、不上传应用列表、不保存屏幕文本、不收集广告标识符。
G7:任何外部状态修改都可审计和恢复
无法证明恢复路径有效时,产品只能记录、返回、主页或执行非持久的 force-stop,不得开放持久禁用或挂起。
v1 不承诺:
- 在 startActivity() 之前拦截所有 Intent;
- 获得来源应用发出的原始 Intent;
- 自动恢复并继续已被撤销的原始跳转;
- 100% 识别快应用内部具体名称;
- 无 Shizuku、Device Owner 或 Root 时真正冻结任意应用;
- 绕过 Android 或 OEM 安全限制;
- 自动点击权限、支付或安装确认按钮;
- 监控网络流量或识别全部广告 SDK;
- 完整支持跨用户、工作资料和所有双开场景;
- 自动卸载被判定为流氓的软件;
- 在用户从系统设置直接清除数据或直接卸载后,由已不存在的应用自动完成恢复。
- 经常被新闻、工具或清理类应用拉起快应用的用户;
- 经常被广告跳转到应用商店或浏览器的用户;
- 为老人配置手机的家庭成员;
- 希望精细控制应用间切换的高级 Android 用户;
- 使用 MIUI 14,但现有跳转防护无效的用户。
场景 A:阻止快应用
新闻应用拉起快应用服务框架;规则命中后执行返回,失败时回到桌面,并记录结果。
场景 B:允许必要支付
购物应用拉起支付宝;来源-目标规则为“始终允许”,不执行动作。
场景 C:首次询问
应用 A 首次进入浏览器:
- 先撤销本次跳转;
- 显示“允许下一次”“始终允许”“保持阻止”;
- 用户选择“允许下一次”后,创建一个短时 AllowOnceToken;
- 明确提示用户返回来源应用并重新触发;
- 下一次完全匹配的稳定候选原子消费该令牌。
产品不得暗示可以恢复原始 Intent。
场景 D:来源反复拉起
相同来源和目标在 10 秒内连续出现三次。前两次阻止,第三次提示结束来源;只有用户提前开启相应选项、归因达到要求且身份明确时,才允许自动结束来源。
场景 E:用户主动打开目标
用户经过桌面或最近任务列表后主动打开浏览器,旧来源上下文已经失效,不得归因给先前的受保护应用。
场景 F:双开或工作资料
如果无法同时确认包名和用户身份,只记录事件并显示“用户身份不明确”,禁止 L3-L5。
默认动作是一次返回,不是冻结、挂起或禁用。
规则主键至少包括:
用户身份 + 来源包 + 目标包或类别 + 模式 -> 动作
不得只维护全局目标黑名单。
| 等级 | 动作 | 默认 | 最低要求 |
|---|---|---|---|
| L0 | 只记录 | 开启 | 任意归因等级 |
| L1 | 执行一次返回 | 开启 | 至少 MEDIUM;LOW 只记录或提示 |
| L2 | 返回失败后回到桌面 | 开启 | MEDIUM,动作前重新确认目标 |
| L3 | Shizuku 结束目标 | 关闭 | 用户开启、身份明确、能力有效;MEDIUM 需额外开关 |
| L4 | Shizuku 结束来源 | 关闭 | HIGH、重复触发、单独授权 |
| L5 | 禁用或挂起 | 关闭 | HIGH、逐包确认、恢复账本和独立恢复路径均有效 |
动态解析以下角色和组件:
- System UI;
- 当前桌面;
- 当前电话和紧急呼叫组件;
- 权限控制器;
- 当前输入法;
- 系统设置;
- 文件选择器;
- 包安装器;
- Jump Terminator 自身;
- Shizuku;
- 当前已启用的无障碍服务;
- 当前设备管理和工作资料管理组件。
安全策略:
- Jump Terminator 自身、System UI、桌面、电话/紧急呼叫、权限控制器、当前输入法和管理组件拒绝 L3-L5;
- Shizuku 和当前无障碍服务拒绝自动 L1-L5;
- 设置、文件选择器、安装器和支付类默认允许;只有来源-目标显式规则才能执行 L1-L2;
- 关键组件不得被导入规则、类别规则或最近修改优先级绕过;
- OEM 角色无法确认时失败开放;
- “阻止安装器”预设只创建待确认的 L1-L2 显式规则,不表示允许结束或禁用安装器。
- HIGH:可执行用户已授权的 L0-L5,但仍需通过安全矩阵;
- MEDIUM:可执行 L0-L2;L3 仅在用户单独开启后允许;
- LOW:只记录或提示,不自动执行返回、主页或 Shell 动作;
- 用户身份未知、数据库异常、规则解析失败或前台状态变化时,降级为 L0。
所有自动化必须是范围狭窄、用户可理解、由静态人类规则定义的“触发 X -> 动作 Y”。不得引入自主规划或自主决策代理。无障碍用途必须在商店材料和应用内显著披露,并取得明确同意。
- 展示当前可识别应用;
- 搜索并按系统/用户应用筛选;
- 按用户资料区分同包应用;
- 为单个来源开启或关闭保护;
- 批量启用推荐类别;
- 在包可见时展示包名、签名摘要和用户资料;
- 包不可见时只展示已观测包名,不伪造标签或签名。
每个来源应用可选择四种模式:
- 严格模式:未明确允许的第三方目标默认阻止;
- 询问模式:首次目标先撤销,再询问用户;
- 记录模式:只记录,不采取动作;
- 暂停保护:临时停止该来源规则。
规则动作包括:
- 允许;
- 允许下一次;
- 阻止;
- 阻止并回到桌面;
- 阻止并结束目标;
- 阻止并结束来源;
- 每次询问。
- 阻止快应用;
- 阻止应用商店;
- 阻止安装器,默认仅生成待确认规则;
- 阻止浏览器;
- 阻止所有第三方目标;
- 允许支付应用;
- 允许文件选择器;
- 允许系统分享面板。
预设只用于初始化。安全绝对拒绝项不可被预设覆盖。
每条记录至少包含:
- 事件 ID、用户序列号和运行时用户 ID;
- 来源/目标包名和可用时的应用名;
- 来源/目标 Activity;
- 墙上时钟、单调时钟和启动会话 ID;
- 证据列表和归因等级;
- 命中规则、被覆盖规则和决策解释;
- 执行动作、返回值、验证结果和耗时;
- 最终活动窗口集合;
- 数据是否已脱敏。
- 自动扫描已知小米快应用宿主;
- 按包名、签名、系统状态、组件和 Activity 模式组合验证;
- 支持按来源单独阻止;
- 支持全局阻止宿主进入前台;
- 高级模式可结束当前宿主运行;
- 禁用整个宿主必须逐包二次确认并先生成恢复记录;
- 宿主更新后适配状态立即失效并重新验证。
- 应用内总开关;
- 通知栏暂停入口;
- 快捷设置磁贴;
- 暂停 5 分钟;
- 暂停至手动恢复;
- 服务失效时明确显示“不再受保护”。
检测:
- 无障碍服务和事件接收状态;
- 使用情况访问状态;
- 通知和电池限制状态;
- MIUI 后台限制风险;
- Shizuku 连接、身份和最近能力探测;
- 当前设备适配等级;
- 最近事件、决策和动作时间;
- 恢复账本是否完整;
- 是否存在尚未恢复的外部状态修改。
专用 Probe APK 不保存用户数据,仅用于测试:
- Binder 是否连接;
- Shizuku API 与服务版本;
- 当前 shell 身份;
- 当前用户 ID 和用户序列号映射;
- 对 Probe APK 执行 force-stop 并验证;
- 对 Probe APK 执行 suspend,验证后立即 unsuspend;
- 对 Probe APK 执行 disable-user,验证后立即 enable;
- 模拟超时、断连和回滚;
- 删除 Probe APK 前确认已恢复。
探测结果按设备指纹、Android 版本、用户、操作和目标类别记录。真实包操作前必须再次验证,不得把一次探测结果视为全局永久能力。
- 结束本次目标;
- 来源短时间重复拉起时结束来源;
- 命令只从内部枚举构造;
- 包名、用户和当前前台状态必须重新验证;
- 返回码成功后仍需验证目标状态;
- 失败时降级为返回或主页,不允许循环重试。
首版“隔离”定义为:
在用户指定的时间窗口内,发现同一用户下的目标再次进入前台后立即按已授权动作处理。
不得把隔离描述为 Android 原生挂起。
仅在以下条件全部满足时展示 L5:
- 能力探测成功;
- 目标不在绝对保护集合;
- 用户身份明确;
- 已写入写前恢复账本;
- 已生成可供用户保存的外部恢复清单;
- 用户阅读影响说明并逐包确认;
- 操作后状态验证成功;
- 对应恢复操作已经通过当前设备测试。
恢复中心提供:
- 查看全部待恢复操作;
- 恢复单个或全部包;
- 导出签名恢复清单和只读 ADB/Shizuku 恢复说明;
- “恢复全部并卸载”引导;
- 数据库损坏时只读扫描和外部清单导入;
- 明确说明:直接清除数据或从系统设置直接卸载,无法保证应用自行恢复。
如果独立恢复路径未通过 S7 验收,v1 必须移除 suspend 和 disable,仅保留 force-stop。
flowchart TD
UI["UI:应用、规则、历史、健康检查、恢复中心"]
POLICY["Policy Engine:规则、豁免、动作上限、解释"]
CORR["Transition Correlator:窗口集合、来源上下文、时序归因"]
ID["Identity Resolver:用户 ID、用户序列号、包与系统角色"]
A11Y["Accessibility Signal"]
USAGE["UsageStats Signal"]
PKG["Package / Role Signal"]
ROUTER["Action Router:动作前确认、超时、防循环"]
BASIC["Basic Actions:Back / Home / Overlay"]
SHIZUKU["Shizuku Actions:Force-stop / Suspend / Disable"]
JOURNAL["Write-ahead Recovery Journal"]
UI --> POLICY
POLICY --> CORR
CORR --> ID
A11Y --> CORR
USAGE --> CORR
PKG --> ID
POLICY --> ROUTER
ROUTER --> BASIC
ROUTER --> JOURNAL
JOURNAL --> SHIZUKU
- :app
- :core:model
- :core:identity
- :core:policy
- :core:timeline
- :core:rules
- :core:database
- :core:recovery
- :core:diagnostics
- :engine:accessibility
- :engine:usage
- :engine:action-basic
- :engine:action-shizuku
- :adapter:oem-common
- :adapter:xiaomi-quickapp
- :feature:onboarding
- :feature:app-selector
- :feature:rules
- :feature:history
- :feature:health
- :feature:recovery
- :feature:settings
- :probe
- :test:fixtures
- :test:benchmark
- Kotlin;
- Jetpack Compose;
- Coroutines 与 Flow;
- Room;
- DataStore;
- Hilt;
- AndroidX Benchmark;
- JUnit、Robolectric、Instrumentation Test;
- Gradle Version Catalog;
- Android Lint、Detekt、Ktlint;
- Macrobenchmark 和 Baseline Profile;
- 可重放的纯 Kotlin 状态机测试夹具。
AccessibilitySignal
- TYPE_WINDOW_STATE_CHANGED;
- TYPE_WINDOWS_CHANGED;
- TYPE_VIEW_CLICKED;
- 必要时监听触摸交互开始和结束;
- 服务连接、中断和配置变化;
- 活动窗口集合、焦点窗口、包名、类名和 windowId。
默认不遍历完整节点树。
UsageSignal
- API 28:MOVE_TO_FOREGROUND、MOVE_TO_BACKGROUND;
- API 29+:ACTIVITY_RESUMED、ACTIVITY_PAUSED;
- 包名、Activity、墙上时钟;
- 锁屏、解锁和用户交互相关事件在版本可用时作为辅助证据。
PackageAndRoleSignal
- 应用安装、卸载、替换和启用状态变化;
- 当前桌面、电话、输入法、权限控制器、安装器和文件选择器;
- 用户资料增加、删除、锁定和解锁;
- 包签名、版本或系统角色变化后的重新扫描。
内部 ForegroundSignal 至少包含:
- elapsedRealtimeMs;
- wallClockMs;
- bootSessionId;
- userSerial;
- runtimeUserId;
- packageName;
- className;
- source;
- eventType;
- windowId;
- displayId;
- isFocused;
- confidence。
所有排序、超时和窗口计算优先使用单调时钟。UsageStats 的墙上时钟事件通过同一时刻采集的 ClockSnapshot 映射到当前启动会话;检测到时钟大幅跳变时,现有来源上下文立即失效。
来源上下文包含:
- 最近稳定活动窗口及其用户;
- 来源是否受保护;
- 进入前台和最近交互时间;
- 最近窗口证据;
- 是否经过桌面、最近任务、锁屏或用户切换;
- 当前显示器和多窗口状态;
- 上下文过期时间。
初始参数:
- 稳定窗口:100-200 ms;
- 来源最大有效期:2 秒;
- 经桌面、最近任务、锁屏/解锁或用户切换后立即失效;
- 分屏、画中画或多显示器无法确定焦点时降为 LOW;
- 参数来自随应用发布的版本化兼容配置,不接入在线配置服务。
兼容配置只能调整时间阈值和 OEM 特征,不能定义 Shell 命令、放宽绝对保护项或提升动作等级。后续如支持导入,必须校验 schema、签名、适用版本和回滚版本。
只有同时满足以下条件才生成 TransitionCandidate:
- 存在受保护来源 S;
- S 的用户身份明确;
- 新稳定目标 T 与 S 不同;
- 未经过桌面或最近任务;
- 来源上下文未过期;
- T 不是 Jump Terminator 自身提示;
- 当前不处于动作验证或恢复阶段;
- 多窗口状态能够确定活动目标,否则只生成 LOW 记录。
候选包含 sourceUser、source、targetUser、target、开始时间、证据、置信等级和候选 ID。
| 等级 | 典型证据 | 自动动作上限 |
|---|---|---|
| HIGH | 无障碍与 UsageStats 一致;用户和时间匹配;无中间应用 | 用户已授权动作,仍受安全矩阵限制 |
| MEDIUM | 无障碍时间线完整;来源上下文有效;UsageStats 延迟或缺失 | L2;L3 需额外开关 |
| LOW | 信号丢失、多窗口歧义、身份未知或时钟跳变 | L0 |
- 总保护是否暂停;
- 信号、用户身份和数据库是否健康;
- 来源是否受保护;
- 是否为同包、同用户 Activity 变化;
- 是否处于桌面、最近任务、锁屏或多窗口歧义;
- 根据目标动态角色计算动作安全上限;
- 是否命中有效的 AllowOnceToken;
- 是否命中来源-目标显式规则;
- 是否命中来源规则、快应用规则或目标类别规则;
- 是否命中来源默认模式;
- 根据归因等级进一步降低动作上限;
- 输出最终决策、解释和被覆盖规则。
从高到低:
- 不可绕过的安全动作上限;
- 有效的 AllowOnceToken;
- 来源-目标显式规则;
- 来源应用规则;
- 已验证快应用宿主规则;
- 目标类别规则;
- 全局默认规则。
同一层级:
- 用户显式规则优先于预设;
- 更具体规则优先;
- 同样具体时最近修改者优先;
- 每次覆盖必须写入决策解释。
AllowOnceToken 包含:
- tokenId;
- userSerial;
- sourcePackage;
- targetPackage;
- createdAtElapsed;
- expiresAtElapsed;
- remainingUses,固定为 1;
- consumedByCandidateId。
默认有效期 30 秒,可在 10-120 秒范围配置。只有完全匹配且达到稳定状态的候选才能在数据库事务中原子消费;过期、经过桌面、用户切换、来源改变或目标改变时立即失效。应用崩溃后不得重复消费。
- 目标进入稳定前台;
- 策略输出 BLOCK;
- 动作前重新确认用户、目标和活动窗口;
- 执行一次 GLOBAL_ACTION_BACK;
- 在验证窗口内检查是否回到来源或离开目标;
- 仍在目标时执行一次 GLOBAL_ACTION_HOME;
- 验证最终前台并结束本次动作。
禁止无条件连续返回。performGlobalAction 返回 true 只表示请求已接受,不能视为处理成功。
- 策略输出 L3-L5;
- 重新检查授权、身份、能力快照有效期和安全矩阵;
- 对持久动作写入 PREPARED 恢复账本并落盘;
- 按白名单 API/参数执行;
- 记录返回码和耗时;
- 查询真实状态并验证;
- 更新为 APPLIED、FAILED 或 ROLLED_BACK;
- 验证失败时尝试一次回滚,然后降级基础动作;
- 不允许后台无限重试。
重复拉起定义:
- 相同用户、来源和目标;
- 10 秒内至少三次;
- 每次已验证离开目标;
- 中间没有用户重新主动打开来源。
默认:
- 第一次阻止;
- 第二次阻止并提示;
- 第三次建议结束来源;
- 只有 HIGH 且用户已开启“自动结束重复来源”时执行 L4。
每个候选最多产生一条动作链;服务重连、进程恢复或数据库重放不得重新执行过期动作。
- SUCCESS_RETURNED_TO_SOURCE;
- SUCCESS_RETURNED_HOME;
- SUCCESS_FORCE_STOPPED;
- SUCCESS_STATE_CHANGED;
- FAILED_TARGET_CHANGED;
- FAILED_USER_CHANGED;
- FAILED_ACTION_REJECTED;
- FAILED_SERVICE_DISCONNECTED;
- FAILED_TIMEOUT;
- FAILED_UNSUPPORTED;
- FAILED_SAFETY_POLICY;
- FAILED_VERIFICATION;
- FAILED_RECOVERY_JOURNAL;
- ROLLED_BACK。
StateMutationJournal 至少保存:
- operationId;
- userSerial 和运行时 userId;
- packageName;
- operation;
- previousState;
- requestedState;
- lifecycleState;
- command/backend version;
- preparedAt、appliedAt、verifiedAt、restoredAt;
- 返回码和验证证据;
- 恢复命令的结构化参数;
- 关联的外部恢复清单版本。
写账本必须发生在修改命令之前。导出的恢复清单是纯数据,不接受任意命令文本,并包含完整性校验。数据被清除后,应用只能依赖用户保存的外部清单或人工恢复说明;不得承诺自动恢复。
组合特征:
- 包名;
- 签名摘要;
- 系统应用状态;
- Activity 类名模式;
- 应用标签;
- 已知服务或组件;
- 设备扫描样本。
不得只依赖单个硬编码包名。
| 状态 | 含义 | 可用能力 |
|---|---|---|
| VERIFIED | 包名、签名和关键组件匹配 | 可启用快应用预设 |
| PARTIAL | 包名匹配,签名或组件版本未知 | 用户确认后仅允许 L1-L2 |
| UNKNOWN | 疑似宿主但无法确认 | 只记录 |
| NOT_FOUND | 未发现宿主 | 不展示专项开关 |
内部名称识别是实验功能,只可使用窗口标题、Activity 类名和框架公开显示名称。默认不读取或保存完整界面文本。
无法识别时显示:
目标:小米快应用服务框架 内部应用:未识别
仅 Advanced 构建、VERIFIED 状态、L5 总开关、写前账本、外部恢复清单和二次确认全部满足时允许。警告必须说明:
禁用后,设备上的所有小米快应用、小游戏及依赖该框架的入口可能无法使用。
基础模式:
- 无障碍服务;
- 使用情况访问。
可选:
- Android 13+ 通知权限,用于暂停入口和状态通知;
- 忽略电池优化的设置引导;
- Shizuku 授权。
不要求 Root、短信、联系人、位置、通话记录、存储、VPN 或设备管理员。
Android 11+ 会过滤已安装应用。策略是:
- 优先使用有限 queries 和系统自动可见包;
- 从无障碍和 UsageStats 逐步发现包名,但不假定因此能读取标签或签名;
- 小米宿主和关键系统角色使用精确查询;
- Play 构建只有在核心功能确实无法满足且通过政策评审时才申请 QUERY_ALL_PACKAGES;
- Advanced 构建可包含更完整的应用列表;
- UI 必须说明当前列表可能不完整。
欢迎页 -> 能力与限制 -> 隐私说明 -> 无障碍显著披露与授权 -> 使用情况访问 -> 选择来源应用 -> 可选快应用预设 -> 运行测试跳转 -> 主页。
所有步骤均允许返回;跳过核心权限后不得显示“正在保护”。基础流程不得强迫安装 Shizuku。
ProtectedApp
- userSerial;
- packageName;
- displayName;
- enabled;
- mode;
- createdAt;
- updatedAt。
TargetRule
- id;
- userSerial;
- sourcePackage;
- targetPackage 或 targetCategory,二者必须满足 one-of 约束;
- action;
- specificity,由系统计算;
- enabled;
- createdBy;
- expiresAt;
- updatedAt。
AllowOnceToken
- tokenId;
- userSerial;
- sourcePackage;
- targetPackage;
- expiresAtElapsed;
- consumedByCandidateId;
- createdAt。
TransitionRecord
- id;
- bootSessionId;
- wallClockTimestamp;
- elapsedRealtimeMs;
- userSerial;
- runtimeUserId;
- sourcePackage、targetPackage;
- sourceClass、targetClass;
- confidence 和 evidence;
- matchedRuleId;
- decision;
- action;
- actionResult;
- decisionLatencyMs;
- actionLatencyMs;
- finalForegroundPackages。
CapabilityRecord
- deviceFingerprint;
- androidVersion;
- manufacturer、model、ROM;
- userSerial;
- backendVersion;
- operation;
- targetClass 或 probePackage;
- supported;
- verificationResult;
- testedAt;
- expiresAt。
StateMutationJournal
采用 9.5 的写前恢复模型。
- 最多 1,000 条普通跳转记录或最近 7 天,两者先到;
- 恢复账本在对应状态恢复并经过保留期前不得自动删除;
- 用户可以清空普通历史;
- 存在未恢复状态时,“清空全部数据”必须先要求恢复或导出清单;
- 导出默认隐藏窗口文本、设备指纹和应用显示名;
- 用户主动确认后才能导出完整诊断。
- 不建立账户;
- 不上传规则或应用列表;
- 不接入广告或行为分析 SDK;
- 不使用云端恶意评分;
- Standard 构建不请求 INTERNET;
- 崩溃默认生成本地报告,由用户主动导出。
- 不提供任意命令输入框;
- 后端只暴露类型化操作枚举;
- 包名必须通过 PackageManager 和严格语法校验;
- userId 必须从已验证 userSerial 解析;
- 不把用户输入通过字符串拼接传入 Shell;
- 设置超时、取消、返回码和状态验证;
- 禁止导出动作服务;
- Binder 请求验证调用来源;
- 导入规则和恢复清单不能定义命令;
- Release 构建关闭调试后门;
- 关键包在策略层和后端层各拦截一次。
- 数据库异常:L0;
- 恢复账本写入失败:拒绝 L5;
- 用户身份未知:L0;
- Shizuku 断开:降级基础动作;
- 规则文件不合法:记录模式;
- OEM 角色未知:禁止 L3-L5;
- 应用启动时发现 PREPARED 或 APPLIED 未完成记录:先进入恢复中心,不自动重复命令。
以下是立项估算,不代表已经落实的人事承诺:
| 角色 | 基线投入 | 主要职责 |
|---|---|---|
| Android 平台/技术负责人 | 1 FTE | 无障碍、时间线、Shizuku、架构 |
| Android 产品工程师 | 1 FTE | Compose、规则、数据、诊断与恢复 |
| QA/自动化工程师 | 1 FTE | 设备矩阵、自动化、性能与发布门禁 |
| 产品/设计 | 0.3 FTE | 用户流程、披露、文案和验收 |
| 安全/发布 | S7-S9 阶段 0.2 FTE | Shell、供应链、隐私和发布审查 |
从正式启动日 T0 起,基线周期为 26 周,包含 2 周发布缓冲。不包含等待 Google Play 政策审批、采购稀缺设备或 OEM 外部支持的时间。
基线工作量:
- Android 开发:约 52 人周;
- QA/自动化:约 26 人周;
- 产品/设计:约 8 人周;
- 安全与发布专项:约 3 人周;
- 合计约 89 人周,不含外部政策审批等待时间。
设备池建议至少 8 台实体设备,覆盖主力 Redmi MIUI 14、较新 Xiaomi/HyperOS、Pixel/AOSP、Samsung、OPPO、vivo、realme,以及可运行 Android 17 的 Pixel。Android 9-10 可由保留设备和模拟器共同覆盖,但基础动作必须在至少一台 Android 9 实体设备上验证。
现金预算在立项时按下式填写:
人力预算 = 各角色人周 × 对应完全成本周费率 项目预算 = 人力预算 + 设备采购/租赁 + 签名与发布 + 10% 风险准备金
在角色费率、可复用设备和发布渠道尚未确定前,本文件不虚构金额。预算、实际负责人和 T0 日期是把 26 周估算转为正式交付承诺前的立项必填项。
| 切片 | 相对周 | 负责人 | 依赖 | 退出结果 |
|---|---|---|---|---|
| S0 可行性与设备基线 | W1-W2 | 平台负责人、QA | 测试设备 | Go/No-Go |
| S1 应用骨架与权限 | W3-W4 | 产品工程师 | S0 Go | 可安装诊断版 |
| S2 时间线与归因 | W5-W7 | 平台负责人 | S0 | 可重放状态机 |
| S3 确定性规则引擎 | W6-W8 | 产品工程师 | S1、S2 接口 | 可解释决策 |
| S4 基础跳转终止 | W9-W11 | 平台负责人 | S2、S3 | 基础阻止能力 |
| S5 小米快应用适配 | W10-W12 | 平台负责人、QA | S4 | 基础 MVP |
| S6 体验、诊断与恢复 | W13-W15 | 产品工程师、QA | S4 | 非技术用户可用 |
| S7 Shizuku 增强 | W13-W17 | 平台负责人、安全 | S4、恢复模型 | Advanced Alpha |
| S8 兼容、性能、可靠性 | W18-W22 | QA、全体开发 | S5-S7 | Public Beta 候选 |
| S9 合规与发布 | W20-W24 | 产品、发布、全体 | S6-S8 | RC |
| 发布缓冲 | W25-W26 | 全体 | RC | Stable 1.0 或延期决定 |
关键路径:
S0 -> S2 -> S3 -> S4 -> S5 -> S8 -> S9
实际负责人姓名、T0 日期、设备采购和分发渠道必须在立项评审时填写。任何关键角色少于基线投入时,应重新估算,不得保持 26 周承诺不变。
交付:
- PoC APK;
- 无障碍和 UsageStats 双时间线;
- Android 9 兼容实现;
- Redmi MIUI 14 与至少一台对照设备报告;
- 测试 App、标注数据集和延迟工具;
- Go/No-Go 记录。
最低样本:
- 100 次自动触发的应阻止跳转;
- 100 次用户点击触发的应阻止跳转;
- 200 次应允许跳转;
- 50 次桌面主动打开;
- 50 次锁屏、最近任务和多窗口切换。
Go 条件:
- 目标事件获取率至少 95%;
- 应阻止候选识别率至少 93%;
- 允许流程误阻止率不高于 2%;
- 最终离开目标成功率至少 90%;
- 无无限返回、关键组件动作或用户身份混淆;
- 报告每项点估计和 Wilson 95% 置信区间;
- 明确列出稳定、不稳定和不可实现能力。
无法执行一次安全返回,或允许流程误阻止不可控时,项目 No-Go。
- Compose、导航、Room、DataStore 和依赖注入;
- 权限状态、健康检查和总暂停;
- 用户可独立完成授权;
- 权限撤销后 3 秒内更新;
- 所有步骤可返回,不使用误导按钮;
- 数据库迁移测试通过。
- 信号归一化、双时钟、去抖、身份解析和来源上下文;
- 桌面、最近任务、锁屏、多窗口和用户切换处理;
- 同包切换不生成候选;
- 经桌面主动打开不沿用旧来源;
- 时钟跳变使上下文失效;
- 核心分支覆盖率至少 90%;
- 候选生成 P95 不高于 150 ms。
- 严格、询问、记录和暂停;
- 显式规则、类别规则、安全上限和 AllowOnceToken;
- 相同输入产生相同输出;
- 每次决策输出解释;
- AllowOnceToken 原子消费且崩溃不重复;
- 导入不能绕过安全上限;
- 核心分支覆盖率至少 90%。
主测试设备 200 次应阻止测试:
- 正确阻止决策至少 95%;
- 最终离开目标至少 93%;
- 目标出现到首次动作 P95 不高于 300 ms;
- 目标出现到离开目标 P95 不高于 900 ms;
- 允许规则误阻止率不高于 1%;
- 无持续返回循环;
- 基础模式不执行 Shell。
- VERIFIED、PARTIAL、UNKNOWN、NOT_FOUND 状态完整;
- 普通应用不得误标为快应用框架;
- 宿主更新触发失效;
- 200 次来源到宿主测试中,候选识别至少 95%,离开目标至少 93%;
- 未识别内部应用不伪造名称;
- 禁用宿主不是默认推荐。
完成 S0-S5 后达到基础 MVP。
- 历史记录可直接建立规则;
- 三个操作内暂停全部保护;
- 服务中断明确显示失效;
- 导出默认脱敏;
- 普通历史可清空;
- 存在外部状态修改时禁止无提示清空恢复账本;
- 错误页面不得只显示堆栈;
- 直接卸载与清除数据限制有显著说明。
- 未连接时基础模式继续;
- 重启失效有明显提示;
- Probe APK 探测和回滚全部通过;
- force-stop 100 次至少 99 次通过状态验证;
- 无命令注入路径;
- 未授权不得执行 L3-L5;
- 关键组件请求全部拒绝;
- 100 次 suspend/disable/restore 故障注入无不可恢复状态;
- 模拟命令成功但应用崩溃后,恢复中心可根据 PREPARED/APPLIED 账本收敛;
- 使用外部恢复清单可以在应用数据丢失后人工恢复测试包。
最后一项不通过时,v1 移除 suspend 和 disable。
覆盖:
- Android 9-16;
- Android 17 兼容轨道;
- MIUI、HyperOS、Pixel/AOSP、Samsung;
- OPPO、vivo、realme 至少各一台代表设备;
- 分屏、画中画、最近任务、通知跳转、服务重启和系统更新。
门槛:
- 一级设备通过全部核心测试;
- 二级设备通过基础阻止和恢复测试;
- 24 小时无 ANR;
- 10 万次事件重放无持续内存增长;
- 稳态 PSS 不高于 120 MB;
- 空闲后台平均 CPU 低于 1%;
- 标准 8 小时空闲测试附加耗电中位数不超过 2 个百分点;
- 数据库损坏时不执行 L3-L5;
- 无未关闭 P0/P1。
- 隐私政策、无障碍显著披露和演示视频;
- 权限与包可见性声明;
- 开源许可证、第三方清单和 SBOM;
- 可复现 CI 构建、签名和回滚流程;
- Release 不含测试密钥、调试接口或敏感日志;
- 依赖扫描无已知严重漏洞;
- 完成公开测试退出报告;
- 产品、技术和测试负责人签署发布清单。
任务进入实施前必须具备:
- 用户价值;
- 输入、输出和用户身份范围;
- 权限要求;
- 失败与降级行为;
- 动作等级;
- 测试场景和验收标准;
- OEM 影响;
- 是否修改外部状态及其恢复方案;
- 数据处理说明。
- 代码完成并经至少一人审查;
- 单元、仪器或手工验收通过;
- Lint、Detekt、Ktlint 通过;
- 无新增高危安全问题;
- 用户文案、日志和错误状态可解释;
- 文档、迁移和恢复说明更新;
- 验收人按条款确认。
- 策略和状态机使用纯 Kotlin;
- 状态不可变;
- 时间逻辑通过双时钟接口注入;
- Shell 后端通过类型化接口隔离;
- OEM 适配器不得写入策略核心;
- 禁止主线程数据库和命令操作;
- 禁止在无障碍回调执行长任务;
- 异步动作支持超时和取消;
- 不静默吞异常;
- 错误转换为明确领域状态;
- 所有 L5 使用写前账本;
- 用户序列号是持久身份,运行时 userId 只在执行前解析。
| 模块 | 最低分支覆盖率 |
|---|---|
| Policy Engine | 90% |
| Transition Correlator | 90% |
| Identity Resolver | 90% |
| Action Router | 85% |
| Shell 命令构造 | 95% |
| Recovery Journal | 95% |
| 数据库迁移 | 100% 场景覆盖 |
| OEM 适配器 | 80% |
| UI | 关键路径测试 |
不得使用无实际断言的测试提高覆盖率。
每次合并:
- Debug/Release 编译;
- 单元测试;
- Android Lint、Detekt、Ktlint;
- 依赖漏洞扫描;
- 数据库迁移和恢复账本测试;
- 核心事件重放;
- APK 权限和导出组件清单比对;
- 规则/恢复文件模糊测试;
- Android 9 API 兼容检查。
RC 额外执行:
- 物理设备回归;
- 性能和耗电基准;
- 24 小时稳定性;
- Shell 安全和恢复演练;
- 隐私数据流审查;
- SBOM、签名和可复现构建验证。
v1 必须满足:
- 选择受保护来源;
- 设置来源默认模式;
- 管理来源-目标规则;
- 阻止普通第三方目标和小米快应用宿主;
- 允许支付、分享和文件选择流程;
- 查看决策原因;
- 暂停保护;
- Shizuku 不可用时基础功能不受影响;
- 任何已发布的外部状态修改均有独立恢复办法。
每台一级设备至少:
- 200 次应阻止普通跳转;
- 200 次应阻止快应用跳转;
- 400 次应允许跳转;
- 100 次桌面主动打开;
- 100 次权限、分享、文件选择和支付流程;
- 100 次锁屏、最近任务、多窗口和用户切换。
结果按设备单独报告,不允许用汇总数据掩盖单设备失败。同时报告点估计、样本数和 Wilson 95% 置信区间。
| 指标 | 基础模式 | Shizuku 模式 |
|---|---|---|
| 应阻止候选识别率 | >=95% | >=95% |
| 最终离开目标成功率 | >=93% | >=99% |
| 允许流程误阻止率 | <=1% | <=1% |
| 破坏性误操作 | 0 | 0 |
| 无限动作循环 | 0 | 0 |
| 跨用户误操作 | 0 | 0 |
- 事件进入到决策 P95 <=150 ms;
- 决策到首次动作 P95 <=150 ms;
- 目标出现到首次动作 P95 <=300 ms;
- 目标出现到离开目标 P95 <=900 ms;
- 规则查询 P95 <=10 ms;
- 日志写入不得阻塞动作执行;
- 无持续主线程卡顿。
- 无任意 Shell 入口;
- 外部应用不能调用动作服务;
- 导入不能绕过安全上限;
- 包名、用户身份和目标状态均验证;
- 数据库异常不执行 L3-L5;
- 关键包拒绝规则有策略层和后端层测试;
- 每项持久修改都有写前记录、状态验证和恢复;
- 应用数据丢失后的独立恢复演练通过;
- Release 关闭调试接口。
- 默认无网络传输;
- 默认不保存窗口文本或点击内容;
- 应用列表不用于广告或画像;
- 用户可以查看和清除普通数据;
- 导出由用户主动发起;
- 隐私声明准确列出无障碍、UsageStats、包可见性和 Shizuku 用途。
普通应用、浏览器、应用商店、安装器、快应用框架、支付应用、相机、文件选择器、分享面板、设置、权限控制器、桌面、电话、输入法、Jump Terminator、Shizuku 和 Probe APK。
用户点击、伪关闭按钮、自动跳转、返回触发、后台触发、通知点击、Deep Link、URL Scheme、重复拉起、延时拉起、A -> B -> C 链和宿主内部再跳转。
横屏、分屏、画中画、多显示器、锁屏、解锁、最近任务、低电量、省电、无障碍重启、Shizuku 断开、应用/宿主/系统更新、无网络、内存压力、系统时钟修改、双开和工作资料。
| 风险 | 等级 | 触发/指标 | 负责人 | 应对 |
|---|---|---|---|---|
| 无障碍事件延迟或丢失 | 高 | 识别率低于门槛 | 平台负责人 | 双信号、去抖、OEM 参数、真机测试 |
| 允许流程误阻止 | 高 | 任一一级设备 >1% | 产品、平台 | 显式规则、安全角色、扩大负样本 |
| 目标闪屏 | 高 | 用户测试投诉 | 产品 | 明确边界、降低延迟、覆盖层提示 |
| MIUI 杀后台 | 高 | 服务假运行 | 平台负责人 | 健康检查、后台引导、心跳 |
| 快应用宿主变化 | 高 | 签名/组件不匹配 | 适配负责人 | 组合识别、版本失效 |
| Play 无障碍审批 | 高 | 拒审或政策变化 | 产品、发布 | 静态规则、披露、合规构建、替代渠道 |
| 包可见性不足 | 中高 | 应用列表不完整 | 产品工程师 | 精确 queries、分变体、政策评审 |
| Shizuku 重启失效 | 中 | Binder 断开 | 平台负责人 | 自动降级、明显状态 |
| 关键应用误操作 | 极高 | 任一 L3-L5 命中关键包 | 安全负责人 | 动态角色、双层拒绝、故障注入 |
| 恢复账本丢失 | 极高 | 未恢复状态无记录 | 平台、安全 | 写前账本、外部清单;失败则移除 L5 |
| 多用户身份错误 | 高 | userSerial 无法解析 | 平台负责人 | 全链路身份、未知即 L0 |
| 分屏/PiP 归因错误 | 中 | 多活动窗口 | 平台负责人 | 窗口集合模型、降低置信 |
| 规则数据库损坏 | 中 | 校验/迁移失败 | 产品工程师 | 备份、只读模式、禁止 L3-L5 |
| Android 17 行为变化 | 中高 | 兼容测试失败 | 平台、QA | 预览轨道、正式版升级一级设备 |
| 进度低估 | 高 | 关键路径延迟 >2 周 | 技术负责人 | 重估范围,优先砍 L5 和非核心 OEM |
- Internal:开发和自动化;
- Alpha:限定设备和技术用户;
- Closed Beta:MIUI/HyperOS 高频用户;
- Public Beta:扩大 OEM 和 Android 覆盖;
- Stable 1.0:全部发布门槛通过。
Standard
- 无 Root;
- 无障碍基础终止;
- UsageStats;
- 快应用适配;
- 无 L5;
- 默认无 INTERNET;
- Play 包可见性按审批结果最小化。
Advanced
- 包含 Shizuku;
- 增强诊断;
- 可包含更完整应用列表;
- L3-L4 默认关闭;
- L5 仅在 S7 独立恢复门槛通过后编译启用;
- 面向官网、代码托管平台或允许该能力的市场。
两个变体共享规则、归因和安全核心。
采用语义化版本:
- 主版本:权限模型、恢复模型或规则格式不兼容;
- 次版本:新增功能或 OEM 适配;
- 修订版本:缺陷和参数调整。
规则、兼容配置和恢复清单均包含 schemaVersion、producerVersion 和安全策略版本。
只有同时满足以下条件才能发布 1.0:
- S0-S9 全部完成;
- MIUI 14 为一级支持;
- 一台较新 Xiaomi/HyperOS 通过核心测试;
- 一台 AOSP/Pixel 通过基础测试;
- 若 Android 17 已正式发布,则至少通过一台 Android 17 设备;
- 快应用和普通跳转达到准确率门槛;
- 允许流程误阻止不超过 1%;
- 无 P0、无未接受风险的 P1;
- 有完整暂停、诊断和恢复中心;
- 所有已发布持久动作通过独立恢复演练;
- 有权限披露、隐私政策和公开限制;
- 有可复现构建和签名流程;
- 不把返回宣传为事前拦截;
- 不把 force-stop 宣传为永久冻结;
- 不伪造无法识别的快应用名称;
- 所有动作可追踪;
- 产品、技术和 QA 共同签署发布清单。
- 应用保护列表;
- 严格、记录和暂停模式;
- 来源-目标规则;
- Android 9-16 信号兼容;
- 用户身份和双时钟归一化;
- 返回和主页动作;
- 小米快应用宿主识别;
- 历史、暂停和健康检查;
- 本地数据;
- 安全角色解析;
- 无外部状态修改时也可完整使用的 Standard 构建。
- 询问模式和 AllowOnceToken;
- 无障碍覆盖层;
- 快捷设置磁贴;
- 规则导入导出;
- Shizuku force-stop;
- 重复拉起检测;
- OEM 诊断;
- Android 17 兼容。
- 经 S7 验证的 suspend/disable;
- 具体快应用名称实验识别;
- 社区签名规则包;
- Device Owner 版本;
- 其他厂商快应用适配;
- 脱敏适配报告。
- Root、Xposed;
- VPN 流量分析;
- 云账户、广告;
- 自动卸载;
- 任意 Shell 控制台;
- AI 自主操作或自主规则决策;
- 完整跨用户管理;
- 无恢复账本的持久状态修改。
flowchart TD
S0["S0 可行性验证"] --> DECISION{"Go?"}
DECISION -->|No| STOP["停止或重新定义产品"]
DECISION -->|Yes| S1["S1 应用骨架与权限"]
S1 --> S2["S2 时间线、身份与归因"]
S2 --> S3["S3 规则引擎"]
S3 --> S4["S4 基础跳转终止"]
S4 --> S5["S5 小米快应用适配"]
S5 --> MVP["基础 MVP"]
MVP --> S6["S6 体验、诊断与恢复"]
MVP --> S7["S7 Shizuku 增强"]
S6 --> S8["S8 兼容与可靠性"]
S7 --> S8
S8 --> S9["S9 合规与发布"]
S9 --> V1["Stable 1.0"]
项目最重要的首个验收点是:
在实际 MIUI 14 设备上,能否以足够稳定的事件准确率、足够低的允许流程误判率和可接受延迟,识别受保护来源进入目标应用的状态变化,并安全撤销跳转。
只有 S0 达到门槛,完整产品开发才具备工程意义。
- UsageEvents.Event API 与版本信息
- AccessibilityService API
- Google Play 无障碍 API 政策
- Google Play target API 要求
- Android 包可见性
- Android 17 发布说明
- Shizuku 启动与重启说明
- Shizuku API 与 UserService 生命周期
- 应用卸载广播限制
相对 v1.0:
- 修复 Android 9 使用 API 29 事件名称的问题;
- 明确“允许一次”为用户重新触发后的下一次匹配,不重放原始 Intent;
- 将 userSerial/runtimeUserId 贯穿信号、规则、日志、动作和恢复;
- 将 LOW 自动动作上限降为只记录;
- 增加 Shizuku Probe APK 和非破坏性、可回滚能力探测;
- 增加写前恢复账本、外部恢复清单和直接卸载限制;
- 统一关键组件的分级安全矩阵;
- 强化 S0 的负样本、误阻止率和统计报告;
- 补充人员、26 周排期、负责人、依赖和关键路径;
- 加入 Android 17 兼容轨道;
- 修正保护模式列表结构;
- 将无法通过独立恢复验收的 suspend/disable 从 v1 移除。