06 - 信号字典与命名约定
本篇解决”信号叫什么、在哪定义、怎么 grep、怎么新增一个信号常量”的问题。这是开发者最常用的一篇。
1. 信号的标识方式
1.1 主通道(CarProperty)—— int 常量
信号 ID 是 int 常量,全部定义在一个超大”信号字典”文件里:
base/settingsBaseLib/src/main/java/com/android/car/settings/miauto/vehicle/MiCarPropertyIds.java
⚠️ 重要纠正:既有文档
docs/05-车辆接口层与IPC.md说这个文件在settingsVehicleLib,这是错的。物理位置在settingsBaseLib(多 agent 源码确认)。但包名是com.android.car.settings.miauto.vehicle,引用方式是import com.android.car.settings.miauto.vehicle.MiCarPropertyIds——物理模块和包名不一致,是个历史遗留,注意别被误导。
文件规模:2140 行,约 30 个内部静态类。
1.2 组织方式:按功能分组成嵌套类
每个信号是 public static final int,值来自外部依赖 mi.car.config.*(不是手写数字):
public class MiCarPropertyIds {
public static class LightCtrl {
public static final int HEADLIGHT = Light.EXTERIOR_LIGHT_MODE;
public static final int FOG = Light.REAR_FOG_LIGHT_STATE;
public static final int MOOD_LIGHT_BRIGHTNESS = ...;
}
public static class LockCtrl {
public static final int WALK_AWAY_LOCK = ...;
public static final int LOCK_BEEP = ...;
}
// ... 约 30 个内部类
}1.3 内部类(功能域)清单
| 内部类 | 域 | 典型信号 |
|---|---|---|
LightCtrl | 灯光 | HEADLIGHT、FOG、MOOD_LIGHT_BRIGHTNESS |
DoorCtrl | 车门/前备箱/充电口 | COVER_STATE、CHARGE_PORT、CENTRAL_LOCK |
LockCtrl | 锁车 | WALK_AWAY_LOCK、CHILDREN_LOCK、LOCK_BEEP |
DrivingCtrl | 驾驶控制(最大类) | STEERING_MODE、EPB、SUSPENSION_HEIGHT、GEAR、能量回收 |
BattleCtrl | 赛道模式 | 轮胎/刹车/电池温度、G 值表 |
AutoPilot | 智驾 | AEB、NOA_CONTROL、RCTA、DOW、LCA |
EnergyManagement | 充电/能量 | CHARGE_CONTROL、BATTERY_SOC、CHARGE_STATUS、TRANSFER_POWER |
SeatAdjustControl | 座椅 | 靠背/前后/高度调节、位置记忆 |
SafeAndSecurity | 安防 | 哨兵 SENTRY_MAIN_SWITCH、DMS、行车记录仪、限速 |
WindowCtrl | 车窗/遮阳帘/调光天幕 | |
MirrorControl | 后视镜 | |
HvacCtrl | 空调 | |
CarConfig | 配置字(车型配置位) | TRANSMISSION_DRIVELINE、SUSPENSION_CONFIG |
Condition | 状态/能耗统计 | WHEEL_PRESSURE、TOTAL_MILEAGE |
Hud / Radar / Caliper | HUD/雷达/卡钳 | |
Service | 雨刮等 | WIPER_RAIN_SENSOR_DETECT_LEVEL |
BodyCtrl | 车身 | |
Intercom | 对讲 |
2. ⚠️ 关键认识:propId 的真实数值不在本项目
项目内部不维护 propId 的数值。数值由外部 maven 依赖统一发放:
base/settingsBaseLib/build.gradle:118
api 'com.mi.car.config:api:0.0.15-SNAPSHOT'这个 com.mi.car.config:api(即 SOA 仓库)提供这些命名空间(全部为 public static final int):
mi.car.config.Body / Door / Driving / Energy / Guard / Hvac / Light /
Mirror / Peripheral / Seat / Warning / Window / CommonParams
以及枚举子类(如 Door.ChargePortState、Driving.OffRoadSubModeStatus、Body.SuspensionHeight)。
因此”新增一个信号”的真实步骤:
- 升级
com.mi.car.config:api版本(联系车控/SOA 团队)- 在
MiCarPropertyIds.java的对应内部类里加一行:public static final int XXX = mi.car.config.YourDomain.YOUR_SIGNAL;- 确认 dcd / xcd 两套 framework jar 都包含该常量
2.5 ⚠️ mi.car 不只是字典(对抗核验补充)
早期探索 agent 笼统说”mi.car 只是 propId 字典”——不准确。经 grep 定量核验,mi.car 在项目里承担三类角色:
| mi.car 子包 | 角色 | 命中规模 |
|---|---|---|
mi.car.config.* | propId 字典(常量数值) | 458 文件,752 import |
mi.car.hardware.* | 值类型(MiCarPropertyValue、MiVehicleAreaBody/Seat/Door) | 32 处使用 |
mi.car.core.* / mi.car.internal.* | 框架基础设施(storage、activity、user 等) | 56 + 30 import |
而且 base/settingsBaseLib/build.gradle 显式声明了车控 SDK maven 依赖:
api 'mi.car:vehicle.support:0.11.56-test3' // 注释: "micar-support-api for vehicle property control"
api 'mi.car:core.api:0.1.2.48'
api 'mi.car:sdk.static:6.5.1.13'
api 'com.mi.car.config:api:0.0.15-SNAPSHOT'注意区分:
mi.car.config(字典)是编译期常量;mi.car.hardware.MiCarPropertyValue(值类型)是运行时数据对象,比 AOSPCarPropertyValue多relative/extension字段(SOA 扩展)。MiCarPropertyIds.java本身就是 AOSP↔mi.car 的桥接类(同时 importandroid.car.VehiclePropertyIds和mi.car.config.*)。完整的三层架构图见 01 篇 §3。
3. grep 关键词表(带命中量)
命中量在
find ... -name "*.java" -o -name "*.kt"范围、已排除build/下统计。
3.1 最有效的 3 个关键词
| 关键词 | 命中文件数 | 用途 |
|---|---|---|
MiCarPropertyIds | 379 | 找到所有信号使用点(首选) |
SettingsCarPropertyManager | 83 | 找到所有读写入口 |
CarPropertyMgrPreferenceController | 54 | 找到所有车控 UI 控件 |
3.2 完整关键词表
| 关键词 | 命中文件数 | 含义 |
|---|---|---|
Property | 595 | 通用属性 |
CarProperty | 517 | CarProperty 相关 |
prop | 458 | propId / getProperty / setProperty |
VehicleProperty | 238 | VehiclePropertyUtil / VehiclePropertyConfig 等 |
GlobalCarPropertyManager | 34 | 全局单例入口 |
carProperty | 47 | 多为字段名 mCarPropertyManager |
RTI | 78 | rtiLib + 充电曲线(详见 05 篇) |
Signal / signal | 59 / 38 | 多在 rtiLib + 中文注释”信号” |
RTISignal | 7 | RTI 信号 |
VehicleControlManager | 8 | 底层封装(业务一般不直接用) |
3.3 ⚠️ 不存在的命名(别 grep)
以下命名在项目里命中为 0,是其它车载项目的命名习惯,本项目不用:
getSignal / setSignal / subscribeSignal / notifySignal
onSignalChanged / SignalListener / SignalCallback
VehicleSignal / SignalManager
本项目的”信号”就是 CarProperty,读写分别叫 getXxxProperty / setCarProperty,监听叫 registerPropertyCallback,回调叫 onPropertyChanged / onHandlePropertyChange。
3.4 推荐入门 grep 组合
# 找一个业务模块订阅了哪些信号
grep -rn "getPropertyIdSet\|getObservedPropertyIdSet" settingsPage/<module>/src
# 找一个 propId 在哪些地方被读写
grep -rn "MiCarPropertyIds.LightCtrl.FOG" --include=*.kt --include=*.java
# 找 Flow 架构相关
grep -rn "mapPropFlow\|collectIn\|CarPropertyRepo" settingsPage/
# 找超时/回退/中间态处理
grep -rn "onSetPropertyTimeout\|CarPropertyTimeoutFlag\|needIntermediateState"4. 中文术语对照(读注释必备)
| 中文 | 含义 |
|---|---|
| 信号 / 车控 / 车辆属性 / 车控信号 | 同义,指 vehicle property |
| 上行信号 | get / 上报(车 → App) |
| 下行信号 | set / 下发(App → 车) |
| 信号上报 / 信号下发 / 订阅信号 | 描述收发动作 |
| 信号频率 | sample rate(configPropertyRate) |
| 中间态信号 | 有过渡态的信号(如车窗升降中),对应 CarPropertyTimeoutFlag.RESTART、needIntermediateState |
| 依赖信号 | 影响控制项 enable/loading 但不影响值的关联信号(needMapReceiveDependProperty、getSubDependPropertyId) |
| 保留信号值 | 当前车型暂不支持的预留值,UI 保持上一态(isValidPropVal、shouldUpdateUIByPropVal) |
| UI 先行 | 写信号前先更新本地缓存/Flow 让 UI 立即响应(CarPropertyRepo.setCarProperty 的 needEmit=true) |
| 下行信号与上行信号不一致 | 下发 id 与回读 id 不同,用 obtainSetPropertyId 处理 |
| 组合 areaId / 多 area | 同一 propId 不同区域(左/右座椅、左/右童锁),用 areaId 区分 |
5. 信号 ↔ UI 控件的数据驱动映射
5.1 页面级信号集合:*PropertysMap.java
每个业务页面有一个 Map 文件,声明该页关心的所有信号 ID。grep 命中 10 个:
| 文件 | 模块 |
|---|---|
settingsPage/micarLightSettings/.../LightsVehiclePropertysMap.java | 灯光 |
settingsPage/micarLockSettings/.../DoorVehiclePropertysMap.java | 车门 |
settingsPage/micarLockSettings/.../LockVehiclePropertysMap.java | 锁车 |
settingsPage/micarLockSettings/.../ElectricReleaseHeadGatePropertysMap.java | 电释放前备箱 |
settingsPage/micarSafetyServiceSettings/.../SafetyServiceVehiclePropertysMap.java | 安防 |
settingsPage/micarDrivingSettings/.../DrivingVehiclePropertyMap.java | 驾驶 |
settingsPage/micarDisplaySettings/.../DisplayVehiclePropertysMap.java + display/DisplayPropertyMap.kt | 显示 |
settingsPage/VehicleBodyControl/.../VehicleBodyPropertysMap.java + vehicle/VehicleBodyPropertyMap.kt | 车身 |
典型样子(LightsVehiclePropertysMap.java:12):
public static ArraySet<Integer> sExteriorLightPropertyIds = new ArraySet<>(
Arrays.asList(new Integer[]{
MiCarPropertyIds.LightCtrl.HEADLIGHT,
MiCarPropertyIds.LightCtrl.FOG
}));5.2 快捷控制项工厂:VehicleQuickCtrl
DoorVehiclePropertysMap.java 里展示了信号→图标→文案→Tab 标识→点击监听一条龙声明的快捷控制项:
return new VehicleQuickCtrl<Integer>(
Door.POWER_OPERATED_DOOR_MOVING_STATUS, VehicleAreaDoor.DOOR_ROW_1_LEFT,
R.drawable.micar_ic_driver_door, R.string.lock_door_driver_door_open) {
}.withDefault(CommonParams.OnOff.OFF)
.applyKeyGenStrategy(VehicleQuickCtrl.KEY_STRATEGY_PROPERTY_AND_AREA)
.withTabFlag(TAB_FLAG_DRIVER_DOOR)
.withAllowClickWhenDisabled(true)
.withOnClickListener(listener);5.3 信号值范围注解:@PropertyRange
base/settingsVehicleLib/src/main/java/com/android/micar/settings/annotation/PropertyRange.java
@Retention(RUNTIME) @Target(ElementType.TYPE)
public @interface PropertyRange {
int lower() default 0;
int upper() default 0;
int defaultVal() default -1;
int offset() default 0;
int stepValueForVoiceAssist() default 1;
}6. 信号的横切配置:VehiclePropertyConfig
⚠️ 注意包名:
com.android.micar.settings.carproperty(与 vehicle/ 目录下其它类的包名com.android.car.settings.miauto.vehicle不同,历史遗留)。
路径:base/settingsVehicleLib/src/main/java/com/android/micar/settings/carproperty/VehiclePropertyConfig.java
用 static {} 块维护 4 张表:
| 表 | 类型 | 作用 |
|---|---|---|
sSpecialSupportedPropValues | Map<Integer, List<Integer>> | 某信号支持的合法 value 白名单 |
sValuesShouldBeCached | Set | 哪些 value 应该缓存 |
sCustomTimeoutValue | Map<String, Long> | 每个信号下发后的超时时长 |
sTimeoutSignalMapping | Map<Integer, Integer> | 下行信号 → 上行信号映射(下发 ID 和上报 ID 不一致时,如 EnergyManagement.AC_CHARGING_CURRENT_MAX → ALL_CURRENT_STATUS) |
这 4 张表是处理”边界信号”的核心,新增信号功能时如遇下行/上行 ID 不一致、超时阈值异常,优先来这里配置。
7. 关键路径速查
| 你想做的事 | 看这里 |
|---|---|
| 找一个信号叫什么 | base/settingsBaseLib/.../vehicle/MiCarPropertyIds.java |
| 找信号的数字值 | mi.car.config.*(外部 jar,IDE 可跳转) |
| 新增信号常量 | 在 MiCarPropertyIds.java 对应内部类加一行 |
| 找某信号的读写者 | grep -rn "MiCarPropertyIds.Xxx.YYY" |
| 找超时/缓存配置 | base/settingsVehicleLib/.../carproperty/VehiclePropertyConfig.java |
| 找页面关心的信号集合 | settingsPage/<module>/.../*PropertysMap.java |
| 找读写 API | SettingsCarPropertyManager.kt(getXxxProperty / setCarProperty) |
| 找 UI 控件基类 | CarPropertyMgrPreferenceController.java |
| 找全局读信号 | GlobalCarPropertyManager.kt |
| 找 RTI(大数据流) | settingsCommon/rtiLib/.../rtilib/RTISignalMgr.java + 业务侧 RTISignalConstants.java |