AAOS 整体架构分析 —— 基于 Android 14
说起来 AAOS(Android Automotive OS)跟咱们手机上用的 AOSP 虽然同根同源,但真要是做车载开发的,深入进去就会发现差别还是挺大的。车载场景下对稳定性、安全、多屏交互的要求跟手机完全不是一个量级。这篇文章就从 Android 14 的代码出发,把 AAOS 的整体架构掰开揉碎了聊一聊。
AAOS 和 AOSP 到底差在哪
先搞清楚一个基本问题:AAOS 本质上还是 Android,但它加了大量车载专属的 Service 和 HAL。
两者内核几乎一样,都是 Linux 内核 + Android 特有的一些驱动和机制(Binder、ashmem、ion 等)。真正的差别在上层:AAOS 多了一套车载专用的硬件抽象层(Vehicle HAL)、一套车载服务(CarService)、一堆车载应用(CarLauncher、CarSettings 等),以及一个完全不同的电源管理模型。
AOSP AAOS
┌──────────────────────┐ ┌──────────────────────────┐
│ Launcher / Dialer │ │ CarLauncher / CarUI │
│ (普通 Android App) │ │ (车载定制 App) │
├──────────────────────┤ ├──────────────────────────┤
│ System Server │ │ System Server │
│ (AMS/PMS/WMS...) │ │ (AMS/PMS/WMS...) │
├──────────────────────┤ ├──────────────────────────┤
│ │ │ CarService │
│ │ │ (车载业务中枢) │
├──────────────────────┤ ├──────────────────────────┤
│ AudioFlinger │ │ CarAudioService │
│ SurfaceFlinger │ │ + 多Display扩展 │
├──────────────────────┤ ├──────────────────────────┤
│ HAL (Camera/Audio) │ │ VHAL + 标准HAL │
├──────────────────────┤ ├──────────────────────────┤
│ Linux Kernel │ │ Linux Kernel │
│ + Android 驱动 │ │ + 车载CAN驱动 │
└──────────────────────┘ └──────────────────────────┘
AOSP 里的 system_server 管理着 ActivityManager、PackageManager 这些熟悉的 Service。而 AAOS 在 system_server 旁边又跑了一个独立的 CarService 进程,它是整个车载功能的中枢。两个进程通过 Binder 通信,CarService 会向 system_server 注册一些回调,但彼此是独立的。
从进程角度看一下启动流程:
init → Zygote → SystemServer (java)
├─ ActivityManagerService
├─ WindowManagerService
├─ PackageManagerService
└─ ... 其他 AOSP Service
└─ CarServiceHelperService (轻量级桥接)
└─ bind → CarService (独立的 com.android.car 进程)
├─ VehicleHal
├─ CarPropertyService
├─ CarAudioService
├─ CarPowerManagementService
├─ CarUserService
└─ ... 15+ 个子 Service
CarService 是怎么工作的
CarService 是一个 bound service,运行在 com.android.car 这个进程里。它的启动时机比普通应用早,但又在 system_server 之后。核心逻辑在 CarService.java 的 onStart() 方法里:
// packages/services/Car/service/src/com/android/car/CarService.java
public class CarService extends Service {
private static final String TAG = "CarService";
private final List<CarServiceBase> mServices = new ArrayList<>();
private VehicleHal mVehicleHal;
@Override
public void onCreate() {
super.onCreate();
mVehicleHal = new VehicleHal(this);
mServices.add(mVehicleHal);
mServices.add(new CarPropertyService(mVehicleHal));
mServices.add(new CarAudioService(this, mVehicleHal));
mServices.add(new CarInfoService(this, mVehicleHal));
mServices.add(new CarPowerManagementService(this, mVehicleHal));
mServices.add(new CarUserService(this));
mServices.add(new CarBluetoothService(this));
mServices.add(new CarInputService(this));
mServices.add(new CarPackageManagerService(this));
mServices.add(new CarDiagnosticService(this, mVehicleHal));
mServices.add(new CarDrivingStateService(this));
mServices.add(new CarProjectionService(this));
mServices.add(new CarMediaService(this));
mServices.add(new CarNavigationService(this));
mServices.add(new CarOccupantZoneService(this));
mServices.add(new CarStorageMonitoringService(this));
mServices.add(new CarTrustedDeviceService(this));
mServices.add(new CarWatchdogService(this));
// 按顺序初始化
for (CarServiceBase service : mServices) {
service.init();
}
}
}
这里有个细节:CarServiceBase 接口定义了 init() 和 release() 两个方法,初始化的顺序是按照 mServices 列表的顺序来的。VehicleHal 必须是第一个,因为后面的 Service 几乎都依赖它。
CAV (Car API) 暴露给上层应用的方式是通过 Car 这个 Binder 客户端。应用通过 Car.createCar() 拿到 Car 实例,再通过 getCarManager() 获取具体的管理器:
// 应用侧使用示例
Car car = Car.createCar(context);
if (car != null && car.isConnected()) {
CarAudioManager audioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);
CarInfoManager infoManager = (CarInfoManager) car.getCarManager(Car.INFO_SERVICE);
CarPropertyManager propManager = (CarPropertyManager) car.getCarManager(Car.PROPERTY_SERVICE);
// ...
}
这套接口跟 Android 原生的 Context.getSystemService() 很像,但走的完全是另一套 Binder 通道——应用在 com.android.car 进程这边,而 AOSP 的 Service 跑在 system_server 里。两者独立,但也有些桥接逻辑做了同步。
Vehicle HAL —— 连接 Android 和车的关键
VHAL(Vehicle HAL)是整个 AAOS 中最关键的一层。它抽象了车辆的所有属性(车速、车门状态、空调温度、续航里程等),每个属性用 VehicleProperty 来唯一标识。
HIDL 到 AIDL 的迁移
Android 14 的一个大变化是把 VHAL 从 HIDL 迁移到了 AIDL。之前 AAOS 从 Android 8 开始一直用 HIDL 定义车载属性接口,14 终于统一用 AIDL 了。这个迁移对上层影响不大,接口语义没变,但底层的 Binder 通信方式变了——HIDL 走的是 hwbinder,AIDL 走的是标准 binder。好处是以后 VHAL 的 debug 可以用标准的 Binder 工具(dumpsys、`binder’)来跟踪,不再需要单独的 hwservicemanager 那一套。
迁移前后对比一下:
Android 13 及之前: Android 14:
IVehicle.hal IVehicle.aidl
(hwbinder + hwservicemanager) (标准 binder)
VehicleHal.java VehicleHal.java
├─ connect HIDL service ├─ connect AIDL service
├─ getAllPropConfigs() ├─ getAllPropConfigs()
├─ get(...) ├─ get(...)
└─ set(...) └─ set(...)
VHAL 的核心接口
VHAL 的核心接口定义在 hardware/interfaces/automotive/vehicle/aidl/ 下:
// hardware/interfaces/automotive/vehicle/aidl/IVehicle.aidl
package android.hardware.automotive.vehicle;
interface IVehicle {
/**
* 获取所有支持的车载属性配置
*/
VehiclePropConfig[] getAllPropConfigs();
/**
* 读取某个属性的值
* @param prop 属性 ID
* @param areaId 区域 ID(比如左前车门、右前车门)
*/
VehiclePropValue get(VehiclePropStatus status, int prop, int areaId);
/**
* 设置某个属性的值
* @param value 要设置的值
* @return VehiclePropStatus 操作结果
*/
@nullable VehiclePropStatus set(VehiclePropValue value);
/**
* 订阅属性变化
* @param listener 回调接口
* @param subscriptions 订阅列表(属性 ID + 采样率)
* @param maximumNumberOfValues 每次回调最多带多少个值
*/
void subscribe(IVehicleCallback listener, SubscribeOptions[] subscriptions,
float maximumNumberOfValues);
/**
* 取消订阅
*/
void unsubscribe(IVehicleCallback listener, int[] propIds);
}
再看看 VehiclePropConfig 的结构:
// hardware/interfaces/automotive/vehicle/aidl/VehiclePropConfig.aidl
package android.hardware.automotive.vehicle;
parcelable VehiclePropConfig {
int prop; // 属性 ID,比如 VEHICLE_SPEED = 0x11200200
int access; // 访问模式:读(0x01) / 写(0x02) / 读写(0x03)
int changeMode; // 变化通知模式
int[] areaConfigs; // 区域配置(支持多个 instance 的属性)
int[] configArray; // 厂商自定义配置
String minSampleRate; // 最小采样率
String maxSampleRate; // 最大采样率
}
数据流的完整链路
一次典型的属性读取流程:
CarPropertyManager.getProperty(VEHICLE_SPEED, areaId)
│
▼
CarPropertyService (com.android.car 进程内)
│ Binder AIDL 调用
▼
VehicleHal.java (CarService 内的封装层)
│ Socket / 共享内存 / Vendor RPC
▼
VHAL 实现 (OEM 提供,C++ 进程)
│
▼
CAN/Ethernet Driver → ECU → 车辆传感器
反过来属性变化通知的链路:
车辆传感器 → ECU → CAN Bus
│
▼
VHAL 实现 (C++ native 进程)
│ 调用 IVehicleCallback.onPropertyEvent()
▼
VehicleHal.java
│ 通过 CarService 内部回调
▼
CarPropertyService
│ 调用 callback 或 broadcast
▼
应用层 onPropertyChangedListener
Android 14 对这条链路的优化是在 VHAL 到 CarService 之间加了一层缓冲——VehicleHal 会维护一个变化缓存队列,批量上报属性变化,减少了 Binder 调用的次数。之前高频率的属性(比如车速,每秒可能变化几十次),每个变化都发一个回调会占满 Binder 线程池。
常见的 VehicleProperty
AAOS 预定义了一千多个 VehicleProperty,常用的有这些:
// hardware/interfaces/automotive/vehicle/aidl/VehicleProperty.aidl
const int VEHICLE_SPEED = 0x11200200; // 车速
const int ENGINE_RPM = 0x11200300; // 发动机转速
const int FUEL_LEVEL = 0x11400400; // 油量/电量百分比
const int DOOR_POS = 0x11500500; // 车门状态
const int HVAC_TEMPERATURE_SET = 0x15400600; // 空调设定温度
const int HVAC_FAN_SPEED = 0x16400700; // 空调风速
const int GEAR_SELECTION = 0x11800800; // 档位
const int PARKING_BRAKE_ON = 0x11600900; // 手刹状态
const int TIRE_PRESSURE = 0x11400A00; // 胎压
属性 ID 的编码规则:
0xAA BB CC DD
AA = 区域类型(01=全局, 11=座位, 15=车门, 16=车窗)
BB = 属性大类(12=运动信息, 14=能源, 15=车身, 16=HVAC)
CC = 属性小类
DD = 序号
音频架构 —— 比手机复杂太多了
手机上的音频架构很简单:谁会发声,谁拿到 AudioFocus 就行。但车里完全不一样——导航声、电话声、音乐声、警告声,每个都有自己的优先级和区域策略。
一来车里可能同时有好几个人在听不同的内容,二来有些音频(比如倒车雷达告警)优先级极高,必须能打断所有其他音频。
┌─────────────────────────────────────┐
│ AudioPolicyManager │
│ (AOSP 的音频策略引擎) │
└──────────┬──────────────────────────┘
│
┌──────────▼──────────────────────────┐
│ CarAudioService │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ Zone 1 │ │ Zone 2 │ │
│ │ 驾驶位 │ │ 副驾 │ │
│ │ MUSIC │ │ MUSIC/VIDEO │ │
│ │ NAV │ │ │ │
│ │ CALL │ │ │ │
│ └──────────┘ └──────────────────┘ │
└──────────┬──────────────────────────┘
│
┌──────────▼──────────────────────────┐
│ AudioFlinger │
│ (混音 + 输出路由) │
└──────────┬──────────────────────────┘
│
┌───────────┼───────────────┐
▼ ▼ ▼
bus_device_1 bus_device_2 bus_device_3
(驾驶位扬声器) (副驾耳机) (后座扬声器)
CarAudioService
CarAudioService 负责管理音频策略,它比 AOSP 的 AudioService 多了车特有的概念:
Audio Zone——车里不同座位算不同的 zone,每个 zone 有自己的音频策略。Android 14 支持最多 8 个 zone。
Context——音频的上下文类型,定义在 CarAudioContext 里:
// packages/services/Car/car-lib/src/android/car/media/CarAudioContext.java
public static final int INVALID = -1;
public static final int MUSIC = 0; // 媒体播放
public static final int NAVIGATION = 1; // 导航播报
public static final int VOICE_COMMAND = 2; // 语音助手
public static final int CALL = 3; // 电话
public static final int ALARM = 4; // 闹钟
public static final int NOTIFICATION = 5; // 通知
public static final int SYSTEM_SOUND = 6; // 系统音效
public static final int EMERGENCY = 7; // 紧急告警
public static final int SAFETY = 8; // 安全提示(安全带、车门未关)
public static final int VEHICLE_STATUS = 9; // 车辆状态音(转向灯)
public static final int ANNOUNCEMENT = 10; // 语音播报
每个 Context 有固定的优先级高低,EMERGENCY > SAFETY > CALL > NAVIGATION > MUSIC。CarAudioService 在处理 AudioFocus 时会先根据 Context 决定优先级,同 Context 内才走 AOSP 标准的那套 focus 逻辑。
Android 14 的 CarAudioService 改用了 AudioManager.setPreferredDeviceForZone 来控制每个 zone 的输出设备:
// packages/services/Car/service/src/com/android/car/audio/CarAudioService.java
private void setupZoneDevices() {
AudioManager audioManager = getSystemService(AudioManager.class);
for (CarAudioZone zone : mCarAudioZones) {
for (CarAudioContext context : zone.getAllContexts()) {
AudioDeviceInfo device = zone.getDeviceForContext(context);
if (device != null) {
audioManager.setPreferredDeviceForZone(
zone.getId(), device, context.getAudioAttributes()
);
}
}
}
}
音频配置
OEM 通过 car_audio_configuration.xml 来定义音频拓扑。Android 14 把这个文件的格式也重构了,跟 AOSP 的 audio_policy_configuration.xml 做了合并:
<!-- packages/services/Car/service/res/values/car_audio_configuration.xml -->
<carAudioConfiguration version="2">
<zones>
<!-- 驾驶位 Zone -->
<zone name="driver" volumeGroupNumber="1" occupantZoneId="0">
<deviceHolder busNumber="1" address="bus_device_1">
<contexts>
<context context="MUSIC" />
<context context="NAVIGATION" />
<context context="CALL" />
<context context="SAFETY" />
</contexts>
</deviceHolder>
</zone>
<!-- 副驾 Zone -->
<zone name="passenger" volumeGroupNumber="2" occupantZoneId="1">
<deviceHolder busNumber="2" address="bus_device_2">
<contexts>
<context context="MUSIC" />
<context context="VOICE_COMMAND" />
</contexts>
</deviceHolder>
</zone>
</zones>
<!-- 音量分组,每组单独的音量曲线 -->
<volumeGroups>
<group name="driver_group">
<context context="MUSIC" />
<context context="NAVIGATION" />
<context context="CALL" />
</group>
<group name="passenger_group">
<context context="MUSIC" />
<context context="VOICE_COMMAND" />
</group>
</volumeGroups>
</carAudioConfiguration>
volumeGroupNumber 控制哪些 Context 共用一个音量滑块。比如驾驶位的 MUSIC 和 NAVIGATION 可能是独立控制的,而副驾可能只用同一路音量。
多屏显示
AAOS 的多屏方案跟平板的扩展屏完全是两码事。车内每个屏幕可能承担完全不同的功能:仪表盘显示车速和警告,中控屏做导航和设置,副驾屏看视频,后座屏打游戏。
Android 14 的 AAOS 多屏主要依赖这几个机制:
Display Policy
在 device_generic/car/display_settings.xml 里配置每块屏的类型和分辨率:
<!-- device/generic/car/display_settings.xml -->
<displaySettings>
<!-- 中控屏(主屏) -->
<displaySetting port="0" type="MAIN">
<config width="1920" height="720" density="160" />
<config width="1280" height="720" density="120" />
</displaySetting>
<!-- 仪表盘 -->
<displaySetting port="1" type="CLUSTER">
<config width="1920" height="360" density="120" />
<config width="1280" height="240" density="80" />
</displaySetting>
<!-- 副驾屏 -->
<displaySetting port="2" type="AUXILIARY">
<config width="1280" height="720" density="160" />
</displaySetting>
</displaySettings>
CLUSTER 类型就是给仪表盘用的。系统会为它单独创建一个 Display 实例,不走普通的 Activity 启动流程。仪表盘上跑的是一个定制版的 SystemUI,只渲染车速、转速、故障灯这些必要信息,不加载第三方应用。
多屏 HAL
Android 14 用 AIDL 的 IComposer 来实现多屏能力:
// hardware/interfaces/graphics/composer/aidl/IComposer.aidl
interface IComposer {
Display createDisplay(DisplayAttribute attr);
boolean updateDisplay(Display display);
void destroyDisplay(int64_t displayId);
// ...
}
每块物理屏幕对应一个 Display Id(从 0 开始编号)。WindowManager 会在 onDisplayAdded 时创建对应的 DisplayContent,然后走标准的 WMS 窗口管理逻辑。
有一点容易踩坑:不同屏幕之间的触摸事件是独立的。AAOS 用 InputDevice 来区分触摸源,每块屏幕对应不同的 InputDevice。WMS 会根据触摸事件携带的 deviceId 和 displayId 把事件路由到对应的窗口。Android 14 在 InputDispatcher 里给这块加了 trace log,可以通过 adb shell dumpsys input 看到每个事件的完整路由路径。
屏幕拓扑示意:
┌─────────────────────────┐
│ 仪表盘 (CLUSTER) │
│ 1920x360, density 120 │
│ Display ID: 1 │
│ Input Device: /dev/input/event1 │
│ 只运行 ClusterSystemUI │
└─────────────────────────┘
┌─────────────────────────────────┐
│ 中控屏 (MAIN) │
│ 1920x720, density 160 │
│ Display ID: 0 │
│ Input Device: /dev/input/event0│
│ 运行所有 App │
└─────────────────────────────────┘
┌───────────────────┐
│ 副驾屏 (AUX) │
│ Display ID: 2 │
│ 运行多媒体应用 │
└───────────────────┘
电源管理
车载电源状态跟手机完全不一样。手机只有关机、休眠、唤醒三种状态,车里要考虑的多了去了:
- ACC ON:车通了电但没发动
- Engine ON:发动机/电机启动了
- ACC OFF:熄火了但系统还在跑(比如还在导航)
- SHUTDOWN:彻底关机
- SLEEP:深度休眠,但可以被唤醒(比如遥控开车门)
Android 14 的 CarPowerManagementService 重写了状态机:
// packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
public enum CarPowerState {
STATE_OFF(0, "OFF"),
STATE_ON(1, "ON"),
STATE_SHUTDOWN_ONLY(2, "SHUTDOWN_ONLY"),
STATE_SUSPEND(3, "SUSPEND"),
STATE_SLEEP(4, "SLEEP"),
STATE_SHUTDOWN_PREPARE(5, "SHUTDOWN_PREPARE"),
}
// 状态转换的主逻辑
private void handlePowerStateChange(CarPowerState newState) {
switch (newState) {
case STATE_SHUTDOWN_PREPARE:
// 1. 通知所有 Service 准备关闭
notifyServices(CarPowerPolicy.SHUTDOWN_PREPARE);
// 2. 等待异步关闭完成(有超时)
waitForShutdownCompletion(SHUTDOWN_TIMEOUT_MS);
// 3. 写日志
writeShutdownLog();
break;
case STATE_SUSPEND:
// 1. 保存 Display 状态
// 2. 挂起 SurfaceFlinger
// 3. 通知 VHAL 进入休眠
suspendHardware();
break;
case STATE_SLEEP:
// 低功耗模式,网络和大部分外设关闭
// 只保持 CAN 总线唤醒能力
enterSleepMode();
break;
}
}
Android 14 新增了 STATE_SHUTDOWN_ONLY 状态,用于 OTA 升级后的强制重启场景。这个状态下不会进入 SUSPEND 或 SLEEP,直接走完整关机流程。
安全与权限
AAOS 的安全模型在 AOSP 基础上加了不少车载专有的东西。
SELinux 策略
CarService 跑在独立的 car_service domain 里,策略文件在 system/sepolicy/prebuilts/api/34.0/private/car_service.te:
type car_service, domain;
type car_service_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(car_service)
# 允许访问 VHAL
allow car_service vehicle_hal:fd use;
allow car_service vehicle_hal:binder { call transfer };
# 允许读写车载属性数据库
allow car_service car_data_file:dir create_dir_perms;
allow car_service car_data_file:file create_file_perms;
# 不允许访问网络(CarService 不需要直接联网)
neverallow car_service self:udp_socket *;
neverallow car_service self:tcp_socket *;
注意那个 neverallow——CarService 进程默认没有任何网络访问权限。如果 OEM 需要在 CarService 里加联网逻辑(比如远程控车),得单独申请权限审查。
Car 权限系统
AAOS 有自己的一套权限系统,定义在 packages/services/Car/car-lib/ 里:
// packages/services/Car/car-lib/src/android/car/permission/CarPermissionManager.java
public class CarPermissionManager {
// 车载专用权限列表
public static final String CONTROL_CAR_INFO =
"android.car.permission.CAR_CONTROL_INFO";
public static final String CONTROL_AUDIO_VOLUME =
"android.car.permission.CAR_CONTROL_AUDIO_VOLUME";
public static final String CONTROL_ENERGY =
"android.car.permission.CAR_CONTROL_ENERGY";
public static final String CONTROL_ENERGY_PORTS =
"android.car.permission.CAR_CONTROL_ENERGY_PORTS";
public static final String CONTROL_ENGINE =
"android.car.permission.CAR_CONTROL_ENGINE";
public static final String CONTROL_SPEED =
"android.car.permission.CAR_CONTROL_SPEED";
public static final String CONTROL_HVAC =
"android.car.permission.CAR_CONTROL_HVAC";
public static final String CONTROL_CLUSTER_DISPLAY =
"android.car.permission.CAR_CONTROL_CLUSTER_DISPLAY";
// 检查权限
public boolean checkCarPermission(String permission) {
return mContext.checkCallingPermission(permission)
== PackageManager.PERMISSION_GRANTED;
}
}
Android 14 把这些权限的检查点从 CarService 下沉到了 VHAL 层。以前是 CarService 的每个方法里手动 checkCallingPermission,现在 VHAL 的 set() 方法会检查调用方的权限,粒度更细了。
Android 14 的其他重要变化
除了上面重点聊的几个,Android 14 在 AAOS 方向上还有几个值得关注的改动:
数字钥匙框架
Android 14 开始支持数字车钥匙框架(Digital Car Key),用的是 UWB + BLE 来做近场通信和测距。这套框架在 packages/services/Car/car-key/ 下:
frameworks/base/car-key/
├── aidl/
│ └── android/car/key/
│ ├── ICarKey.aidl
│ └── ICarKeyCallback.aidl
├── src/
│ └── android/car/key/
│ ├── CarKeyManager.java
│ └── CarKeyService.java
需要说明的是,它只是个框架层抽象,具体加密协议和认证流程让 OEM 自己实现。Google 在参考实现里用的是 Android Ready SE 的安全元件,但 OEM 也可以用自己选的 eSE 芯片。
Projection API
Android 14 改进了 CarProjectionManager,投屏帧率更可控,丢帧检测也加了系统日志。这层是给 Android Auto 无线连接用的底层 API,App 层直接用不到,但做系统集成的会接触到。
多用户
Android 14 的 CarUserService 完善了多用户切换的体验。车是共享设备,不同驾驶员有不同的配置(座椅位置、空调偏好、导航历史)。Android 14 改进了用户切换时 App 的状态保存和恢复——之前很多 App 在切换用户后会崩溃(因为没处理好 onConfigurationChange),14 里加了更严格的兼容性检测。
总结
AAOS 本质上是在 AOSP 的基础上,为了车载场景做了一整套横跨应用、框架、HAL、内核的扩展:
| 层级 | AOSP | AAOS 扩展 |
|---|---|---|
| 应用层 | Launcher, Settings | CarLauncher, CarSettings, ClusterUI |
| 框架层 | SystemServer, WMS, AMS | CarService (15+ 子 Service) |
| 音频 | AudioFlinger, AudioPolicy | CarAudioService, Zone, Context |
| 显示 | SurfaceFlinger, WMS | 多 Display Policy, Cluster |
| 硬件抽象 | HAL (Camera/Audio) | VHAL (AIDL, 1000+ 属性) |
| 权限 | Android Permissions | Car 专属权限 + SELinux 策略 |
| 电源 | PowerManager | CarPowerManagement (Sleep/Suspend/Off) |
VHAL 是数据通路,CarService 是业务中枢,音频和多屏是最复杂的两个子系统。Android 14 的主要变化体现在 AIDL 迁移、电源状态机重构、权限模型下沉到 VHAL 这几个方向。
说实话车载 Android 开发的坑不少,很多问题只能靠实际调试和读源码才能解决。如果这篇文章能让入门的同学少走点弯路,那就值了。


被折叠的 条评论
为什么被折叠?



