03 · 门开关业务流程图
车门业务有两条主线,交汇点都是「读写车辆信号 + 车门状态可视化」:
| 主线 | 触发方 | 入口 | 典型场景 |
|---|---|---|---|
| A · 设置页主动操作 | 用户 | VehicleDoorToggleCtrlPreferenceController | 在锁车设置页点电动门开关 |
| B · 离车提醒弹窗 | 车端信号 | UnlockDoorTrigger(scene) → DoorUnLockActivity | 锁车时检测到门没关,弹窗提醒 |
主线 A:设置页主动开门(电动门)
sequenceDiagram autonumber participant User as 用户 participant Ctrl as VehicleDoorToggleCtrlPreferenceController participant Base as CarPropertyMgrPreferenceController(基类) participant SCPM as SettingsCarPropertyManager participant VCM as VehicleControlManager participant Car as 车端 Note over Ctrl: onCreateInternal 注册关心的信号<br/>POWER_OPERATED_DOOR_MOVING_STATUS 等 User->>Ctrl: 点击电动门开关按钮 Ctrl->>Ctrl: onClickButton 判断当前状态 [:100] Ctrl->>Ctrl: setVehiclePropertyByStatus 决定命令 [:110] Ctrl->>Base: setVehicleProperty(BUTTON_STATUS, ON/OFF/STOP, area) Base->>SCPM: setCarPropertyBySync(propId, value, area) SCPM->>SCPM: 埋点 + 连接检查 + 启动超时监控 SCPM->>VCM: setIntPropertyBySync VCM->>Car: AOSP setProperty (异步线程) Car-->>VCM: 车端执行 + 回弹 MOVING_STATUS VCM-->>SCPM: onChangeEvent SCPM-->>Base: onPropertyChanged Base-->>Ctrl: onHandlePropertyChange [:150] Ctrl->>Ctrl: updateUI 更新按钮态(开/关/暂停) [:163] alt 不可用(高速/防玩/温度) Car-->>SCPM: DISABLE_REASON SCPM-->>Ctrl: onPropertyChanged Ctrl->>Ctrl: showToast 不可用原因 [:284] end
关键点
- 命令下行用
POWER_OPERATED_DOOR_BUTTON_STATUS(ON/OFF/STOP),状态回读用POWER_OPERATED_DOOR_MOVING_STATUS(6 态)。 - 超时监控自动启动:车端不回弹会触发
onSetPropertyTimeout→ 提示用户。 - 不可用原因单独一个信号
POWER_OPERATED_DOOR_DISABLE_REASON,UI 弹对应 Toast。
主线 B:离车提醒弹窗(JIRA 1838/1839 场景)
sequenceDiagram autonumber participant Car as 车端 MCU participant VHAL as VHAL/CarPropertyService participant CPCM as CarPropertyCacheManager participant Trigger as UnlockDoorTrigger<br/>(com.micar.scene aar) participant Act as DoorUnLockActivity<br/>(本仓库 car.settings) participant SCPM as SettingsCarPropertyManager participant Handler as 8s 倒计时Handler Note over Car: 用户锁车,活体检测发现门没关 Car->>VHAL: LockFltRemdForAlive(0x61403156) v=1 LOCK_FAIL VHAL->>CPCM: onChangeEvent CPCM->>Trigger: processSignal(v=1) [:79-86] Note over Trigger: 无 cooldown! 每次 v=1 都拉起 [:116-132] Trigger->>Act: startActivity(DoorUnLockActivity) Note over Act: onCreate [:57-83] Act->>Act: setContentView(lock_door_unlock_layout)<br/>⚠️ 5 门 ImageView 默认全 unlock(开态) [:59] Act->>SCPM: new SettingsCarPropertyManager + setCarManagerCallback(this) [:80-81] Act->>Handler: sendMessageDelayed 8s 倒计时 [:82] Act->>Act: onPropertyManagerPrepared [:86-89] Act->>SCPM: registerPropertyCallback(Door.STATE, LOCK_FAILED) [:88] Note over Car: 车端 Door.STATE(0x66403101) 6 area 回弹 Car->>VHAL: Door.STATE 逐 area v=0/1 VHAL->>CPCM: onChangeEvent (首注册异步,不 callbackByCache) loop 60ms 窗口逐门到达 CPCM->>SCPM: onChangeEvent SCPM->>Act: onPropertyChanged [:98-147] Act->>Act: 按 area+value setImageResource [:110-138] Note over Act: ⚠️ 多帧切换 = 闪烁源(1839) end alt 8s 到点 Handler->>Act: finish() [:47-49] else 收到 v=2 CANCEL Car->>VHAL: 0x61403156 v=2 VHAL->>SCPM: onChangeEvent SCPM->>Act: onPropertyChanged(LOCK_FAILED, CANCEL) [:141] Act->>Act: finish() [:143] end
两条线交汇点
graph TD A["车端信号变化"] --> B["CarPropertyService / VHAL"] B --> C["CarPropertyCacheManager<br/>(单例,分发+缓存)"] C --> D["SettingsCarPropertyManager<br/>(per-Controller)"] D --> E1["主线A: VehicleDoorToggle...<br/>设置页刷新按钮态"] D --> E2["主线B: DoorUnLockActivity<br/>弹窗刷新车门图标"] F["用户操作设置页"] --> G["setCarPropertyBySync 下行"] G --> D
主线 A 和 B 是两套独立的 UI,但共享底层
SettingsCarPropertyManager+CarPropertyCacheManager。区别:
- A 是 PreferenceController(设置页内),用户主动触发,有预读(
onCreateInternal就注册并刷新)。- B 是 Activity(弹窗),信号触发,无预读(
onCreate只setContentView,等onPropertyManagerPrepared异步注册)——这正是 JIRA 1839 闪烁的根因。
主线 B 的 Activity 生命周期(JIRA 1838 关联)
stateDiagram-v2 [*] --> Created: onCreatebr/setContentView(默认5门全开) Created --> Prepared: onPropertyManagerPreparedbr/registerPropertyCallback Prepared --> Showing: 收到 onChangeEventbr/逐门 setImageResource Showing --> Showing: 8s 倒计时进行中 Showing --> Finished: 8s 到点 finish() Showing --> Finished: 收到 v=2 CANCEL finish() Showing --> Finished: onStop finish() 【:158-161】 Finished --> [*] Finished --> Created: 下次 v=1 又拉起br/(launchMode=singleInstance + onNewIntent 重置计时)
onStop → finish()+singleInstance:每次信号触发都是全新 onCreate,必走「默认全开 → 异步回弹」流程——这就是 JIRA 1839「必现」的机制原因。
相关:04-MANNPROB-1838-根因-弹窗弹两次.md | 05-MANNPROB-1839-根因-车门闪烁全开.md