06b - AAOS 官方 CarProperty 录制→JSON→重放工具链(专题深化)
本篇是 06 信号录制与回放 的深化,专攻**用户指定的”AAOS 公开 CarProperty 录制→JSON/CSV→重放”**工具链。基于 AOSP 源码(
JsonFakeValueGenerator、tools/emulator/、emu_metadata/)核实。调研方法:因模型周配额耗尽未启动子代理,改由主控用 WebSearch + GitHub Code Search 直接抓取 AOSP 源码镜像(LineageOS/android_hardware_interfaces 等)核实。
TL;DR
- AAOS 官方”重放”工具 =
JsonFakeValueGenerator:读一份 JSON 事件文件,由FakeVehicleHardware按时间戳回放 prop 变化。源码在automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/。 - AAOS 没有”录制”工具——官方只管”回放”(读 JSON),录制侧(订阅 prop 变化→生成 JSON)需自己写。这是最大缺口。
- AAOS 用 JSON,不用 CSV——没有官方 CSV 链路;CSV 需自写转换(JSON↔CSV 很简单)。
- 真机不可用:依赖
FakeVehicleHardware+ GeneratorHub,小米 vendor VHAL 没集成 → 仅 Cuttlefish/AAOS emulator 可用(见 04)。 - 配套工具:
tools/emulator/(vhal_emulator.py、diagnostic_injector.py JSON 注入、gui.py)+emu_metadata/(vehicle-types-meta.json 属性字典生成)。
1. 官方工具链全貌
┌─────────────────────────────────────┐
录制侧(自写 ⚠) │ 订阅 dumpsys/logcat/CarProperty 回调 │
│ → 记 (timestamp, propId, areaId, val)│
│ → 生成 JsonFakeValueGenerator JSON │
└───────────────┬─────────────────────┘
▼
replay.json(version + logs[])
│
┌───────────────▼─────────────────────┐
重放侧(官方 ✅) │ JsonFakeValueGenerator(C++) │
│ FakeVehicleHardware 读 JSON │
│ 按原始 timestamp 回放 prop 事件 │
│ → 经 IVehicle AIDL 扇出给订阅者 │
└─────────────────────────────────────┘
仅在 Cuttlefish / AAOS emulator / default VHAL 可用
2. JsonFakeValueGenerator——官方重放核心
2.1 源码位置
- AIDL(新):
hardware/interfaces/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp+include/JsonFakeValueGenerator.h - HIDL 2.0(老):
hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp - GitHub 镜像(可直接读):LineageOS/android_hardware_interfaces
2.2 原理(源码核实)
// 构造:传 JSON 文件路径 + 迭代次数
JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path, int32_t iteration) {
initWithPath(path, iteration); // 解析 JSON,按 timestamp 调度事件
}
// HIDL 老版从 VehiclePropValue 取路径:request.value.stringValue = JSON 路径- 解析 JSON 中的事件列表,按每个事件的
timestamp间隔调度,通过FakeVehicleHardware注入到 VHAL,再经IVehicleAIDL 扇出给所有订阅者(CarPropertyManager 全链路)。
2.3 JSON Schema(FakeVehicleHardware.cpp 源码注释权威定义)
{
"version": 1,
"logs": [
{
"timestamp": 1234567890, // 纳秒,事件发生时刻(相对开始)
"propId": 291504647, // 0x11400400 = PERF_VEHICLE_SPEED
"areaId": 0,
"valueType": "INT32_VEC", // 类型标识
"int32Values": [60] // 类型化值数组(int32/float/bytes/string...)
},
{
"timestamp": 1234667890,
"propId": 289408000, // CURRENT_GEAR
"areaId": 0,
"valueType": "INT32",
"int32Values": [4] // P 挡
}
]
}精确字段以
FakeVehicleHardware.cpp注释 “JSON content must be in the format…” 为准(每个事件propId/areaId/timestamp/valueType+ 类型化值数组int32Values/floatValues/bytes/stringValue)。
2.4 触发方式
通过 VHAL set 一个 controlling property(FakeVehicleHardware 注册的 kGenerateFakeDataControllingProperty),把 JSON 文件路径作为 stringValue 传入即启动回放:
# AIDL default VHAL(CF/emulator)
adb shell dumpsys android.hardware.automotive.vehicle.IVehicle/default \
--set <controlling_prop_id> -s /data/local/tmp/replay.json
# 或通过 vhal_emulator.py 编程触发controlling prop 的精确 ID 见
FakeVehicleHardware.cpp的kGenerateFakeDataControllingProperty常量;int32Values[1]可指定迭代次数。
3. tools/emulator/——host 端辅助工具集
源码:packages/services/Car/tools/emulator/(README)
| 工具 | 作用 | 与录制/重放关系 |
|---|---|---|
| vhal_emulator.py | host↔设备 VHAL socket(ADB 端口转发 + TCP),可编程 get/set | 编程触发回放 |
| vhal_const_generate.py | 从 types.hal 生成 propId/zone/类型字典(vhal_consts_2_0.py) | 给 JSON 填 propId 名字 |
| VehicleHalProto_pb2.py | VHAL emulator 的 protobuf 消息定义 | socket 通信协议 |
| ⭐diagnostic_injector.py | 反序列化 JSON → 诊断事件,经 HAL Emulator Interface 注入 | 官方”JSON→注入”现成例子 |
| diagnostic_builder.py | diagnostic_injector 的辅助类(VehiclePropValue 兼容) | — |
| diagjson.example | 诊断 JSON 格式样例(169KB) | JSON schema 参考 |
| gui.py | PyQt4 GUI,点按钮 set property | 无 GUI 痛点的官方原型 |
diagnostic_injector.py 用法(官方 JSON 注入例子):
./diagnostic_injector.py ./diagjson.example # 读 JSON → 注入诊断事件这是 AAOS 官方”JSON 描述事件 → 注入 VHAL”的最直接模板,可作为自写通用录制回放器的参照。
4. emu_metadata/——属性字典 JSON 生成
源码:hardware/interfaces/automotive/vehicle/aidl/emu_metadata/
| 文件 | 作用 |
|---|---|
generate_emulator_metadata.py | 从 AIDL 接口定义生成 VHAL 属性元数据 JSON |
vehicle-types-meta.json | 生成的产物——全量 propId + 元数据,驱动 emulator VHAL 窗口显示 |
用途:录制/回放的 JSON 里 propId 是数字,这个工具帮你把”AIDL 枚举名 → propId 数字”做映射,相当于 propId 字典生成器(小米自定义 prop 可仿照生成自己的字典)。官方文档:extend VHAL properties。
5. ⭐ 关键缺口与诚实结论
| 缺口 | 说明 | 对小米 |
|---|---|---|
| 无官方”录制”工具 | JsonFakeValueGenerator 只读 JSON(回放),录制侧(订阅 prop→生成 JSON)AAOS 没提供 | 必须自写录制脚本(见 §6) |
| 无 CSV 链路 | AAOS 全用 JSON;CSV 需自己 JSON↔CSV 转换(trivial) | CSV 仅作 Plotjuggler/Excel 中间格式 |
| 真机不可用 | 依赖 FakeVehicleHardware + GeneratorHub + SocketComm,小米 vendor VHAL 没集成 | 仅 Cuttlefish/emulator(04) |
| 无小米 vendor prop 字典 | JsonFakeValueGenerator JSON 要填 propId 数字,小米 3791 自定义 prop 无名字映射 | 用 generate_emulator_metadata.py 仿照生成小米字典 |
6. 对小米的可落地路径(完整方案)
6.1 录制侧(自写,核心缺口)
Python 脚本:订阅 prop 变化 → 生成 JsonFakeValueGenerator 格式 JSON:
# record_carprop.py(骨架)
# 数据源:adb logcat | grep MiCarPropertyService,解析 onPropertyChange 行
# 抓 (timestamp, mPropertyId, mAreaId, mValue)
import json, re, sys
events = []
for line in sys.stdin:
m = re.search(r'onPropertyChange.*mPropertyId=(0x[0-9a-f]+).*mAreaId=(0x[0-9a-f]+).*mTimestamp=(\d+).*mValue=(.+)', line)
if m:
events.append({
"timestamp": int(m.group(3)),
"propId": int(m.group(1), 16),
"areaId": int(m.group(2), 16),
"valueType": "INT32",
"int32Values": [parse_value(m.group(4))]
})
json.dump({"version": 1, "logs": events}, open("replay.json","w"), indent=2)
# 用法:adb logcat | python record_carprop.py这正是 06 §7 路径 A 的升级版——直接产出 AAOS 标准 JSON,可在 CF 上用官方 JsonFakeValueGenerator 回放。
6.2 回放侧(CF 上用官方机制)
- 把
replay.jsonpush 到 Cuttlefish:adb push replay.json /data/local/tmp/ - 触发 JsonFakeValueGenerator(set controlling property,传路径)
- CF 上的 MiCarSettings 收到信号 → 验证 UI
6.3 CSV 转换(可选,接 Plotjuggler)
JSON → CSV 一行命令,导给 Plotjuggler 画波形:
jq -r '.logs[] | [.timestamp, .propId, (.int32Values[0] // .floatValues[0] // "")] | @csv' replay.json > replay.csv7. 第三方对标
| 方案 | 定位 | 对小米 |
|---|---|---|
| RemotiveLabs | 商业云端录制回放(RemotiveCloud + Cuttlefish Bridge),Volvo/P3/Ford 在用 | 战略参考,08 |
| nkh-lab/aosp-ncar-vehicle-hal | GitHub 开源 AOSP VHAL 参考实现 | 自定义 VHAL 参考 |
| aesteve-rh/vhal_emulator | Rust 版 vhal_emulator | 替代语言实现 |
| Perfetto | trace VHAL IPC(录制调用链,非回放) | 调试用,不是回放 |
8. 源码索引(全部 GitHub 可读)
| 路径 | 作用 |
|---|---|
automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp | ⭐官方重放核心 |
automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp | JSON schema 注释 + controlling prop |
packages/services/Car/tools/emulator/ | host 工具集(vhal_emulator.py/diagnostic_injector.py/gui.py) |
hardware/interfaces/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py | propId 字典生成 |
| extend VHAL properties 官方文档 | JSON 元数据用法 |
| VHAL reference implementation | FakeVehicleHardware 架构 |
9. 一句话
AAOS 官方只给了”回放”(
JsonFakeValueGenerator读 JSON),没给”录制”;小米要补的就是自写录制脚本(解析 logcat → 生成标准 JSON),然后在 Cuttlefish 上用官方机制回放。CSV 不是 AAOS 路线,JSON 才是;要 CSV 仅作可视化中间格式。这条链路仅离线环境可用(真机 vendor VHAL 没集成 GeneratorHub),是 04 模拟器篇 Cuttlefish 底座上的一个具体应用。