跳转至

Android 15 CarService源码03-服务及接口

服务介绍

Android 原生的 CarService 是一个功能丰富的服务框架,作为 C/S 模式中的服务端,承担了关键的中间桥梁作用。它通过与 HAL 层的 VehicleHAL 通信,进一步借助车载总线(如 CAN 总线)与车身硬件进行交互,实现对车辆硬件的控制与状态获取。同时,CarService 还通过 Car API(如 Car**Manager,C/S 模式中的客户端)向应用层提供标准化接口,使 Car App 能够方便地实现车身控制和状态显示功能。

以下列举 CarService 中所有的服务:

Java服务 Native服务 Stub SDK 功能
CarOemProxyService - - - 负责与OEM特定功能的交互。
SystemActivityMonitoringService - - - 监控系统活动状态。
CarPowerManagementService PowerHalService ICarPower.Stub CarPowerManager 管理车辆的电源状态和策略。
CarPackageManagerService - ICarPackageManager.Stub CarPackageManager 管理车辆相关的软件包。
CarInputService InputHalService ICarInput.Stub CarInputManager 处理车辆的输入事件,如按钮和开关。
CarDrivingStateService - ICarDrivingState.Stub CarDrivingStateManager 管理和监控车辆的驾驶状态。
CarUxRestrictionsManagerService - ICarUxRestrictionsManager.Stub CarUxRestrictionsManager 管理用户体验限制,确保驾驶安全。
OccupantAwarenessService - IOccupantAwarenessManager.Stub OccupantAwarenessManager 监控车内乘客的状态和活动。
CarAudioService - ICarAudio.Stub CarAudioManager 管理车辆的音频系统。
CarProjectionService - ICarProjection.Stub CarProjectionManager 处理手机与车机的投影功能。
CarPropertyService PropertyHalService ICarProperty.Stub CarPropertyManager 访问和管理车辆属性。
CarNightService - - - 管理车辆的夜间模式。
AppFocusService - IAppFocus.Stub CarAppFocusManager 管理应用程序的焦点状态。
FixedActivityService - - - 管理固定活动的状态。
GarageModeService - - - 管理车辆的车库模式。
ClusterNavigationService - IInstrumentClusterNavigation.Stub - 管理仪表盘导航显示。
InstrumentClusterService - - - 管理仪表盘功能。
CarLocationService - - - 管理车辆的位置信息。
CarBluetoothService - - - 管理车辆的蓝牙连接。
CarPerUserServiceHelper - - - 提供用户相关的服务帮助。
CarDiagnosticService DiagnosticHalService ICarDiagnostic.Stub CarDiagnosticManager 提供车辆诊断信息。
CarStorageMonitoringService - ICarStorageMonitoring.Stub CarStorageMonitoringManager 监控车辆存储状态。
CarMediaService - ICarMedia.Stub CarMediaManager 管理车辆的媒体播放。
CarUserService UserHalService ICarUserService.Stub CarUserManager 管理车辆用户信息。
ExperimentalCarUserService - IExperimentalCarUserService.Stub ExperimentalCarUserManager 实验性的用户服务功能。
ExperimentalCarKeyguardService - IExperimentalCarKeyguardService.Stub - 实验性的钥匙管理功能。
CarOccupantZoneService - ICarOccupantZone.Stub CarOccupantZoneManager 管理车内乘客区域。
CarUserNoticeService - - - 管理用户通知。
VmsBrokerService - IVmsBrokerService.Stub - 管理车辆的VMS(车辆管理系统)。
CarBugreportManagerService - ICarBugreportService.Stub CarBugreportManager 管理车辆的错误报告。
CarStatsService - - - 管理车辆的统计信息。
CarExperimentalFeatureServiceController - - - 管理实验性功能控制。
CarWatchdogService - ICarWatchdogService.Stub CarWatchdogManager 监控车辆系统的健康状态。
CarPerformanceService - ICarPerformanceService.Stub CarPerformanceManager 管理车辆的性能监控。
CarDevicePolicyService - ICarDevicePolicyService.Stub CarDevicePolicyManager 管理车辆的设备策略。
ClusterHomeService ClusterHalService IClusterHomeService.Stub ClusterHomeManager 管理仪表盘主页显示。
CarEvsService EvsHalService ICarEvsService.Stub CarEvsManager 管理车辆的EVS(增强视觉系统)。
CarTelemetryService - ICarTelemetryService.Stub CarTelemetryManager 管理车辆的遥测数据。
CarActivityService - ICarActivityService.Stub CarActivityManager 管理车辆的活动状态。
CarOccupantConnectionService - ICarOccupantConnection.Stub CarOccupantConnectionManager 管理车内乘客的连接状态。
CarRemoteDeviceService - ICarRemoteDevice.Stub CarRemoteDeviceManager 管理车辆的远程设备连接。
CarWifiService - ICarWifi.Stub CarWifiManager 管理车辆的WiFi连接。
CarRemoteAccessService - ICarRemoteAccessService.Stub CarRemoteAccessManager 管理车辆的远程访问功能。

在 Android 15 中,我列举了所有的服务。由于目前对这个模块还不熟悉,有些对应的 stub 和 manager 尚未找到,但我会持续更新这个表格。接下来,我们将从客户端的角度开始分析,如何调用服务中的接口。

客户端

如何使用

Car car = Car.createCar(mContext);  
CarPowerManager carPowerManager = (CarPowerManager) car.getCarManager(Car.POWER_SERVICE);  
int powerState = carPowerManager.getPowerState();

如上,创建新的 Car 对象,并通过 Car 对象获取到对应的 CarXXXManager,即可调到对应的服务接口。

Car.createCar()

// packages/services/Car/car-lib/src/android/car/Car.java

/**
 * 汽车 API,适用于 Android Automotive OS 部署。
 * 该 API 仅适用于具有 {@link PackageManager#FEATURE_AUTOMOTIVE} 特性的设备。
 * 在不具备此特性的设备上调用此 API 将导致异常。
 */
public final class Car implements ICarBase {

    /**
     * @deprecated 建议使用 {@link #createCar(Context, Handler)}。
     */
    @Deprecated
    public static Car createCar(Context context, ServiceConnection serviceConnectionListener,
            @Nullable Handler handler) {
    }

    /**
     * @deprecated 建议使用 {@link #createCar(Context, Handler)}。
     */
    @Deprecated
    public static Car createCar(Context context, ServiceConnection serviceConnectionListener) {
    }

    /**
     * 创建新的 {@link Car} 对象,该对象同步连接到汽车服务并准备使用。
     *
     * <p>使用此方法创建的实例在传入的 {@code Context} 释放之前,应通过调用
     * {@link #disconnect()} 从汽车服务断开连接。
     *
     * @param context 应用程序的上下文
     *
     * @return 如果操作成功,则返回 Car 对象,否则返回 null。
     */
    @Nullable
    public static Car createCar(Context context) {
        // 使用 CarBuilder 创建一个新的 Car 实例
        return new CarBuilder().createCar(context);
    }

    /**
     * 创建新的 {@link Car} 对象,该对象同步连接到汽车服务并准备使用。
     *
     * <p>使用此方法创建的实例在传入的 {@code Context} 释放之前,应通过调用
     * {@link #disconnect()} 从汽车服务断开连接。
     *
     * @param context 不能为 {@code null}。如果传入 {@link ContextWrapper},
     *                请确保其 {@link ContextWrapper#getBaseContext() base context} 也不为 {@code null}。
     *                否则将抛出 {@link java.lang.NullPointerException}。
     * @param handler 用于执行管理器回调的处理器,如果为 null,则在应用程序的主线程上执行。
     *
     * @return 如果操作成功,则返回 Car 对象,否则返回 null。
     */
    @Nullable
    public static Car createCar(Context context, @Nullable Handler handler) {
        // 使用 CarBuilder 创建一个新的 Car 实例,并指定 handler
        return new CarBuilder().createCar(context, handler);
    }

    /**
     * 创建新的 {@link Car} 对象,并附带 {@link CarServiceLifecycleListener}。
     *
     * <p>使用此方法创建的实例在传入的 {@code Context} 释放之前,应通过调用
     * {@link #disconnect()} 从汽车服务断开连接。
     *
     * <p>如果在此调用中汽车服务已准备好,并且调用者在主线程中运行,
     * 则会调用 {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)},
     * 并将 ready 设置为 true。否则,将稍后从主线程调用
     * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)}。</p>
     *
     * <p>此调用最多可以阻塞指定的 waitTimeoutMs 时间,以等待汽车服务准备好。
     * 如果汽车服务未在给定时间内准备好,它将返回一个处于断开状态的 Car 实例。
     * 永久阻塞主线程可能导致系统杀死应用程序(应用程序无响应,ANR),
     * 如果应用程序需要在汽车服务崩溃/重启后继续运行,则不应使用这种方式。
     * 如果应用程序在汽车服务准备好之前无法执行任何操作,它仍然有用。
     * 在任何等待中,如果线程被中断,它将立即返回。</p>
     *
     * <p>注意,当有有限的超时时间时,返回的 {@link Car} 对象不保证已连接。
     * 无论返回的汽车是否已连接,建议在
     * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} 中实现所有汽车相关的初始化,
     * 并避免需要检查返回的 {@link Car} 是否已连接。</p>
     *
     * @param context 不能为 {@code null}。如果传入 {@link ContextWrapper},
     *                请确保其 {@link ContextWrapper#getBaseContext() base context} 也不为 {@code null}。
     *                否则将抛出 {@link java.lang.NullPointerException}。
     * @param handler 将所有 Car*Manager 事件分派到此处理器。
     *                例外情况是 {@link CarServiceLifecycleListener},它将始终分派到主线程。
     *                传递 null 将导致所有 Car*Manager 回调也分派到主线程。
     * @param waitTimeoutMs 设置为 {@link #CAR_WAIT_TIMEOUT_DO_NOT_WAIT} 将确保 API 根本不等待汽车服务。
     *                      设置为 {@link #CAR_WAIT_TIMEOUT_WAIT_FOREVER} 将永远阻塞调用,直到汽车服务准备好。
     *                      设置任何正值将被解释为超时时间。
     */
    @NonNull
    public static Car createCar(@NonNull Context context,
            @Nullable Handler handler, long waitTimeoutMs,
            @NonNull CarServiceLifecycleListener statusChangeListener) {
        // 使用 CarBuilder 创建一个新的 Car 实例,指定 handler、超时时间和生命周期监听器
        return new CarBuilder().createCar(context, handler, waitTimeoutMs, statusChangeListener);
    }

}

Warning

createCar(Context, ServiceConnection, Handler)createCar(Context, ServiceConnection) 是已弃用的方法,用于创建 Car 实例。

可以使用createCar(Context)createCar(Context, Handler) 获取对象,也可以使用 createCar(Context, Handler, long, CarServiceLifecycleListener) 来指定等待超时时间和生命周期监听器。 这三个方法最终都是利用 CarBuilder 来创建 Car 实例。

CarBuilder.createCar()

// packages/services/Car/car-lib/src/android/car/Car.java

/**
 * 汽车 API,适用于 Android Automotive OS 部署。
 * 该 API 仅适用于具有 {@link PackageManager#FEATURE_AUTOMOTIVE} 特性的设备。
 * 在不具备此特性的设备上调用此 API 将导致异常。
 */
public final class Car implements ICarBase {

    /**
     * 注册到服务管理器的汽车服务的 Binder 服务名称。
     *
     * @hide
     */
    @VisibleForHiddenApiCheck
    public static final String CAR_SERVICE_BINDER_SERVICE_NAME = "car_service";


    /**
     * 一个包装类,围绕 {@code createCar} 函数,允许在测试中注入依赖。
     *
     * @hide
     */
    @VisibleForTesting
    public static final class CarBuilder {

        /**
         * 我们在此类中访问的服务管理器函数。
         */
        public interface ServiceManager {
            /** 检查 {@link ServiceManager#getService(String)} */
            IBinder getService(String name);
        }

        // 默认的服务管理器实现,使用 ServiceManagerHelper 获取服务
        private ServiceManager mServiceManager = new ServiceManager() {
            @Override
            public IBinder getService(String name) {
                return ServiceManagerHelper.getService(name);
            }
        };

        /**
         * 设置用于测试的假服务管理器。
         */
        public CarBuilder setServiceManager(ServiceManager serviceManager) {
            mServiceManager = serviceManager;
            return this;
        }

        /**
         * 参见 {@link Car#createCar}。
         */
        public Car createCar(Context context) {
            return createCar(context, (Handler) null);
        }

        /**
         * 参见 {@link Car#createCar}。
         */
        public Car createCar(Context context, @Nullable Handler handler) {
            // 确保 context 不为 null
            assertNonNullContext(context);
            Car car = null;
            IBinder service = null;
            boolean started = false;
            int retryCount = 0;
            while (true) {
                // 尝试获取 car_service
                service = mServiceManager.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
                if (car == null) {
                    // 即使 service 为空,构造函数也是安全的
                    car = new Car(context, ICar.Stub.asInterface(service),
                            null /*serviceConnectionListener*/, null /*statusChangeListener*/,
                            handler);
                }
                if (service != null) {
                    if (!started) {  // 最常见的情况:服务已准备好
                        car.startCarService();
                        return car;
                    }
                    break;
                }
                if (!started) {
                    car.startCarService();
                    started = true;
                }
                retryCount++;
                if (retryCount > CAR_SERVICE_BINDER_POLLING_MAX_RETRY) {
                    Slog.e(TAG_CAR, "无法获取 car_service,等待时间(毫秒):"
                                    + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS
                                    * CAR_SERVICE_BINDER_POLLING_MAX_RETRY,
                            new RuntimeException());
                    return null;
                }
                try {
                    Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
                } catch (InterruptedException e) {
                    Slog.e(CarLibLog.TAG_CAR, "等待 car_service 时被中断",
                            new RuntimeException());
                    return null;
                }
            }
            // 可以从主线程中的 mServiceConnectionListener 访问
            synchronized (car.mLock) {
                if (car.mService == null) {
                    car.mService = ICar.Stub.asInterface(service);
                    Slog.w(TAG_CAR,
                            "等待 car_service(毫秒):"
                                    + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS * retryCount,
                            new RuntimeException());
                }
                car.mConnectionState = STATE_CONNECTED;
            }
            return car;
        }

        /**
         * 参见 {@link Car#createCar}。
         */
        @NonNull
        public Car createCar(@NonNull Context context,
                @Nullable Handler handler, long waitTimeoutMs,
                @NonNull CarServiceLifecycleListener statusChangeListener) {
            // 确保 context 和 statusChangeListener 不为 null
            assertNonNullContext(context);
            Objects.requireNonNull(statusChangeListener);
            Car car = null;
            IBinder service = null;
            boolean started = false;
            int retryCount = 0;
            long maxRetryCount = 0;
            if (waitTimeoutMs > 0) {
                maxRetryCount = waitTimeoutMs / CAR_SERVICE_BINDER_POLLING_INTERVAL_MS;
                // 至少等待一次,如果它是正值
                if (maxRetryCount == 0) {
                    maxRetryCount = 1;
                }
            }
            boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
            while (true) {
                // 尝试获取 car_service
                service = mServiceManager.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
                if (car == null) {
                    // 即使 service 为空,构造函数也是安全的
                    car = new Car(context, ICar.Stub.asInterface(service), null,
                            statusChangeListener, handler);
                }
                if (service != null) {
                    // 最常见的情况:服务已准备好
                    if (!started) {
                        car.dispatchCarReadyToMainThread(isMainThread);
                        car.startCarService();
                        return car;
                    }
                    break;
                }
                if (!started) {
                    car.startCarService();
                    started = true;
                }
                retryCount++;
                if (waitTimeoutMs < 0 && retryCount >= CAR_SERVICE_BINDER_POLLING_MAX_RETRY
                        && retryCount % CAR_SERVICE_BINDER_POLLING_MAX_RETRY == 0) {
                    Slog.w(TAG_CAR, "car_service 未准备好,等待时间(毫秒):"
                                    + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
                            new RuntimeException());
                } else if (waitTimeoutMs >= 0 && retryCount > maxRetryCount) {
                    if (waitTimeoutMs > 0) {
                        Slog.w(TAG_CAR, "car_service 未准备好,等待时间(毫秒):"
                                        + waitTimeoutMs,
                                new RuntimeException());
                    }
                    return car;
                }

                try {
                    Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    Slog.w(TAG_CAR, "中断", new RuntimeException());
                    return car;
                }
            }
            // 可以从主线程中的 mServiceConnectionListener 访问
            synchronized (car.mLock) {
                Slog.w(TAG_CAR,
                        "等待 car_service(毫秒):"
                                + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
                        new RuntimeException());
                if (car.mService != null) {
                    return car;
                }
                car.mService = ICar.Stub.asInterface(service);
                car.mConnectionState = STATE_CONNECTED;
            }
            car.dispatchCarReadyToMainThread(isMainThread);
            return car;
        }
    }
}

CarBuilder 是一个内部类,用于创建 Car 实例。提供了多种 **createCar** 重载方法来创建 Car 实例。 如果服务不可用,方法会重试多次,直到达到最大重试次数或服务可用;如果服务在重试后仍不可用,方法将返回 null 或部分初始化的 Car 实例。

这里通过 ServiceManager 获取的 CAR_SERVICE_BINDER_SERVICE_NAME 也就是car_service ,在前面的 CarServiceImpl.onCreate() 函数里有提到过:将ICarImpl对象添加为系统服务,服务名称为"car_service",使其可以被系统中的其他组件访问。

查找到服务后将 IBinder 对象转换为 ICar 接口的实例,并赋给mService 。 同时设置 mConnectionState 为连接状态。

car.mService = ICar.Stub.asInterface(service);  
car.mConnectionState = STATE_CONNECTED;

Car.getCarManager()

// packages/services/Car/car-lib/src/android/car/Car.java

public final class Car implements ICarBase {

    /**
     * 获取特定于汽车的服务管理器,类似于 {@link Context#getSystemService(String)}。
     * 返回的 {@link Object} 应该被强制转换为所需的服务管理器类型。
     *
     * <p>例如,要获取传感器服务的管理器,可以这样使用:
     * <code>
     * CarSensorManager carSensorManager = (CarSensorManager) car.getCarManager(Car.SENSOR_SERVICE);
     * </code>
     *
     * @param serviceName 应创建的服务名称,例如 {@link #SENSOR_SERVICE}。
     * @return 匹配的服务管理器,如果没有这样的服务,则返回 null。
     */
    @Nullable
    public Object getCarManager(String serviceName) {
        CarManagerBase manager;
        synchronized (mLock) { // 确保线程安全,锁定 mLock
            if (mService == null) { // 检查汽车服务是否已准备好
                Slog.w(TAG_CAR, "在汽车服务未准备好时 getCarManager 无法工作");
                return null;
            }
            manager = mServiceMap.get(serviceName); // 从缓存中获取服务管理器
            if (manager == null) { // 如果缓存中没有,则尝试创建新的服务管理器
                try {
                    IBinder binder = mService.getCarService(serviceName); // 获取服务的 IBinder
                    if (binder == null) { // 如果没有获取到 IBinder,记录警告并返回 null
                        Slog.w(TAG_CAR, "getCarManager 无法获取服务的 binder:" + serviceName);
                        return null;
                    }
                    manager = createCarManagerLocked(serviceName, binder); // 创建新的服务管理器
                    if (manager == null) { // 如果创建失败,记录警告并返回 null
                        Slog.w(TAG_CAR, "getCarManager 无法为服务创建管理器:" + serviceName);
                        return null;
                    }
                    mServiceMap.put(serviceName, manager); // 将创建的管理器放入缓存
                } catch (RemoteException e) { // 处理远程异常
                    handleRemoteExceptionFromCarService(e);
                }
            }
        }
        return manager; // 返回服务管理器
    }

    /**
     * 通过类获取特定于汽车的服务管理器,类似于 {@link Context#getSystemService(Class<T>)}。
     * 返回所需的服务,不需要类型转换。
     *
     * <p>例如,要获取传感器服务的管理器,可以这样使用:
     * <code>CarSensorManager carSensorManager = car.getCarManager(CarSensorManager.class);</code>
     *
     * @param serviceClass 所需服务的类。
     * @return 匹配的服务管理器,如果没有这样的服务,则返回 {@code null}。
     */
    @Nullable
    public <T> T getCarManager(@NonNull Class<T> serviceClass) {
        String serviceName = CAR_SERVICE_NAMES.get(serviceClass); // 获取服务名称
        return serviceName != null ? (T) getCarManager(serviceName) : null; // 返回服务管理器
    }
}

在获取特定于汽车的服务管理器时,由于 mServiceMap 仅在 getCarManager() 函数中执行 put 操作,因此第一次获取时 manager 通常为空。在这个过程中,mService 实际上是 ICar 接口的实现,即 ICarImpl。因此,在分析这个函数时,我们主要关注的是 getCarService()createCarManagerLocked 这两个方法的实现。

ICarImpl.getCarService()

Warning

这里已经走到 CarService 服务进程了。

// packages/services/Car/service/src/com/android/car/CarServiceImpl.java

public class ICarImpl extends ICar.Stub {

    /**
     * 根据服务名称获取对应的 Binder 对象。
     *
     * @param serviceName 要获取的服务名称。
     * @return 对应服务的 IBinder 对象,如果服务不可用或未启用,则返回 null。
     */
    public IBinder getCarService(String serviceName) {
        // 检查服务是否启用
        if (!mFeatureController.isFeatureEnabled(serviceName)) {
            Slogf.w(CarLog.TAG_SERVICE, "尝试获取已禁用的服务:" + serviceName);
            return null;
        }
        // 根据服务名称返回对应的 Binder 对象
        switch (serviceName) {
            case Car.AUDIO_SERVICE:
                return mCarAudioService;
            case Car.APP_FOCUS_SERVICE:
                return mAppFocusService;
            case Car.PACKAGE_SERVICE:
                return mCarPackageManagerService;
            case Car.DIAGNOSTIC_SERVICE:
                CarServiceUtils.assertAnyDiagnosticPermission(mContext);
                return mCarDiagnosticService;
            case Car.POWER_SERVICE:
                return mCarPowerManagementService;
            case Car.CABIN_SERVICE:
            case Car.HVAC_SERVICE:
            case Car.INFO_SERVICE:
            case Car.PROPERTY_SERVICE:
            case Car.SENSOR_SERVICE:
            case Car.VENDOR_EXTENSION_SERVICE:
                return mCarPropertyService;
            case Car.CAR_NAVIGATION_SERVICE:
                CarServiceUtils.assertNavigationManagerPermission(mContext);
                return mClusterNavigationService;
            case Car.CAR_INSTRUMENT_CLUSTER_SERVICE:
                CarServiceUtils.assertClusterManagerPermission(mContext);
                return mInstrumentClusterService.getManagerService();
            case Car.PROJECTION_SERVICE:
                return mCarProjectionService;
            case Car.VEHICLE_MAP_SERVICE:
                CarServiceUtils.assertAnyVmsPermission(mContext);
                return mVmsBrokerService;
            case Car.VMS_SUBSCRIBER_SERVICE:
                CarServiceUtils.assertVmsSubscriberPermission(mContext);
                return mVmsBrokerService;
            case Car.TEST_SERVICE: {
                CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
                synchronized (mLock) {
                    if (mCarTestService == null) {
                        mCarTestService = new CarTestService(mContext, this);
                    }
                    return mCarTestService;
                }
            }
            case Car.STORAGE_MONITORING_SERVICE:
                CarServiceUtils.assertPermission(mContext, Car.PERMISSION_STORAGE_MONITORING);
                return mCarStorageMonitoringService;
            case Car.CAR_DRIVING_STATE_SERVICE:
                CarServiceUtils.assertDrivingStatePermission(mContext);
                return mCarDrivingStateService;
            case Car.CAR_UX_RESTRICTION_SERVICE:
                return mCarUXRestrictionsService;
            case Car.OCCUPANT_AWARENESS_SERVICE:
                return mOccupantAwarenessService;
            case Car.CAR_MEDIA_SERVICE:
                return mCarMediaService;
            case Car.CAR_OCCUPANT_ZONE_SERVICE:
                return mCarOccupantZoneService;
            case Car.CAR_BUGREPORT_SERVICE:
                return mCarBugreportManagerService;
            case Car.CAR_USER_SERVICE:
                return mCarUserService;
            case Car.EXPERIMENTAL_CAR_USER_SERVICE:
                return mExperimentalCarUserService;
            case Car.EXPERIMENTAL_CAR_KEYGUARD_SERVICE:
                return mExperimentalCarKeyguardService;
            case Car.CAR_WATCHDOG_SERVICE:
                return mCarWatchdogService;
            case Car.CAR_PERFORMANCE_SERVICE:
                return mCarPerformanceService;
            case Car.CAR_INPUT_SERVICE:
                return mCarInputService;
            case Car.CAR_DEVICE_POLICY_SERVICE:
                return mCarDevicePolicyService;
            case Car.CLUSTER_HOME_SERVICE:
                return mClusterHomeService;
            case Car.CAR_EVS_SERVICE:
                return mCarEvsService;
            case Car.CAR_TELEMETRY_SERVICE:
                return mCarTelemetryService;
            case Car.CAR_ACTIVITY_SERVICE:
                return mCarActivityService;
            case Car.CAR_OCCUPANT_CONNECTION_SERVICE:
                return mCarOccupantConnectionService;
            case Car.CAR_REMOTE_DEVICE_SERVICE:
                return mCarRemoteDeviceService;
            case Car.CAR_REMOTE_ACCESS_SERVICE:
                return mCarRemoteAccessService;
            default:
                // CarDisplayCompatManager 不需要新的服务,但 Car 类不允许没有服务的新 Manager 类。
                if (mFeatureFlags.displayCompatibility()) {
                    if (serviceName.equals(CAR_DISPLAY_COMPAT_SERVICE)) {
                        return mCarActivityService;
                    }
                }
                if (mFeatureFlags.persistApSettings()) {
                    if (serviceName.equals(Car.CAR_WIFI_SERVICE)) {
                        return mCarWifiService;
                    }
                }
                IBinder service = null;
                if (mCarExperimentalFeatureServiceController != null) {
                    service = mCarExperimentalFeatureServiceController.getCarService(serviceName);
                }
                if (service == null) {
                    Slogf.w(CarLog.TAG_SERVICE, "尝试获取未知服务:" + serviceName);
                }
                return service;
        }
    }
}

getCarService 方法用于根据服务名称返回对应的 IBinder 对象。IBinder 是 Android 中用于进程间通信的接口,通过它可以实现服务的绑定和调用。

在这个例子中,我们传入 Car.POWER_SERVICE 时,方法会返回 mCarPowerManagementService,即 ICarPower 对象。

public class CarPowerManagementService extends ICarPower.Stub {
}

Car.createCarManagerLocked()

// packages/services/Car/car-lib/src/android/car/Car.java
public final class Car implements ICarBase {

    /**
     * 根据服务名称和 IBinder 创建对应的 CarManagerBase 实例。
     *
     * @param serviceName 服务名称,用于确定要创建的管理器类型。
     * @param binder 服务的 IBinder 对象,用于与服务进行通信。
     * @return 创建的 CarManagerBase 实例,如果服务名称未知或无法创建,则返回 null。
     */
    @Nullable
    private CarManagerBase createCarManagerLocked(String serviceName, IBinder binder) {
        CarManagerBase manager = null;
        switch (serviceName) {
            case AUDIO_SERVICE:
                manager = new CarAudioManager(this, binder);
                break;
            case SENSOR_SERVICE:
                manager = new CarSensorManager(this, binder);
                break;
            case INFO_SERVICE:
                manager = new CarInfoManager(this, binder);
                break;
            case APP_FOCUS_SERVICE:
                manager = new CarAppFocusManager(this, binder);
                break;
            case PACKAGE_SERVICE:
                manager = new CarPackageManager(this, binder);
                break;
            case CAR_OCCUPANT_ZONE_SERVICE:
                manager = new CarOccupantZoneManager(this, binder);
                break;
            case CAR_NAVIGATION_SERVICE:
                manager = new CarNavigationStatusManager(this, binder);
                break;
            case CABIN_SERVICE:
                manager = new CarCabinManager(this, binder);
                break;
            case DIAGNOSTIC_SERVICE:
                manager = new CarDiagnosticManager(this, binder);
                break;
            case HVAC_SERVICE:
                manager = new CarHvacManager(this, binder);
                break;
            case POWER_SERVICE:
                manager = new CarPowerManager(this, binder);
                break;
            case PROJECTION_SERVICE:
                manager = new CarProjectionManager(this, binder);
                break;
            case PROPERTY_SERVICE:
                // 使用 ICarProperty.Stub.asInterface 将 binder 转换为 ICarProperty 接口
                manager = new CarPropertyManager(this, ICarProperty.Stub.asInterface(binder));
                break;
            case VENDOR_EXTENSION_SERVICE:
                manager = new CarVendorExtensionManager(this, binder);
                break;
            case CAR_INSTRUMENT_CLUSTER_SERVICE:
                manager = new CarInstrumentClusterManager(this, binder);
                break;
            case TEST_SERVICE:
                // CarTestManager 存在于静态库中,因此这里只传递 binder 包装器,以便在外部构造 CarTestManager
                manager = new CarTestManager(this, binder);
                break;
            case VEHICLE_MAP_SERVICE:
                manager = new VmsClientManager(this, binder);
                break;
            case VMS_SUBSCRIBER_SERVICE:
                // 使用 VmsSubscriberManager 包装 VmsClientManager
                manager = VmsSubscriberManager.wrap(this,
                        (VmsClientManager) getCarManager(VEHICLE_MAP_SERVICE));
                break;
            case STORAGE_MONITORING_SERVICE:
                manager = new CarStorageMonitoringManager(this, binder);
                break;
            case CAR_DRIVING_STATE_SERVICE:
                manager = new CarDrivingStateManager(this, binder);
                break;
            case CAR_UX_RESTRICTION_SERVICE:
                manager = new CarUxRestrictionsManager(this, binder);
                break;
            case OCCUPANT_AWARENESS_SERVICE:
                manager = new OccupantAwarenessManager(this, binder);
                break;
            case CAR_MEDIA_SERVICE:
                manager = new CarMediaManager(this, binder);
                break;
            case CAR_BUGREPORT_SERVICE:
                manager = new CarBugreportManager(this, binder);
                break;
            case CAR_USER_SERVICE:
                manager = new CarUserManager(this, binder);
                break;
            case EXPERIMENTAL_CAR_USER_SERVICE:
                manager = new ExperimentalCarUserManager(this, binder);
                break;
            case CAR_WATCHDOG_SERVICE:
                manager = new CarWatchdogManager(this, binder);
                break;
            case CAR_INPUT_SERVICE:
                manager = new CarInputManager(this, binder);
                break;
            case CAR_DEVICE_POLICY_SERVICE:
                manager = new CarDevicePolicyManager(this, binder);
                break;
            case CLUSTER_HOME_SERVICE:
                manager = new ClusterHomeManager(this, binder);
                break;
            case CAR_EVS_SERVICE:
                manager = new CarEvsManager(this, binder, /* featureFlags= */ null);
                break;
            case CAR_TELEMETRY_SERVICE:
                manager = new CarTelemetryManager(this, binder);
                break;
            case CAR_ACTIVITY_SERVICE:
                manager = new CarActivityManager(this, binder);
                break;
            case CAR_PERFORMANCE_SERVICE:
                manager = new CarPerformanceManager(this, binder);
                break;
            case CAR_REMOTE_ACCESS_SERVICE:
                manager = new CarRemoteAccessManager(this, binder);
                break;
            case CAR_OCCUPANT_CONNECTION_SERVICE:
                manager = new CarOccupantConnectionManager(this, binder);
                break;
            case CAR_REMOTE_DEVICE_SERVICE:
                manager = new CarRemoteDeviceManager(this, binder);
                break;
            default:
                // 处理实验性或不存在的服务
                if (Flags.displayCompatibility()) {
                    if (serviceName.equals(CAR_DISPLAY_COMPAT_SERVICE)) {
                        manager = new CarDisplayCompatManager(this, binder);
                        break;
                    }
                }
                if (Flags.persistApSettings()) {
                    if (serviceName.equals(CAR_WIFI_SERVICE)) {
                        manager = new CarWifiManager(this, binder);
                        break;
                    }
                }
                String className = null;
                try {
                    synchronized (mLock) {
                        className = mService.getCarManagerClassForFeature(serviceName);
                    }
                } catch (RemoteException e) {
                    handleRemoteExceptionFromCarService(e);
                    return null;
                }
                if (className == null) {
                    Slog.e(TAG_CAR, "无法为服务构建 CarManager:" + serviceName + " : 未定义类");
                    return null;
                }
                manager = constructCarManager(className, binder);
                break;
        }
        return manager;
    }
}

根据传入的服务名称和 IBinder 对象,创建相应的 CarManagerBase 实例。

Car.POWER_SERVICE 为例,创建 manager 的过程如下:

manager = new CarPowerManager(this, binder);

在这个例子中,binder 实际上是 ICarPower 接口的实现。

CarPowerManager.getPowerState()

// packages/services/Car/car-lib/src/android/car/hardware/power/CarPowerManager.java


/**
 * 用于接收电源策略更改通知的 API。
 */
public class CarPowerManager extends CarManagerBase {

    // ICarPower 接口的实例,用于与电源服务进行通信
    private final ICarPower mService;

    /**
     * 获取 CarPowerManager 的实例。
     *
     * <p>不应由客户端直接获取,而应使用 {@link Car#getCarManager(String)}。
     *
     * @hide
     */
    public CarPowerManager(Car car, IBinder service) {
        super(car); // 调用父类构造函数,传入 Car 实例
        // 将 IBinder 转换为 ICarPower 接口
        mService = ICarPower.Stub.asInterface(service);
    }

    /**
     * 返回当前的电源状态。
     *
     * @return 在 {@link CarPowerStateListener} 中定义的值之一。
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(Car.PERMISSION_CAR_POWER)
    public @CarPowerState int getPowerState() {
        try {
            // 调用 ICarPower 接口的方法获取电源状态
            return mService.getPowerState();
        } catch (RemoteException e) {
            // 处理远程异常,并返回无效状态
            return handleRemoteExceptionFromCarService(e, STATE_INVALID);
        }
    }
}

通过 IPC 调用服务的 getPowerState()

服务端

CarPowerManagementService.getPowerState()

// packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java

/**
 * 汽车的电源管理服务类。控制电源状态并与系统的其他部分交互以确保其自身状态。
 */
public class CarPowerManagementService extends ICarPower.Stub implements
        CarServiceBase, PowerHalService.PowerEventListener {

    /**
     * 获取当前的电源状态。
     *
     * @return 在 {@link CarPowerManager.CarPowerState} 中定义的电源状态。
     */
    @Override
    public @CarPowerManager.CarPowerState int getPowerState() {
        // 确保调用者具有电源权限
        CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
        synchronized (mLock) { // 确保线程安全,锁定 mLock
            // 如果当前状态为 null,则返回无效状态;否则返回当前的电源状态
            return (mCurrentState == null) ? CarPowerManager.STATE_INVALID
                    : mCurrentState.mCarPowerStateListenerState;
        }
    }
}

CarPowerManagementService 是一个用于管理汽车电源状态的服务类。继承自 ICarPower.Stub 并实现相关的接口。

实际上,状态信息来源于 PowerHalService。然而,在这篇文章中,我们的重点在于分析客户端如何调用到 Java 服务端的过程,因此我们将不再深入探讨状态的具体实现细节。

后续

通过三篇文章,我们已经分析了服务进程的启动、服务的初始化、服务列表的使用以及客户端如何调用服务。至此,我们对 CarService 服务有了一个初步的了解。在进一步深入分析每个服务的具体功能、接口设计及其实现细节之前,我们将用一篇文章深入探讨 CarService 如何调用 Vehicle HAL 以及如何接收 Vehicle HAL 的回调。

评论