4. Android Automotive OS基础

Android Automotive OS(AAOS)不是把手机 Android 简单搬进车机,而是在标准 Android 框架之上叠加了一层面向车辆的扩展。理解 AAOS 的关键,是看清它如何把“应用层—框架层—车辆抽象层—车辆总线”串成一条可管控、可授权、可扩展的链路。本节围绕 AAOS 架构、Car API、CarAppService、CarPropertyManager 与权限模型展开,为后续 CarPropertyService 车身属性服务工程打下基础。

一、AAOS 分层架构与 Car API 的定位

AAOS 在传统 Android 架构中新增了 Car 相关模块。应用层通过 Car API 访问车辆能力;框架层由 CarService 统一调度;车辆抽象层通过 Vehicle HAL 与具体 ECU、CAN/LIN/以太网总线交互。Car API 是应用与车辆能力之间的“合同”,它把空调、车窗、座椅、灯光、里程、胎压等能力抽象为属性、动作和权限。

AAOS 分层架构与 Car API 调用链 应用层 Car App(导航/媒体/空调面板) · 系统设置 · 第三方应用 Car API 层 CarPropertyManager · CarAppService · CarInfoManager · CarUxRestrictions CarAudioManager · CarHvacManager · CarSensorManager 框架层 CarService CarPropertyService · CarPackageManagerService · CarPowerManagementService 权限校验 · 属性路由 · 订阅分发 · 状态缓存 车辆抽象层 Vehicle HAL VehicleProperty · VehicleArea · VehiclePropValue · 订阅回调 车辆总线与 ECU CAN / LIN / 以太网 · BCM · HVAC · 座椅模块 · 车窗模块 属性订阅/回调反向流

从图中可以看到,应用并不直接触碰 CAN 报文,而是通过 Car API 发起请求,由 CarService 做权限与路由,再经 Vehicle HAL 落到具体 ECU。这条链路决定了后续所有车身属性服务的实现方式。

二、CarAppService:车载应用的入口与模板约束

CarAppService 是 AAOS 为车载应用提供的专用服务入口。它继承自 androidx.car.app.CarAppService,通过 CarAppService 与 Session 管理应用与车机宿主(如 Launcher、Maps)之间的连接。与手机应用不同,车载应用不能随意绘制全屏界面,必须使用 Car App Library 提供的模板(Template),例如 NavigationTemplate、MapTemplate、PaneTemplate、MessageTemplate,以保证驾驶安全与交互一致性。

class MyCarAppService : CarAppService() {
    override fun onCreateSession(): Session {
        return MySession()
    }
}

class MySession : Session() {
    override fun onCreateScreen(intent: Intent): Screen {
        return MyScreen(carContext)
    }
}

CarAppService 的典型使用场景是导航、媒体、充电、停车等需要与车辆状态联动的应用。它解决的是“应用如何被车机安全地承载”,而 CarPropertyManager 解决的是“应用如何读取和写入车辆属性”,两者职责不同但常配合使用。

三、CarPropertyManager:车身属性的读写与订阅

CarPropertyManager 是应用访问车辆属性的核心 API。它通过属性 ID(如 HVAC_TEMPERATURE_SET、WINDOW_POS、DOOR_LOCK、PERF_VEHICLE_SPEED)读写车辆状态,并支持注册回调监听变化。属性由 VehiclePropertyIds 定义,区域由 VehicleArea 描述,例如左前、右前、后排、全部。

CarPropertyManager manager =
    (CarPropertyManager) car.getCarManager(Car.PROPERTY_SERVICE);

// 读取主驾空调温度
float temp = manager.getFloatProperty(
    VehiclePropertyIds.HVAC_TEMPERATURE_SET,
    VehicleAreaSeat.SEAT_ROW_1_LEFT);

// 订阅车窗位置变化
manager.registerCallback(callback,
    VehiclePropertyIds.WINDOW_POS,
    CarPropertyManager.SENSOR_RATE_ONCHANGE);

CarPropertyManager 的关键能力包括:同步读取、异步写入、订阅回调、权限校验。它并不直接操作硬件,而是把请求交给 CarPropertyService,由后者完成属性路由、区域匹配、权限检查与 HAL 调用。因此,理解 CarPropertyManager 必须同时理解权限模型。

四、权限模型:谁可以读写哪些车辆属性

AAOS 的权限模型比手机 Android 更严格。车辆属性通常属于敏感能力,应用必须在 AndroidManifest.xml 中声明对应权限,并在运行时获得授权。常见权限包括 android.car.permission.CAR_POWERTRAIN、CAR_HVAC、CAR_WINDOW、CAR_DOOR、CAR_SEAT、CONTROL_CAR_CLIMATE 等。系统应用与第三方应用的授权范围不同,部分属性仅对系统签名或特权应用开放。

属性/能力 典型权限 常见调用方 风险等级
HVAC_TEMPERATURE_SET android.car.permission.CAR_HVAC 空调面板、语音助手 中
WINDOW_POS android.car.permission.CAR_WINDOW 车窗控制、车身域应用 高
DOOR_LOCK android.car.permission.CAR_DOOR 门锁控制、远程车控 高
PERF_VEHICLE_SPEED android.car.permission.CAR_SPEED 仪表、导航、行车记录 中
SEAT_MEMORY_SELECT android.car.permission.CAR_SEAT 座椅记忆、个性化设置 中

常见误区:认为声明了权限就一定能读写属性。实际上,AAOS 还会校验调用方 UID、应用签名、是否为特权应用、属性是否支持当前区域,以及车辆是否处于允许操作的状态(如行驶中禁止调节座椅)。权限只是第一道门。

五、案例与排障:一次车窗属性写入失败的分析

假设某应用调用 setFloatProperty(WINDOW_POS, SEAT_ROW_1_LEFT, 0.5f) 失败。可按以下顺序排查:第一,检查是否声明并授予 CAR_WINDOW 权限;第二,确认属性 ID 与区域是否匹配,部分车型只支持整排区域;第三,查看 CarService 日志中是否有 Permission denied 或 Property not available;第四,确认 Vehicle HAL 是否已注册该属性;第五,检查车辆状态是否允许该操作。

adb shell dumpsys car_service | grep -i window
adb logcat | grep -i CarPropertyService
adb shell cmd car_service get-property 0x00000000

工程建议:在车身属性服务中,把“属性 ID + 区域 + 权限 + 当前车辆状态”作为一次完整校验单元,而不是只判断权限。这样能显著减少跨车型适配时的偶发失败。

综上,AAOS 通过分层架构把应用与车辆硬件解耦,Car API 提供统一访问入口,CarAppService 约束车载应用形态,CarPropertyManager 负责属性读写与订阅,权限模型则保证只有合适的调用方才能操作合适的车辆能力。这五者共同构成 CarPropertyService 车身属性服务工程的运行基础。