3. 车身属性服务概述
在 Android Automotive 的软件栈中,应用层想要读取车速、空调温度、车门状态、座椅位置等车身信号,不能直接访问 CAN 总线或硬件寄存器,而必须经过一套标准化的属性访问框架。CarPropertyService(简称 CPS)正是这套框架的核心服务,它把底层 VehicleHal 暴露的原始属性,包装成可被 CarPropertyManager 调用的、带权限与订阅机制的 Java API。理解 CPS 的定义、作用以及它与 CarService、VehicleHal、CarPropertyManager 的关系,是后续所有车身属性开发的基础。
一、CarPropertyService 的定义
CarPropertyService 是运行在 CarService 进程中的一个系统服务(System Service),继承自 Android 的 Binder 服务模型,对外通过 ICarProperty AIDL 接口暴露能力。它的本质是一个“属性访问代理与治理层”:向上为应用提供 get/set/subscribe 三类操作,向下把请求翻译成 VehicleHal 的 HAL 调用,并在中间完成权限校验、区域(Area)解析、属性配置校验、订阅分发和速率控制。
从代码结构看,CPS 位于 packages/services/Car/service/src/com/android/car/hal/ 相关包中,核心类包括 CarPropertyService、PropertyHalService、VehicleHal 等。它并不直接持有硬件句柄,而是通过 VehicleHal 这一层与 vendor 实现的 HAL 交互。
二、CarPropertyService 的核心作用
CPS 的职责可以归纳为五个方面,它们共同构成了车身属性访问的完整闭环:
- 属性注册与配置管理:启动时从 VehicleHal 拉取所有支持的属性配置(PropertyConfig),包括属性 ID、数据类型、区域类型、访问权限、支持的速率等,形成属性能力清单。
- 权限与访问控制:根据属性的
access字段(READ / WRITE / READ_WRITE)和调用方 UID,判断是否允许读取或写入,防止普通应用越权控制车身。 - 区域(Area)解析:对于座椅、空调、车门等多区域属性,CPS 负责把 AreaId 映射到具体区域,并校验该属性是否支持对应区域。
- 订阅与事件分发:应用通过
registerCallback订阅属性变化,CPS 维护订阅列表,在属性值变化时按注册的速率回调给对应应用。 - 速率控制与去抖:通过
sampleRate控制属性上报频率,避免高频信号(如车速)无节制地冲击应用层。
三、与 CarService、VehicleHal、CarPropertyManager 的关系
这四个组件构成了车身属性访问的完整链路,理解它们的分工与调用方向,比记住类名更重要。下图展示了它们之间的层次与数据流关系:
从图中可以清晰看到四者的分工:
| 组件 | 所在层 | 核心职责 | 与 CPS 的关系 |
|---|---|---|---|
| CarPropertyManager | 应用框架层 | 面向应用的 API 封装,提供 get/set/registerCallback | CPS 的客户端代理,通过 Binder 调用 CPS |
| CarService | 系统服务层 | 车载系统服务容器,管理生命周期与权限 | CPS 的宿主进程,CPS 是其内部服务之一 |
| CarPropertyService | 系统服务层 | 属性治理:权限、区域、订阅、速率 | 核心中间层,连接 Manager 与 VehicleHal |
| VehicleHal | HAL 抽象层 | 与 vendor HAL 交互,缓存属性配置 | CPS 的下游依赖,提供原始属性读写 |
四、典型调用流程与代码示例
以“读取车速”为例,完整链路如下:应用调用 CarPropertyManager.getProperty(),Manager 通过 Binder 把请求发给 CarPropertyService;CPS 校验权限和属性配置后,调用 VehicleHal 的 get();VehicleHal 再通过 HIDL/AIDL 请求 vendor HAL,最终从 CAN 总线拿到车速并逐层返回。
// 应用侧:通过 CarPropertyManager 读取车速
CarPropertyManager mgr = (CarPropertyManager)
car.getCarManager(Car.PROPERTY_SERVICE);
// 车速属性:PERF_VEHICLE_SPEED,单位 m/s
float speed = mgr.getFloatProperty(
VehiclePropertyIds.PERF_VEHICLE_SPEED,
VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
// 订阅车速变化,采样率 1Hz
mgr.registerCallback(callback,
VehiclePropertyIds.PERF_VEHICLE_SPEED,
1000f); // sampleRateHz
写入类属性(如空调温度)则走 setProperty,CPS 会额外校验调用方是否具备 WRITE 权限,以及目标区域是否合法。若属性为只读,写入请求会被直接拒绝并记录日志。
五、常见误区与复盘
access 包含 READ,且 changeMode 支持 ON_CHANGE 或 CONTINUOUS,否则注册会失败。
adb shell dumpsys car_service 查看属性配置与订阅状态,再检查 vendor HAL 是否正常上报,能快速定位是权限、区域、速率还是底层信号的问题。
总结来说,CarPropertyService 是 Android Automotive 车身属性访问的中枢:它上承 CarPropertyManager 的应用请求,下接 VehicleHal 的硬件能力,并依托 CarService 进程完成权限与生命周期管理。掌握这四者的层次关系与数据流向,才能在后续的属性配置、订阅优化和问题排查中做到有的放矢。