2. AAOS架构与座舱定制

Android Automotive OS(AAOS)并不是把手机 Android 简单搬进车机,而是在 AOSP 基础上引入了一整套面向车辆的分层扩展。理解这套架构的关键,是分清“谁负责感知车辆、谁负责把车辆能力变成 App 可用的 API、谁负责在座舱里调度多屏多用户”。本节围绕系统架构、Vehicle HAL、CarService、CarApp 与座舱多屏多用户特性展开,帮助你在定制座舱平台时知道每一层该改什么、不该改什么。

一、AAOS 的分层架构

从下往上看,AAOS 大致分为五层。最底层是车辆硬件与 ECU,包括车身控制器、动力、空调、灯光等,它们通过 CAN、LIN、FlexRay 或车载以太网对外暴露信号。往上一层是 Vehicle HAL(VHAL),它是 AAOS 与车辆之间的唯一标准接口,把原始总线信号抽象成属性(Property)。再往上是 CarService 及其配套的 CarManager API,它把 VHAL 属性、电源状态、驾驶状态、用户与显示信息统一封装,供上层调用。第四层是 CarApp 与系统应用,例如 Car Launcher、Settings、Media、HVAC 等。最上层是 OEM 定制应用与第三方应用。

这套分层最重要的价值是“隔离”:应用不直接读 CAN,而是通过 CarService 暴露的 API 获取车辆状态;OEM 更换总线或 ECU 时,只需重写 VHAL 实现,上层应用基本不动。因此定制座舱时,改动通常集中在 VHAL 与 CarService 的配置,而不是去改应用。

AAOS 座舱平台分层架构与数据流 应用层 OEM 定制 App | 第三方 App | Car Launcher | Settings | Media | HVAC CarApp / Car API 层 CarAppService | CarActivity | CarPropertyManager | CarUxRestrictions | CarUserManager CarService 层 CarPropertyService | CarPowerManagementService | CarOccupantZoneService CarUxRestrictionsService | CarDrivingStateService | CarUserService Vehicle HAL (VHAL) VehicleProperty | get/set/subscribe | PropertyConfig | AreaId | 属性权限与访问控制 车辆硬件与总线 ECU | CAN / LIN / FlexRay | 车载以太网 | 车身 / 动力 / 空调 / 灯光信号 数据流方向:总线信号 → VHAL 属性 → CarService 服务 → Car API → 应用 UI 定制重点:VHAL 属性映射、CarService 配置、多屏多用户 Zone 划分,而非修改应用层

二、Vehicle HAL:车辆能力的抽象入口

VHAL 是 AAOS 与车辆之间的契约。它把车辆能力抽象为“属性”,每个属性由 VehicleProperty 标识,并带有类型、访问权限、区域(AreaId)和配置信息。例如空调温度可以定义为 HVAC_TEMPERATURE_SET,区域用 VehicleAreaSeat 区分主驾、副驾、后排;车窗用 WINDOW_POS 配合 VehicleAreaWindow 区分左前、右前等。

VHAL 对外提供三类操作:get 读取当前值,set 下发控制,subscribe 订阅变化。属性还分为静态属性(如 INFO_VIN、INFO_MAKE)和动态属性(如车速、挡位、温度)。静态属性在启动时读取一次,动态属性需要持续上报。实现 VHAL 时,OEM 通常基于 AOSP 的参考实现,把 CAN 信号映射到属性,并处理信号周期、去抖和超时。

一个常见的教学示例是车速属性 PERF_VEHICLE_SPEED:假设总线以 100ms 周期发送车速,VHAL 收到后更新属性值,CarService 订阅该属性并广播给需要的应用。若总线信号丢失超过 500ms,VHAL 应上报无效值或触发故障,而不是继续沿用旧值,否则会影响驾驶限制判断。

三、CarService:座舱能力的调度中枢

CarService 是运行在系统进程中的核心服务,它把 VHAL 属性、电源、驾驶状态、用户和显示信息统一管理,并通过 Binder 向应用暴露 Car API。几个关键服务值得关注:

  • CarPropertyService:封装 VHAL 属性,提供 CarPropertyManager 给应用读写和订阅。
  • CarPowerManagementService:管理点火状态、休眠、关机流程,协调各服务在电源状态切换时的行为。
  • CarUxRestrictionsService:根据驾驶状态生成 UX 限制,例如行驶中禁止视频、限制列表项数量。
  • CarOccupantZoneService:管理乘员区域与显示器的映射,是多屏多用户的基础。
  • CarUserService:管理多用户生命周期,包括用户创建、切换和与区域的绑定。

定制座舱时,CarService 的配置通常通过 config.xml 和 car_config.xml 完成,例如定义哪些属性可被哪些应用访问、哪些区域对应哪些显示、驾驶状态如何映射到 UX 限制。理解这些配置,比直接改代码更安全,也更容易在升级 AOSP 时保持兼容。

四、CarApp:面向座舱的应用形态

CarApp 是 AAOS 上应用的特殊形态。它通过 CarAppService 声明自己是车载应用,使用 CarActivity 或模板化 UI 来适配驾驶场景。CarApp 不直接操作 VHAL,而是通过 CarPropertyManager、CarUxRestrictionsManager 等 API 获取车辆状态和限制。

例如一个 HVAC 应用,需要读取 HVAC_TEMPERATURE_SET 和 HVAC_FAN_SPEED,并根据 CarUxRestrictions 决定是否允许复杂交互。CarApp 的 UI 通常遵循“驾驶时简化、停车时丰富”的原则,这与手机应用的设计思路明显不同。

五、座舱多屏多用户特性

座舱与手机最大的差异之一,是“多屏多用户”。一辆车可能有中控屏、副驾屏、后排娱乐屏和仪表屏,不同屏幕可能属于不同乘员区域,甚至对应不同用户。AAOS 通过 CarOccupantZoneService 把显示器、音频设备、用户和区域关联起来。

典型配置中,主驾区域绑定中控屏和仪表屏,副驾区域绑定副驾屏,后排区域绑定后排屏。每个区域可以有自己的用户,用户切换时,该区域的应用状态、音频焦点和显示内容随之切换。实现时需要注意:区域划分要与硬件实际连接一致;音频输出要按区域路由;用户切换不能影响驾驶相关服务。

多屏多用户调试时,建议先确认 CarOccupantZoneService 中每个 Zone 的 display、audio 和 user 映射是否正确,再检查应用是否按 Zone 获取上下文。很多“屏幕内容串了”或“音频跑到别的屏”的问题,根源都在 Zone 配置。

六、定制实践中的判断依据

当你拿到一个座舱定制需求时,可以按以下顺序判断改动位置:如果需求是“新增一个车辆信号”,优先改 VHAL 属性映射和 CarService 配置;如果需求是“行驶中限制某个操作”,改 CarUxRestrictions 配置或应用内判断;如果需求是“副驾屏独立播放”,检查 CarOccupantZone 和音频路由;如果需求是“不同用户不同桌面”,检查 CarUserService 与 Launcher 的用户绑定。这样分层定位,能避免把问题都堆到应用层。

AAOS 的架构价值在于“分层解耦、标准接口、可配置扩展”。掌握 VHAL、CarService、CarApp 与多屏多用户这四块,就掌握了座舱定制的核心路径。