Skip to content

FAMILY-26 — Telemetry 端到端真机 E2E 测试计划

目标: 验证 telemetry 全链路 — Android 孩子端采集前台 app → 权限/freeze/quiet-hours 闸 → child_event 落库 → P2P 上行 → 桌面 family_child_event 镜像 → 家长仪表板(V5/native renderer IPC + web-shell/V6/web-panel WS 三入口)显示。

范围: FAMILY-20(ForegroundAppTimer + Usage Access UI)/ FAMILY-21(CentralTelemetryDispatcher

  • RelationshipTelemetryUploadGate)/ FAMILY-24(Quiet Hours)/ FAMILY-26(SyncManagerTelemetryOutbox
  • desktop 接收器 + 家长仪表板 + cross-shell)。FAMILY-16 freeze 闸联动。

不能在 Windows dev box 跑 — 需 Android 真机(CHILD 角色)+ 已配对真桌面(Electron)+ USB adb。 本文档是可执行清单;执行需 Mac/Linux 或带真机的 Win + 真桌面实例。串行预计 ~2h。


0. 链路总览(被测对象)

[Android child]                                  [Desktop parent]
ForegroundAppTimer (60s poll, UsageStatsManager)
  → ChildIdentityProvider 闸 (role==CHILD + DID)
  → ForegroundAppQuery 闸 (Usage Access granted)
  → ForegroundAppTelemetrySource.submitSample
  → CentralTelemetryDispatcher.process
      ├ UpstreamFreezer.isFrozen?            (FAMILY-16)
      ├ RelationshipTelemetryUploadGate      (FAMILY-25 level + FAMILY-24 quiet hours)
      ├ ChildEventRepository.saveTelemetryEvent  → child_event (SQLCipher)
      └ SyncManagerTelemetryOutbox.enqueue   → SyncItem(TELEMETRY) → SyncManager.recordChange
                                              → P2P sync.push ───────►  handlePush → _applyItemLocal
                                                                         → _applyTelemetry
                                                                         → family_child_event 镜像表
                                                                         → family-guard:* IPC / WS topic
                                                                         → 家长仪表板 (V5 + web-panel)

1. 前置条件

硬件

  • [ ] Android 真机 1 台(Android 8.0+ / API 26+,UsageStatsManager 需要;arm64)。
  • [ ] USB 线(adb debug + APK install)。
  • [ ] 真桌面 1 台(Electron 桌面 app 已装;Win/macOS/Linux 均可作家长端)。
  • [ ] 同一局域网 / 信令可达(P2P sync 走 mobile-bridge)。

软件

  • [ ] Android SDK platform-tools(adb devices 识别真机)。
  • [ ] 桌面 Electron app 可启动(cd desktop-app-vue && npm run dev 或已打包安装版)。
  • [ ] 已配对:child↔parent 走 Flow A/C QR 配对(见 Android_W3_Pairing_E2E.md),是 telemetry 上行前置。

仓库 / 构建状态

  • [ ] Android release/debug APK 含 FAMILY-20→26(a93f27b4e / 533fb3e3c / c04b068d2 / 7e53a1820 …)。
  • [ ] 桌面含 FAMILY-26 接收器 + 仪表板(459a61901 / 7936235df / c6cd3c38f)。
  • [ ] web-panel dist 已 build(cd packages/web-panel && npm run build)— V6 shell / web-shell 读 dist。

2. Setup 步骤

2.1 安装 APK + 启动

bash
adb devices                                    # 确认真机 authorized
adb install -r android-app/app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n com.chainlesschain.android/.MainActivity

2.2 选 CHILD 角色 + 锁

  • App 首启 → 角色选择 → 选「孩子」→ 确认。
  • 验证:RolePreferencesRepository 状态进入 LockPending(CHILD)(24h 内可改)。CHILD 是 telemetry 采集的硬闸(RoleAwareChildIdentityProvider.childDidOrNull 非 CHILD 返 null → 不采集)。

2.3 授予 Usage Access

  • 进「家庭」tab → 顶部出现红色「开启『使用情况访问』」引导卡(UsageAccessCard,仅 CHILD + 未授权时显)。
  • 点「前往授权」→ 系统设置「使用情况访问」→ 找到本 app → 开启 → 返回。
  • 验证:返回后(onResume)卡自动消失UsageAccessViewModel.recheck → state 翻 Granted)。

2.4 确认前台服务 + 调度器启动

bash
adb logcat -s FamilyGuardForegroundService CentralTelemetryDispatcher
# 期望:
#   FamilyGuardForegroundService.onCreate
#   CentralTelemetryDispatcher started; N source(s)
  • 持久通知「家庭守护」应常驻。ForegroundAppTimer 已 start(每 60s poll)。

2.5 桌面启动 + 配对确认

bash
cd desktop-app-vue && npm run dev          # 或启动打包版
  • 完成 child↔parent 配对(Flow A)。验证 mobile-bridge 就绪 + 设备列表含孩子设备。

3. 测试场景

采集是 60s 轮询 + 同 app 连续合段(30min 强制切)。每个使用场景后等 ≥2 个 poll 周期(~2-3min) 再切包,确保 aggregator finalize 一段。

Scenario 1 — Happy Path(采集 → 上行 → 仪表板)

Child 步骤:

  1. 打开 app A(如游戏)用 ~2min → 切到 app B(如聊天)用 ~2min → 回桌面。
  2. adb logcat -s SyncManagerTelemetryOutbox 期望见 Telemetry → sync queue: telemetry|<did>|foreground_app|run|<ts> (source=foreground_app guardians=N)

Desktop 步骤: 3. 等 sync 周期(SyncCoordinator ~30s push)。 4. V5/native renderer: 进 /family-guard → 选孩子 → 见「应用使用排行」含 app A/B + 时长;「最近事件」含 run 行。 5. web-panel / V6 shell: 切到 web-shell 模式(或 cc ui→ 实为 desktop 内嵌)→ 「家庭守护」侧栏 → 同样数据。

预期: 两端仪表板都显示 app A/B 的使用时长聚合 + 事件列表;时长与实际使用接近(±1 poll 周期)。

Scenario 2 — Telemetry level gate(FAMILY-25)

  • 家长端把对该孩子的 permissions.telemetryLevel 设为 L0(仅聚合)。
  • Child 继续用 app。预期: L1 run 事件被 RelationshipTelemetryUploadGate 挡下(check(ReadTelemetryL1) Deny)→ 不落库不上行 → 仪表板无新增 L1 事件。
  • 改回 L1 → 恢复上行。

Scenario 3 — Quiet hours(FAMILY-24)

  • 家长端配私有时段覆盖当前时刻(如 00:00-23:59)。
  • Child 用 app。预期: 事件发生时刻落私有时段 → QuietHoursEngine.isActive true → 该 guardian 被排除 → 不上行。退出私有时段后恢复。
  • 注:按事件 timestampMs(采集时刻)判,非"现在"。

Scenario 4 — Emergency freeze(FAMILY-16)

  • 触发紧急解绑 freeze(孩子端复活码路径)→ UpstreamFreezer.isFrozen = true。
  • 预期: CentralTelemetryDispatcher 收到 freeze → pause 所有 source(真停采集);process() 二重保险也丢。仪表板无新数据。unfreeze 后恢复。

Scenario 5 — Usage Access 未授予

  • 撤销 Usage Access(系统设置关闭)。
  • 预期: UsageAccessCard 重现;ForegroundAppQuery.isAccessGranted false → pollOnce 早返 → 不采集。仪表板无新数据。

Scenario 6 — 非 CHILD 端不采集

  • 另一台设备选 PARENT 角色。
  • 预期: ForegroundAppTimer.pollOncechildDidOrNull() 返 null → 早返,零采集(家长端不监控自己)。

Scenario 7 — 三入口 parity

  • 同一份 family_child_event 数据,在 (a) V5/native renderer /family-guard(IPC family-guard:*)、(b) web-shell/V6(WS topic family-guard.*)、(c) web-panel 独立页,显示一致(孩子列表 / app 排行 / 事件 / 时窗 24h/7d)。

Scenario 8 — cc ui standalone 降级

  • cc ui(非 desktop Electron,无 desktop DB)打开「家庭守护」页。
  • 预期: 优雅显空("还没有收到任何孩子端的使用数据"),不崩。family-guard topic 仅注册于 web-shell Gateway 1(desktop-only 数据),standalone 无 handler → composable reject → store 兜底空。

Scenario 9 — 幂等(重复 sync 不重复行)

  • 触发重复 sync push(断网重连 / 手动重推)。
  • 预期: 同 resource_idtelemetry|childDid|source|kind|startMs)在 desktop _applyItemLocal conflict 预检判 "local" 跳过 → family_child_event 不出现重复行。

4. 验收标准(总)

  • [ ] S1 端到端:child 采集的 app 使用时长在两端(V5 + web-panel)仪表板可见且数值合理。
  • [ ] S2/S3/S4/S5/S6 五个闸(level / quiet hours / freeze / usage-access / role)各自正确拦截。
  • [ ] S7 三入口数据一致。
  • [ ] S8 cc ui standalone 优雅降级不崩。
  • [ ] S9 重复 sync 无重复行。
  • [ ] 全程无 ANR / crash(adb logcat *:E 无 family-guard FATAL;主线程无 keystore ANR,见 [[android_main_thread_keystore_anr_and_dagger_default_param]])。

5. 验证手段速查

目标手段
timer/dispatcher 启动adb logcat -s FamilyGuardForegroundService CentralTelemetryDispatcher
上行入队adb logcat -s SyncManagerTelemetryOutboxTelemetry → sync queue: …
child_event 落库family-guard DB 是 SQLCipher,不直接 adb dump;以「上行入队日志 + 桌面镜像到达」作端到端证据
桌面镜像家长仪表板(V5 /family-guard + web-panel);或桌面 DevTools 看 family-guard:* IPC 返回
sync 推送桌面 mobile-bridge / SyncCoordinator 日志

6. 已知限制(本计划不解决)

限制影响后续
Windows dev box 不能跑需 Android 真机 + 真桌面 + 配对Mac/Linux 或带真机环境执行
family-guard DB SQLCipher无法直接 adb dump child_event 核对以端到端(桌面镜像到达)为证;或后续加 in-app debug dump(仿 VaultPreviewSheet)
采集 60s 轮询 + 30min 合段短时使用可能未 finalize;需等 ≥2 poll测试时显式等待或缩短 poll(debug build 可调 ForegroundAppTimer.POLL_INTERVAL_MS
后台关屏未切包时长累计依赖"沿用上次包"关屏期间可能过/欠计真机标定后调 query 窗口逻辑
cc ui standalone 无数据设计如此(desktop-only 镜像)不修;UI 已优雅降级

7. 执行记录(填表)

Scenario设备日期结果备注
S1 Happy Path
S2 Level gate
S3 Quiet hours
S4 Freeze
S5 No usage access
S6 Non-child
S7 三入口 parity
S8 cc ui standalone
S9 幂等

8. 相关

  • 配对前置:Android_W3_Pairing_E2E.md(Flow A QR 配对)。
  • 设计主文档:AI陪学_主文档.md(§3.2 telemetry 数据源 / §3.1 freeze / §3.4 时间裁决)。
  • 上行接收实装:desktop-app-vue/src/main/sync/mobile-bridge-sync.js_applyTelemetry)。
  • 采集链:android-app/feature-family-guard/.../data/telemetry/(Timer / Source / Dispatcher / Outbox / Gate)。

附录:规范章节补全(v5.0.3.108)

本文为设计文档。为对齐项目文档标准结构,下列章节以 见正文 指引或简述方式补齐若干视角,不重复正文细节。

1. 概述

见正文头部。FAMILY-26 Telemetry 真机 E2E 测试计划:家庭守护 telemetry 真机 E2E。

2. 核心特性

Telemetry / 真机 E2E / FAMILY 守护。

3. 系统架构

见正文架构 / 设计章节。

4. 系统定位

ChainlessChain 的「FAMILY-26 Telemetry E2E」。

5. 核心功能

见正文功能 / 设计章节。

6. 技术架构

见正文实现 / 技术章节。

7. 系统特点

见正文(状态 / 版本 / 特性)。

8. 应用场景

见正文应用场景 / 背景。

9. 竞品对比

见正文对比 / 借鉴(如有)。

10. 配置参考

见正文配置 / 参数章节。

11. 性能指标

见正文性能 / 指标章节。

12. 测试覆盖

见正文测试 / E2E 章节。

13. 安全考虑

见正文安全 / 权限章节。

14. 故障排除

见正文故障 / trap / 已知限制章节。

15. 关键文件

见正文实现位置 / 关键文件章节。

16. 使用示例

见正文使用 / 命令 / API 示例。

17. 相关文档

系统设计主文档、相关设计文档。

ChainlessChain 系统设计文档 — 面向开发者