Android Automotive CarService 和 CarManager 源码剖析

1. CarService 启动流程

1.1 CarServiceImpl 入口

CarService 是一个系统服务,在系统启动时由 System Server 启动。

文件位置: packages/services/Car/service/src/com/android/car/CarServiceImpl.java

java 复制代码
@Keep
public class CarServiceImpl extends ProxiedService {
    private ICarImpl mICarImpl;
    private VehicleStub mVehicle;

    @Override
    public void onCreate() {
        // 1. 获取 VehicleStub(连接 Vehicle HAL)
        mVehicle = VehicleStub.newVehicleStub();

        // 2. 构建 ICarImpl 核心实现
        mICarImpl = new ICarImpl.Builder()
                .setServiceContext(this)
                .setBuiltInContext(getBuiltinPackageContext())
                .setVehicle(mVehicle)
                .setSystemInterface(
                        SystemInterface.Builder.defaultSystemInterface(this).build())
                .setVehicleInterfaceName(mVehicle.getInterfaceDescriptor())
                .build();

        // 3. 初始化所有服务
        mICarImpl.init();

        // 4. 注册死亡监听,VHAL 崩溃时重启
        mVehicle.linkToDeath(mVehicleDeathRecipient);

        // 5. 注册到 ServiceManager,服务名为 "car_service"
        ServiceManagerHelper.addService("car_service", mICarImpl);
    }
}

启动流程:

复制代码
System Server 启动
    ↓
CarServiceImpl.onCreate()
    ↓
连接 Vehicle HAL
    ↓
创建 ICarImpl(包含所有子服务)
    ↓
初始化所有服务
    ↓
注册到 ServiceManager ("car_service")
    ↓
服务准备就绪,接受客户端请求

2. ICarImpl 核心实现

2.1 ICarImpl 架构

文件位置: packages/services/Car/service/src/com/android/car/ICarImpl.java

ICarImpl 是 CarService 的核心,实现了 ICar.aidl 接口,管理着 30+ 个子服务。

java 复制代码
public class ICarImpl extends ICar.Stub {

    // Vehicle HAL 抽象层
    private final VehicleHal mHal;

    // 核心服务
    private final CarOemProxyService mCarOemService;
    private final CarPropertyService mCarPropertyService;
    private final CarPowerManagementService mCarPowerManagementService;
    private final CarUserService mCarUserService;
    private final CarAudioService mCarAudioService;
    private final CarInputService mCarInputService;
    private final CarDrivingStateService mCarDrivingStateService;
    private final CarUxRestrictionsManagerService mCarUXRestrictionsService;
    private final CarOccupantZoneService mCarOccupantZoneService;
    private final CarPackageManagerService mCarPackageManagerService;
    // ... 更多服务

    // 所有服务的初始化顺序
    private final CarSystemService[] mAllServicesInInitOrder;
}

2.2 服务创建流程

ICarImpl 使用 Builder 模式创建所有服务:

java 复制代码
private ICarImpl(Builder builder) {
    List<CarSystemService> allServices = new ArrayList<>(40);

    // 1. 创建 VehicleHal(基础层)
    mHal = constructWithTrace(t, VehicleHal.class,
            () -> new VehicleHal(mContext, builder.mVehicle), allServices);

    // 2. 创建 CarPropertyService(依赖 VehicleHal)
    mCarPropertyService = constructWithTrace(
            t, CarPropertyService.class,
            () -> new CarPropertyService.Builder()
                    .setContext(mContext)
                    .setPropertyHalService(mHal.getPropertyHal())
                    .build(), allServices);

    // 3. 创建 CarDrivingStateService(依赖 CarPropertyService)
    mCarDrivingStateService = constructWithTrace(
            t, CarDrivingStateService.class,
            () -> new CarDrivingStateService(mContext, mCarPropertyService), allServices);

    // 4. 创建 CarUXRestrictionsService(依赖前述服务)
    mCarUXRestrictionsService = constructWithTrace(t, CarUxRestrictionsManagerService.class,
            () -> new CarUxRestrictionsManagerService(mContext, mCarDrivingStateService,
                    mCarPropertyService, mCarOccupantZoneService), allServices);

    // 5. 创建 CarAudioService
    mCarAudioService = constructWithTrace(t, CarAudioService.class,
            () -> new CarAudioService(mContext), allServices);

    // ... 创建其他 30+ 服务

    // 保存初始化顺序
    mAllServicesInInitOrder = allServices.toArray(new CarSystemService[allServices.size()]);
}

关键点:

  • 使用 constructWithTrace 包装,每个服务初始化都有性能追踪
  • 服务间通过构造函数传递依赖
  • 按依赖顺序创建,确保依赖服务先创建

2.3 init() 初始化流程

java 复制代码
@MainThread
void init() {
    // 1. 优先初始化关键服务(如果在构造中未执行)
    if (!mDoPriorityInitInConstruction) {
        priorityInit();
    }

    // 2. 按顺序初始化所有服务
    for (CarSystemService service : mAllServicesInInitOrder) {
        service.init();
    }

    // 3. 标记服务准备就绪
    ready();
}

priorityInit() - 优先初始化:

java 复制代码
private void priorityInit() {
    // VehicleHal 必须先初始化
    mHal.init();

    // CarUserService 需要早期初始化以设置启动用户
    mCarUserService.init();
}

3. CarManager 获取流程

3.1 Car 类入口

文件位置: packages/services/Car/car-lib/src/android/car/Car.java

应用通过 Car 类获取各种 Manager:

java 复制代码
// 创建 Car 实例
Car car = Car.createCar(context);

// 获取 CarAudioManager
CarAudioManager audioManager = car.getCarManager(CarAudioManager.class);

// 或通过服务名称获取(不推荐)
CarAudioManager audioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);

3.2 getCarManager 源码分析

java 复制代码
public Object getCarManager(String serviceName) {
    CarManagerBase manager;
    synchronized (mLock) {
        // 1. 检查 CarService 是否连接
        if (mService == null) {
            return null;
        }

        // 2. 从缓存获取
        manager = mServiceMap.get(serviceName);
        if (manager == null) {
            try {
                // 3. 向 CarService 请求服务 Binder
                IBinder binder = mService.getCarService(serviceName);
                if (binder == null) {
                    return null;
                }

                // 4. 创建 Manager 实例
                manager = createCarManagerLocked(serviceName, binder);

                // 5. 缓存 Manager
                mServiceMap.put(serviceName, manager);
            } catch (RemoteException e) {
                handleRemoteExceptionFromCarService(e);
            }
        }
    }
    return manager;
}

3.3 createCarManagerLocked - Manager 创建

java 复制代码
private CarManagerBase createCarManagerLocked(String serviceName, IBinder binder) {
    CarManagerBase manager = null;
    switch (serviceName) {
        case AUDIO_SERVICE:
            manager = new CarAudioManager(this, binder);
            break;
        case POWER_SERVICE:
            manager = new CarPowerManager(this, binder);
            break;
        case PROPERTY_SERVICE:
            manager = new CarPropertyManager(this, ICarProperty.Stub.asInterface(binder));
            break;
        case CAR_USER_SERVICE:
            manager = new CarUserManager(this, binder);
            break;
        case CAR_OCCUPANT_ZONE_SERVICE:
            manager = new CarOccupantZoneManager(this, binder);
            break;
        // ... 更多服务

        default:
            // 支持实验性服务,通过反射创建
            String className = mService.getCarManagerClassForFeature(serviceName);
            if (className != null) {
                manager = constructCarManager(className, binder);
            }
            break;
    }
    return manager;
}

4. CarManager 调用流程

4.1 完整调用链

以设置音频音量为例:

复制代码
应用层
    │
    │ CarAudioManager.setVolume(volume)
    ▼
CarManager (Client)
    │
    │ ICarAudio.setVolume(volume)  // AIDL 调用
    ▼
CarService (ICarImpl)
    │
    │ CarAudioService.setVolume(volume)
    ▼
CarAudioService 内部处理
    │
    │ PropertyHalService.setProperty()
    ▼
VehicleHal
    │
    │ VehicleStub.set()  // Binder 调用
    ▼
Vehicle HAL (厂商实现)
    │
    │ 硬件操作
    ▼
音频硬件

4.2 CarAudioManager 示例

文件位置: packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java

java 复制代码
public class CarAudioManager extends CarManagerBase {

    private final ICarAudio mService;

    public CarAudioManager(Car car, IBinder service) {
        super(car);
        mService = ICarAudio.Stub.asInterface(service);
    }

    public void setVolume(int groupId, int flags, int volumeIndex) {
        try {
            mService.setVolume(groupId, flags, volumeIndex);
        } catch (RemoteException e) {
            handleRemoteException(e);
        }
    }

    public int getVolume(int groupId) {
        try {
            return mService.getVolume(groupId);
        } catch (RemoteException e) {
            return handleRemoteExceptionAndReturn(e, /* defaultValue */ 0);
        }
    }
}

4.3 CarAudioService 实现

文件位置: packages/services/Car/service/src/com/android/car/audio/CarAudioService.java

java 复制代码
public class CarAudioService extends ICarAudio.Stub implements CarSystemService {

    private final PropertyHalService mPropertyHal;

    @Override
    public void setVolume(int groupId, int flags, int volumeIndex) {
        // 1. 权限检查
        enforcePermission();

        // 2. 查找音频组
        CarVolumeGroup volumeGroup = mCarAudio Zones.getVolumeGroup(groupId);

        // 3. 设置音量
        volumeGroup.setGainIndex(volumeIndex);

        // 4. 更新车辆属性
        int volumeProperty = getVolumePropertyForGroup(groupId);
        mPropertyHal.setIntProperty(volumeProperty, 0, volumeIndex);
    }

    @Override
    public int getVolume(int groupId) {
        // 1. 查找音频组
        CarVolumeGroup volumeGroup = mCarAudioZones.getVolumeGroup(groupId);

        // 2. 返回当前音量
        return volumeGroup.getGainIndex();
    }
}

5. VehicleHal 层

5.1 VehicleHal 架构

文件位置: packages/services/Car/service/src/com/android/car/hal/VehicleHal.java

VehicleHal 是与 Vehicle HAL 通信的抽象层。

java 复制代码
public class VehicleHal implements VehicleHalCallback, CarSystemService {

    // VehicleStub - 直接与 VHAL 通信
    private final VehicleStub mVehicleStub;

    // HAL 服务集合
    private final PowerHalService mPowerHal;
    private final PropertyHalService mPropertyHal;
    private final InputHalService mInputHal;
    private final UserHalService mUserHal;
    // ... 更多 HAL 服务

    // 属性处理器映射:PropertyId -> HalServiceBase
    private final SparseArray<HalServiceBase> mPropertyHandlers;

    // 所有支持的属性
    private final SparseArray<HalPropConfig> mAllProperties;
}

5.2 属性设置流程

java 复制代码
// 应用层调用
carPropertyManager.setIntProperty(PropertyId, areaId, value);

    ↓

// CarPropertyManager
mService.setIntProperty(propId, areaId, value);

    ↓

// CarPropertyService
public void setIntProperty(int propId, int areaId, int value) {
    // 1. 创建属性值
    HalPropValue propValue = mHal.getPropValueBuilder()
            .build(propId, areaId, value);

    // 2. 发送到 VehicleHal
    mHal.set(propValue);
}

    ↓

// VehicleHal
public void set(HalPropValue value) {
    int propId = value.getInt32(HalPropValue.HAL_PROP_ID);

    // 查找对应的 HAL 服务
    HalServiceBase handler = mPropertyHandlers.get(propId);
    if (handler != null) {
        handler.setProperty(value);
    }
}

    ↓

// PropertyHalService
public void setProperty(HalPropValue value) {
    // 发送到 VHAL
    mVehicleStub.set(value);
}

    ↓

// Vendor Vehicle HAL
// 厂商实现,操作硬件

5.3 事件订阅流程

java 复制代码
// 应用层注册回调
carPropertyManager.registerListener(callback, PropertyId, rateHz);

    ↓

// CarPropertyManager
mService.subscribeProperty(token, propId, rateHz);

    ↓

// CarPropertyService
public void subscribeProperty(int token, int propId, float rateHz) {
    HalSubscribeOptions options = new HalSubscribeOptions(propId, areaIds, rateHz);
    mHal.subscribe(options);
}

    ↓

// VehicleHal
public void subscribe(HalSubscribeOptions... options) {
    // 1. 分配处理器
    for (HalSubscribeOptions option : options) {
        HalServiceBase handler = findHandlerForProp(option.getHalPropId());
        mPropertyHandlers.put(option.getHalPropId(), handler);
    }

    // 2. 发送订阅到 VHAL
    mSubscriptionClient.subscribe(convertToSubscribeOptions(options));
}

    ↓

// VHAL 订阅

    ↓

// 属性变化事件回调
VehicleHal.onPropertyEvent(values)
    → handler.handleHalEvents(values)
    → CarPropertyService.notifyPropertyEvent()
    → ICarPropertyCallback.onEvent()
    → 应用层回调

6. 主要 CarManager 列表

Manager 服务名称 功能 必需/可选
CarAudioManager AUDIO_SERVICE 音频路由、音量控制 必需
CarPowerManager POWER_SERVICE 电源状态管理 必需
CarPropertyManager PROPERTY_SERVICE 车辆属性读写 必需
CarInputManager CAR_INPUT_SERVICE 输入事件处理 必需
CarUserManager CAR_USER_SERVICE 用户切换管理 必需
CarDrivingStateManager CAR_DRIVING_STATE_SERVICE 驾驶状态 必需
CarUxRestrictionsManager CAR_UX_RESTRICTION_SERVICE UX 限制 必需
CarOccupantZoneManager CAR_OCCUPANT_ZONE_SERVICE 乘员区域 必需
CarPackageManager PACKAGE_SERVICE 应用包管理 必需
CarHvacManager HVAC_SERVICE 空调控制 可选
CarCabinManager CABIN_SERVICE 车厢控制 可选
CarDiagnosticManager DIAGNOSTIC_SERVICE 诊断信息 可选
CarInstrumentClusterManager CAR_INSTRUMENT_CLUSTER_SERVICE 仪表盘 可选
CarEvsManager CAR_EVS_SERVICE 环视 可选

7. 常用调试命令

查看 CarService 状态

bash 复制代码
adb shell dumpsys car_service

查看特定服务

bash 复制代码
adb shell dumpsys car_service CarAudioService
adb shell dumpsys car_service CarPropertyService

查看 VHAL 属性

bash 复制代码
adb shell dumpsys android.hardware.automotive.vehicle.IVehicle/default

查看事件日志

bash 复制代码
adb logcat -b events | grep car

8. 总结

CarService 核心职责

  1. 管理所有汽车相关服务(30+ 个子服务)
  2. 提供 Binder 接口给客户端
  3. 与 Vehicle HAL 交互
  4. 处理车辆属性和事件

CarManager 核心职责

  1. 封装 Binder 通信细节
  2. 提供类型安全的 API
  3. 管理服务连接状态
  4. 缓存 Manager 实例

架构设计优点

  • 分层清晰:API -> Manager -> Service -> HAL
  • 模块化:每个服务独立,易于维护
  • 权限控制:在 Service 层统一检查权限
  • 性能优化:Manager 缓存,避免重复创建

关键文件位置

复制代码
Car API:         packages/services/Car/car-lib/
Car Service:     packages/services/Car/service/
VehicleHal:      packages/services/Car/service/src/com/android/car/hal/
Vehicle HAL:     hardware/interfaces/automotive/vehicle/

原文地址:
https://mp.weixin.qq.com/s/UzbVnzCaTFebyXgYulc7bQ

相关推荐
独隅2 小时前
PyTorch模型转TensorFlow Lite的Android部署全流程指南
android·pytorch·tensorflow
ganshenml2 小时前
Android 存储权限与文件系统演进全解析(Android 10 → 16)
android·gitee
seabirdssss2 小时前
从 Windows GUI 自动化到 Android 自动化:一套双端巡检脚本的重构过程
android·windows·自动化
winfredzhang2 小时前
Android中安装模拟器失败,清理安装失败的模拟器
android·清理·模拟器
ganshenml2 小时前
Android PopupWindow 在老年模式下定位偏移问题分析与解决(showAtLocation / 字体缩放 / 抖动)
android
summerkissyou19873 小时前
Android-SurfaceView-投屏-例子
android·surfaceview
Kapaseker3 小时前
我再也不用求设计做阴影了 — Compose 阴影
android·kotlin
Digitally3 小时前
6 种简单方法:在 Mac 电脑与安卓手机之间传输文件
android
鹏程十八少3 小时前
3. 2026金三银四 Android 背完这 23 道题,Android 线程面试横着走
android·面试·前端框架