2. Android Automotive 基础

Android Automotive OS(AAOS)并不是“把手机 Android 装进车机”那么简单。它在标准 Android 框架之上,增加了车辆硬件抽象层(VHAL)、车辆属性(Vehicle Property)、CarService、Car API 以及面向驾驶场景的权限模型。理解 AAOS 的架构分层、系统分区职责、应用模型差异,以及车辆属性如何与权限安全绑定,是后续做权限裁剪、变体适配和安全加固的前提。

一、AAOS 架构分层:从应用到底层车辆总线

AAOS 的架构可以自上而下分为五层:应用层、Car API 与框架层、CarService 与车辆属性服务层、VHAL 层、车辆总线与 ECU 层。应用不直接访问 CAN、LIN 或以太网,而是通过 Car API 请求 CarService,再由 CarService 通过 VHAL 与车辆通信。VHAL 是 Android 与车辆硬件之间的标准化接口,通常以 AIDL 或 HIDL 形式实现,由 OEM 或 Tier1 提供。

这种分层带来的核心安全价值是:权限检查点集中在框架与 CarService 层,应用无法绕过 CarService 直接读写车辆信号。因此,车辆属性的访问控制、权限映射和变体配置,最终都落在 CarService 与 VHAL 的边界上。

AAOS 架构分层与车辆属性权限链路 应用层 系统应用 / 第三方应用 / 车载 Launcher / 媒体与导航应用 权限声明:AndroidManifest carPermission / 签名权限 Car API 与框架层 CarPropertyManager / CarUxRestrictions / CarPackageManager / 权限校验入口 CarService 与车辆属性服务层 CarPropertyService / 属性权限映射 / 变体配置 / 区域与速率限制 config.xml 属性白名单 vendor 权限映射表 VHAL 车辆硬件抽象层 IVehicle AIDL / get、set、subscribe / 属性 ID 与区域 / 回调与事件 车辆总线与 ECU 层 CAN / LIN / FlexRay / 车载以太网 / 车身、动力、空调、ADAS 控制器 权限链路:应用声明权限 → Car API 校验 → CarService 属性映射 → VHAL 执行 → 车辆总线响应

二、系统分区:权限与安全的物理边界

AAOS 沿用 Android 的分区模型,但车载场景对分区职责有更严格的要求。常见分区包括:system(AOSP 框架与系统应用)、vendor(OEM 定制、VHAL 实现、车辆配置)、product(产品差异化应用与配置)、odm(ODM 定制)、data(用户数据与运行时状态)。其中,vendor 分区承载 VHAL 与车辆属性配置,是权限映射的关键落点。

分区边界直接决定 SELinux 策略与权限授予范围。例如,只有 vendor 或 system 分区的应用才可能被授予 signature|privileged 级别的车辆权限;第三方应用即使声明了 android.car.permission.CAR_POWERTRAIN,也会因签名或特权级别不匹配而被拒绝。

关键结论:车辆权限不是“声明即得”,而是由分区归属、签名级别、特权应用白名单和 CarService 属性映射共同决定。

三、应用模型:与手机 Android 的差异

AAOS 的应用模型在权限、生命周期和用户交互上与手机 Android 有明显差异。下表列出主要区别:

维度 手机 Android Android Automotive OS
权限类型 运行时权限为主 签名权限、特权权限、车辆属性权限并存
车辆数据访问 无统一车辆 API 通过 CarPropertyManager 与 VHAL 访问
驾驶限制 无 CarUxRestrictions 限制驾驶中交互
应用安装来源 应用商店、侧载 以预装与 OEM 商店为主,侧载受限
多用户与多屏 单用户为主 多用户、多显示区域、乘客屏隔离

这意味着在 AAOS 上做权限安全,不能只依赖运行时权限弹窗,而必须结合签名权限、特权白名单和 CarService 的属性级控制。

四、车辆属性与权限安全的关系

车辆属性(Vehicle Property)是 AAOS 中车辆数据的抽象单位,每个属性有唯一 ID、数据类型、访问模式(读/写/订阅)和区域(Zone)。CarService 在启动时加载属性配置,并将每个属性映射到对应的权限。例如:

// 属性权限映射示例(简化)
VehicleProperty.PERF_VEHICLE_SPEED
  → android.car.permission.CAR_SPEED

VehicleProperty.HVAC_TEMPERATURE_SET
  → android.car.permission.CONTROL_CAR_CLIMATE

VehicleProperty.GEAR_SELECTION
  → android.car.permission.CAR_POWERTRAIN

VehicleProperty.DOOR_LOCK
  → android.car.permission.CONTROL_CAR_DOORS

当应用调用 CarPropertyManager.getProperty() 或 setProperty() 时,CarService 会先检查调用方是否持有对应权限,再检查属性是否在变体配置中启用,最后才转发给 VHAL。任何一环不通过,都会抛出 SecurityException 或返回错误码。

常见误区:认为“只要在 AndroidManifest 中声明了车辆权限就能读写属性”。实际上,签名权限需要平台签名,特权权限需要放入 /system/priv-app 或 /vendor/priv-app,且属性本身还必须在 CarService 的配置中启用。

五、案例:车速属性的权限链路复盘

假设一个第三方应用尝试读取车速。其调用链如下:

  1. 应用声明 android.car.permission.CAR_SPEED,但未使用平台签名。
  2. 应用调用 CarPropertyManager.getProperty(PERF_VEHICLE_SPEED)。
  3. CarService 检查权限:该权限为 signature|privileged,第三方应用不满足。
  4. CarService 抛出 SecurityException,VHAL 不会被调用。

如果该应用是 OEM 预装且使用平台签名,则权限检查通过,CarService 继续检查属性是否在变体配置中启用,最后通过 VHAL 读取 CAN 信号并返回。这个案例说明:车辆属性的安全边界由“权限 + 签名 + 分区 + 属性配置”四层共同构成。

六、方法流程:从属性到权限的排查步骤

在实际项目中,遇到车辆属性访问失败时,可按以下流程排查:

  1. 确认属性 ID 与访问模式是否正确。
  2. 检查应用是否声明了对应车辆权限。
  3. 检查应用签名级别与安装分区是否满足权限要求。
  4. 检查 CarService 配置中该属性是否启用、是否绑定正确权限。
  5. 检查 VHAL 实现是否支持该属性,以及车辆总线是否返回有效值。
  6. 查看 logcat 中 CarPropertyService 与 SecurityException 相关日志。
adb logcat -s CarPropertyService:V CarService:V AndroidRuntime:E
adb shell dumpsys car_service --properties
adb shell cmd car_service get-property-config