02 - AAOS 官方 VHAL 工具链
AOSP
packages/services/Car+hardware/interfaces/automotive仓库里,Google 官方维护的 VHAL 调试/模拟/测试工具。结论先行:小米团队有一半官方能力没用足——尤其”按 prop 名字注入”和”错误码注入”,直接解决 P1(propId 难记)和 P6(异常状态难模拟),且零成本(纯 adb)。解决痛点:P1 propId 难记 / P2 areaId 语义 / P5 命令冗长 / P6 异常状态 / P7 难离车(部分)。
1. 先理清”分层”——决定每个工具能测什么
小米当前两类注入命令处在不同层级(01 篇 §2 已给表,这里展开原理):
App (CarPropertyManager)
↑ Binder
CarService (Java) ←─① inject-vhal-event 在这里"半路截胡"
↑ HAL binder
VHAL 进程 (IVehicle/micar) ←─② --mock_from_car 在这里
↑
vehiclecore → MCU/CAN
- ①
inject-vhal-event:在 CarService 内部直接调HalService.onPropertyChange,VHAL 进程本身不知道。能骗过所有 CarPropertyManager 订阅者,但测不了 VHAL 自身的订阅/回调逻辑。 - ②
--mock_from_car:在 VHAL 进程的dump()里注入,经过完整 HAL binder 扇出给 CarService。能测 VHAL→CarService 链路。
这条分层认知是后续选型的前提:测 App UI 任选其一;测 VHAL/vehiclecore 必须下沉到 ② 或更深。
2. cmd car_service 全家桶——小米没用足的官方命令
入口源码:packages/services/Car/service/src/com/android/car/CarShellCommand.java(4663 行)。小米 11 篇只记了 inject-vhal-event/publish-vhal-event,以下子命令都没用:
| 子命令 | 作用 | 注入层 | user 版 | 解决痛点 |
|---|---|---|---|---|
inject-vhal-event <名|ID> [area] <val> [-t delay] | 注入 VHAL 事件 | CarService | 否 | P1/P5 |
inject-error-event <名|ID> <area> <errorCode> | 注入错误事件 | CarService | 否 | P6 |
inject-continuous-events <ID> <val> [-s rate] [-d dur] | 按采样率持续注入 | CarService | 否 | 模拟连续信号 |
get-property-value <名|ID> [area] | 读 prop | HAL | 部分 | P1 |
set-property-value <名|ID> <area> <val> | 写 prop(走真实 HAL) | HAL | 部分 | — |
get-carpropertyconfig <名|ID> | 查 CarPropertyConfig | CarService | 是 | P2 |
list-vhal-props | 列所有 propId | CarService | 是 | P1 |
get-vhal-backend | AIDL/HIDL | CarService | 是 | P3 |
check-fake-vhal | 是否连 FakeVHAL | CarService | 是 | — |
emulate-driving-state [park|drive|reverse|neutral] | 驾驶态聚合注入(自动 inject 车速+挡位+手刹) | CarService | 否 | 场景编排 |
day-night-mode / garage-mode / silent-mode | 模式模拟 | CarService | 是 | 场景 |
3. ⭐ HalPropertyDebugUtils——告别 16 进制,按”名字”注入(解决 P1)
这是本次调研最高 ROI 的发现。CarShellCommand 里所有 propId 参数都走 decodePropertyId()(源码 HalPropertyDebugUtils.java):
private static int decodePropertyId(String propertyIdString) {
if (toPropertyId(propertyIdString) != null) // 先按名字查
return toPropertyId(propertyIdString).intValue();
return Integer.decode(propertyIdString); // 再按 16/10 进制
}AOSP 上可以这么写(不用背 0x1120040a):
adb shell cmd car_service inject-vhal-event ABS_ACTIVE 0 1
adb shell cmd car_service set-property-value HVAC_TEMPERATURE_SET ROW_1_LEFT 22.0
adb shell cmd car_service get-property-value PERF_VEHICLE_SPEED
adb shell cmd car_service inject-error-event SEAT_MEMORY_SELECT ROW_1_LEFT 2 # ERROR输出侧会打印 ABS_ACTIVE(0x1120040a) 这种**“名字(16进制)“双语格式**。
小米的缺口与对策
- 缺口:AOSP 的名字字典只覆盖 SYSTEM_PROPERTY;小米 vendor 私有 prop(
0x6xxxxxxx系列 3791 个)没有名字映射,仍要手填数字。 - 对策(高 ROI):推动 micar vendor VHAL 把自定义 propId 注册进
HalPropertyDebugUtils(或在 App 侧维护一份名字↔propId表,包一个micar-inject <名字> <值>脚本)。这一步做完,团队调试效率直接翻倍。 - 链接:
service/src/com/android/car/hal/property/HalPropertyDebugUtils.java(cs.android.com)
4. vhal_emulator.py——官方 Python 注入库(真机不可用,但设计可抄)
AOSP packages/services/Car/tools/emulator/ 维护的 Python 模块,从 host 通过 ADB 端口转发(固定端口 33452) 连设备端 DefaultVehicleHal 的 SocketComm,protobuf 收发。
# 官方唯一"一行代码模拟异常态"的工具
vhal.setProperty(prop, area_id, value, status=AVAILABLE) # status 可传 UNAVAILABLE/ERROR同目录还有:prop_event_simulator.py(按名字注入 CLI)、vhal_prop_simulator.py(持续模拟驾驶/用户事件)、driving_info_generator.py(GPX 轨迹回放为车信号)、gui.py(PyQt4 GUI,无 GUI 痛点的官方原型)。
致命局限:依赖设备端 VHAL 是 DefaultVehicleHal + FakeVehicleHardware 并开了 SocketComm。小米真机 vendor VHAL 是自研 micar,没开 SocketComm,直接用连不上 33452。真机不可用(除非改整机源码集成)。
值得抄的:setProperty(status=...) 这一行 API 设计——比小米 --mock_from_car --stat 0/1/2 用数字更清晰。自研 mock 工具时可借鉴。
5. FakeVehicleHardware + vhalconfig JSON(模拟器侧,详见 04 篇)
AOSP 默认 VHAL 的”假硬件”参考实现,用内存 map 存 prop 值。Android 14+ 支持零代码加自定义 prop:
# 放 /vendor/etc/automotive/vhalconfig/xiaomi.json 定义小米 3791 自定义 prop
# 无需改 VHAL 源码,CF/模拟器启动即支持
adb root && adb shell setprop persist.vendor.vhal_init_value_override 1 && adb reboot这是小米 3791 prop 落地到离线环境的载体,深度见 04 模拟器篇。
6. car-test-lib——应用层单测官方桩(详见 07 篇)
路径 packages/services/Car/libs/car-test-lib/(注意是 libs/ 下),提供 FakeCar/FakeCarPropertyService/CarPropertyController,纯 JVM 跑,给 Controller 补单测。是 P9(应用层难自动化测试)的官方解药之一,落地评估见 07 篇。
7. ⭐ 最被低估:Android 16 GRPCVehicleHardware——“插着真机但脱离 CAN 调试”
AOSP 16 给 IVehicleHardware 增加了 gRPC 远端实现(hardware/interfaces/automotive/vehicle/aidl/impl/grpc/):
真机 AAOS 的 VHAL 变成代理(proxy)
↓ gRPC
开发机上的 gRPC server(任意语言写信号源)
战略价值:让真机上的 VHAL 把 prop 请求转发给开发机的 gRPC server,实现**“插着真车机镜像、但完全脱离真实 CAN/MCU”调试**——比 vhal_emulator.py 的 SocketComm 现代得多,是 Google 官方的”云真机/信号源中心化”方向。
对小米:若升级到 Android 16 + 利用 newton/YU7 已有的多 VM 虚拟化,可在 host VM 跑一个 gRPC server 做开发期信号源,让 guest AAOS 的 VHAL 转发。建议单独立项评估升级 Android 16 的可行性——这可能比任何单点工具都更能根治”难脱离真车”(P7)。
- 链接:
hardware/interfaces/automotive/vehicle/aidl/impl/grpc/(source.android.com 虚拟化参考平台)
8. 小米落地结论
| 优先级 | 方案 | 解决痛点 | 门槛 | 行动 |
|---|---|---|---|---|
| TOP1 立刻做 | cmd car_service 按名字注入 + inject-error-event + emulate-driving-state | P1/P5/P6 | 纯 adb(userdebug) | 团队 SOP 从 --mock_from_car 切到 cmd car_service <名字>;推动 micar vendor prop 注册进 HalPropertyDebugUtils |
| TOP2 战略投入 | Android 16 GRPCVehicleHardware | P7 | 升级 A16 + 多 VM | 立项评估”真机代理 + 开发机信号源” |
| TOP3 应用层补强 | car-test-lib 给 Controller 补单测 | P9 | 加 gradle 依赖 | 见 07 篇 |
| 不推荐直接用 | vhal_emulator.py | — | 改整机源码 | 真机没 SocketComm,仅抄其 setProperty(status) 设计 |
与小米现有工具的对应关系
| 小米现有 | AOSP 官方对应 | 提升点 |
|---|---|---|
dumpsys car_service inject-vhal-event | (就是它本身) | 配 HalPropertyDebugUtils 后可按名字 |
dumpsys ...IVehicle/micar --mock_from_car | dumpsys ...IVehicle/default --set/--get | AOSP 版支持 --help + 名字,建议推动 micar dump 标准化 |
CarDemo4Test.apk | tools/emulator/gui.py + car-test-lib | 官方版可脱离设备/持续维护 |
LogPropMonitor.py | list-vhal-props + get-property-value | 官方版自带名字字典 |
附:AOSP 关键路径速查
| 路径 | 作用 |
|---|---|
packages/services/Car/service/src/com/android/car/CarShellCommand.java | cmd car_service 全部子命令源 |
packages/services/Car/service/src/com/android/car/hal/property/HalPropertyDebugUtils.java | propId 名字↔ID 互转 |
packages/services/Car/tools/emulator/ | vhal_emulator.py + 配套 |
packages/services/Car/libs/car-test-lib/src/android/car/testapi/ | FakeCar / FakeCarPropertyService |
hardware/interfaces/automotive/vehicle/aidl/impl/fake_impl/ | FakeVehicleHardware |
hardware/interfaces/automotive/vehicle/aidl/impl/default_config/config/ | 默认 prop JSON 字典 |
hardware/interfaces/automotive/vehicle/aidl/impl/grpc/ | Android 16 GRPCVehicleHardware |
device/google/cuttlefish/ | Cuttlefish 虚拟设备(见 04 篇) |