手套箱 07 · 埋点与测试

本篇回答:数据上报了什么、单测覆盖什么、台架怎么自测。 基线:fuben31_micarsettings/MiCarSettings @ dev

1. 埋点事件清单

常量:base/settingsBaseLib/src/main/java/com/android/micar/settings/track/TrackConstants.java:308-313(TIP)+ :536-538(参数 key); 封装:VehicleControlReporter.kt:104-115(TrackValues)+ :489-534(report 方法)。

事件事件 ID类型参数时机调用点
TIP_OPEN_GLOVE_BOX1147.1.0.1.54662CLICKtype:1=无密码直开 / 2=验证后开;+ tab_instance_id=VEHICLE_CONTROL实际下发 GLOVE_BOX=OPEN 时GloveBoxController.kt:237(openGloveBox() 内)
TIP_GLOVE_BOX_FORGOT_PASSWORD_SUCCESS1147.0.0.0.54663EXECUTE仅 tab_instance_id锁定→车主账号验证通过GloveBoxController.kt:248;GloveBoxSettingsDialogActivity.kt:262
TIP_GLOVE_BOX_PASSWORD_OPERATION1147.0.0.0.54664EXECUTEtype:1=设置成功 / 2=关闭成功 / 3=修改成功;+ tab_instance_id三个密码操作各自成功回调GloveBoxSettingsDialogActivity.kt:160/179/130

TrackValues 枚举(VehicleControlReporter.kt:104-115):

GLOVE_BOX_OPEN_NO_PASSWORD = 1   // 开箱 type:无密码
GLOVE_BOX_OPEN_WITH_PASSWORD = 2 // 开箱 type:密码/账号验证后
GLOVE_BOX_PWD_SET = 1            // 密码操作 type:设置
GLOVE_BOX_PWD_CLEAR = 2          // 密码操作 type:关闭
GLOVE_BOX_PWD_CHANGE = 3         // 密码操作 type:修改

埋点挂接示意:

flowchart LR
    A[点击开箱] --> B{分支}
    B -->|无密码直开| C["openGloveBox(NO_PASSWORD)<br/>→ 54662 type=1"]
    B -->|密码/账号验证通过| D["openGloveBox(WITH_PASSWORD)<br/>→ 54662 type=2"]
    E[锁定→账号验证通过] --> F["54663<br/>+ 54662 type=2"]
    G[设置密码成功] --> H["54664 type=1"]
    I[关闭密码成功] --> J["54664 type=2"]
    K[修改密码成功] --> L["54664 type=3"]

注意:MIS 语音/远程开箱复用 GloveBoxController.openGloveBox 吗?——不复用, GloveBoxNavigationHandler.openGloveBox()(:125-131)是自己直接写属性, 语音/远程开箱不会产生 54662 埋点(埋点只挂在 Controller 路径)。做数据分析时注意口径。

2. 单元测试覆盖

settingsPage/VehicleBodyControl/src/test/java/com/android/car/settings/miauto/vehicle/glovebox/GloveBoxControllerTest.kt(124 行), 继承 BaseVehicleToggleGroupTest<GloveBoxController>,JUnit5 + Mockito + Truth。

用例覆盖点
testButtonGroupSignal(参数化)TG-01/02:注入 OPEN/CLOSE,断言选中态跟信号走
signalUnavailable_groupDisabledTG-03:信号不可用 → 按钮组置灰
clickDisabledToggle_noPropertyWrittenTG-05:不可用下点击不写属性(Mockito never())
signalOpen_gloveBoxSwitchSelectedTG-04:OPEN → selectedToggleIndex ≥ 0
signalClose_gloveBoxSwitchNotSelectedTG-05:CLOSE 未选中(@Disabled,TODO 待基类精确断言)
timeout_uiRestoresPreviousSelectionTG-06:写属性超时 → UI 回滚原选中
getPropertyIdSet_containsCarModeStatusTG-07:订阅集含 CAR_MODE_STATUS
getPropertyIdSet_containsGloveBoxPropId订阅集含 GLOVE_BOX
getPropertyIdSet_containsTwoPropIds订阅集 size == 2

Mock 策略:基类统一提供 context/fragmentController/carPropertyManager(Mockito mock); injectSignalValue / injectUnavailableSignal / injectTimeout 三个 helper 模拟信号推送/ 信号不可用/写超时回滚;TestReflectionHelper 反射调 protected 方法; 参数化用自定义注解 @VehiclePropertyValues(@VehicleProp(propId=GLOVE_BOX, intValues=[OPEN,CLOSE]))。

未覆盖(改这些区域时自己补验证):密码弹窗(Fragment/Dialog)、账号验证、 MIS Handler、mLoginReceiver、GloveBoxSettingsDialogActivity。

3. 台架 mock 配方

按 car-signal-mock-test skill 的通用打法,手套箱台架自测需要这些信号/数据:

3.1 让入口显示出来(前置)

目的mock说明
入口显示0x6140b409 = 2GLOVE_BOX_LOCK_TYPE_CONFIG=POWER;台架默认 1(MANUAL)时入口隐藏
按钮可用0x6140b407 = 0GLOVE_BOX=CLOSE
无不可用原因0x6140b40a = 0UNAVL_REASON=IDLE
Tab1 可用登录账号 + 非代客 + CAR_MODE_STATUS=NORMAL代客: settings put secure judge_user_guest 0

3.2 分支用例矩阵

#前置操作期望
1无密码点开箱直接下发 OPEN;埋点 54662 type=1
2已是 OPEN点开箱Toast「请手动关闭手套箱」
3UNAVL_REASON=1点开箱Toast「请解锁车辆后重试」
4UNAVL_REASON=2点开箱Toast「操作过于频繁」
5无密码Tab1 → 点 Switch弹密码框(SET 模式,无「忘记密码」)→ 两次一致 → Toast「设置成功」,Switch ON,出现「修改密码」;埋点 54664 type=1
6有密码点开箱弹密码框(CHECK 模式,有「忘记密码」)→ 输对 → 开箱;埋点 54662 type=2
7有密码开箱时连错 4 次每次「密码错误」提示;settings get global glove_box_password_wrong_times 递增
8有密码开箱时第 5 次错自动拉账号验证页(qr_code);P 挡才拉起
9有密码非 P 挡触发锁定验证Toast「请驻车后重试」
10有密码密码框点「忘记密码」账号验证(不查 P 挡)→ 通过后进 SET 重设
11有密码Tab1 → 点 SwitchCHECK+close 流程 → 输对 → Toast「清除成功」,Switch OFF;埋点 54664 type=2
12有密码Tab1 → 修改密码验旧 → 两次新 → Toast「修改成功」;埋点 54664 type=3
13代客模式看 Tab1 / 点 Tab1置灰;点击 Toast「请在用户模式下使用该功能」
14未登录账号看 Tab1隐藏;登录广播后实时出现
15语音「打开手套箱」(无密码)MIS直接开,响应 1001
16语音开箱(有密码)MIS弹密码框 + 控制中心收起,响应 1002
17配置字=MANUAL语音开箱响应 1003,入口隐藏

3.3 密码数据的 adb 观察

# 查看密码哈希(非空=已设密码)
adb shell settings get global glove_box_password
# 查看错误次数
adb shell settings get global glove_box_password_wrong_times
# 查看盐(时间戳)
adb shell settings get global glove_box_password_salt
# 手动重置密码(模拟未设密码态)
adb shell settings put global glove_box_password ""
adb shell settings put global glove_box_password_wrong_times 0
# 手动制造锁定态
adb shell settings put global glove_box_password_wrong_times 5

⚠️ 台架判定以 App 日志与 UI 为准;vehicled 侧不持久回滚是假象(通用踩坑)。

4. 日志观测点

TAG/关键字内容
GloveBoxController / GloveBoxController 分发与状态
getGloveBoxLockTypeCarConfigManager 配置字读取(MLog.d)
PinPassword通用框架输入/校验
glovebox_verify账号验证 scene(账号侧日志)
CARSIGNAL 中 6140b407 / 6140b409 / 6140b40a车端原始信号流(04 篇 §7 排障表)