Android O CarService

本文基于Android8.1源码。
主要介绍Android的CarService。

架构

Android Automative的整体架构如下图所示:

《Android O CarService》

从这幅图中我们可以看出,Android Automative是在原先Android的系统架构上增加了一些与车相关的(图中中间部分)模块。
包括:

  • Car App:包括原始设备制造商(OEM)和第三方开发的App。
  • Car API:提供给汽车App特有的接口。包含 CarHvacManager 、 CarSensorManager 和CarVendorExtensionManager等 API。如需详细了解受支持的 API,请参阅 /platform/packages/services/Car/car-lib,是car相关的API集合,底层是由CarService实现。
  • Car Service:系统中与车相关的服务。位于 /platform/packages/services/Car/service,CarService主要是基于CarProperty实现Vechile相关的一些策略。
  • Vehicle Network Service:汽车的网络服务。通过内置安全机制控制车载 HAL。仅限访问系统组件(第三方应用等非系统组件需使用 Car API)。原始设备制造商 (OEM) 可以通过 vns_policy.xml 和 vendor_vns_policy.xml 控制访问权限。位于 /platform/packages/services/Car/vehicle_network_service/;要查看用于访问车辆网络的库,请参阅 /platform/packages/services/Car/libvehiclenetwork/。
  • Vehicle HAL:汽车的硬件抽象层描述。定义 OEM 可以实现的车辆属性的接口。包含属性元数据(例如,车辆属性是否为 int 以及允许使用哪些更改模式)。位于 hardware/libhardware/include/hardware/vehicle.h。要了解基本参考实现的相关信息,请参阅 hardware/libhardware/modules/vehicle/。

有关更多详情,请参阅车辆属性

Car App

/car_product/build/car.mk 这个文件中列出了汽车系统中专有的模块:

# Automotive specific packages
PRODUCT_PACKAGES += \
    vehicle_monitor_service \
    CarService \
    CarTrustAgentService \
    CarDialerApp \
    CarRadioApp \
    OverviewApp \
    CarLensPickerApp \
    LocalMediaPlayer \
    CarMediaApp \
    CarMessengerApp \
    CarHvacApp \
    CarMapsPlaceholder \
    CarLatinIME \
    CarUsbHandler \
    android.car \
    libvehiclemonitor-native \

这个列表中,首字母大写的模块基本上都是汽车系统中专有的App。
这些App的源码位于/platform/packages/apps/Car目录下。

Car API

开发汽车专有的App自然需要专有的API。这些API对于其他平台(例如手机和平板)通常是没有意义的。所以这些API没有包含在Android Framework SDK中。

下面这张大图大致列出了Car API:

《Android O CarService》

从这个图中我们可以看到Car API主要包括:

android.car:包含了与车相关的基本API。例如:车辆后视镜,门,座位,窗口等。

  1. annotation:包含了两个注解。annotation:包含了两个注解。
  2. app
    menu:车辆应用菜单相关API。
  3. cluster:仪表盘相关API。
    render:渲染相关API。
  4. content
    pm:应用包相关API。
  5. diagnostic:包含与汽车诊断相关的API。
  6. hardware:车辆硬件相关API。
    cabin:座舱相关API。
    hvac:通风空调相关API。(hvac是Heating, ventilation and air conditioning的缩写)
    property:属性相关API。
    radio:收音机相关API。
  7. input:输入相关API。
  8. media:多媒体相关API。
  9. navigation:导航相关API。
  10. settings:设置相关API。
  11. vms:汽车监测相关API。

CarCabinManager: 管理车窗,座椅,窗户等信息。
CarPackageManager:允许应用对系统范围内的package进行控制,允许添加黑白名单以便允许或者阻止APP的运行,例如在高速状态下禁止video应用等。
CarAppFocusManager:允许应用获取系统当前的焦点应用,例如导航或者语音是否处于active状态。
CarInfoManager:获取车辆静态信息,例如制造商,VehicleID,生产日期等。
CarVendorExtensionManager:自定义car event可以放到CarVendorExtensionManager中进行管理。

CarService

CarService集中在一个App中。这个App需要非常高的权限,所以这是一个系统App。其Manifest开头如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
        package="com.android.car"
        coreApp="true"
        android:sharedUserId="android.uid.system">

android:sharedUserId属性使得这个应用具有系统权限。

CarService.java的onCreate()方法会new一个ICarImpl,并对一系列的服务进行初始化。
CarService并非一个服务,而是一系列的服务。这些服务都在ICarImpl.java构造函数中列了出来。

public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
        CanBusErrorNotifier errorNotifier) {
    mContext = serviceContext;
    mHal = new VehicleHal(vehicle);
    mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
    mCarPowerManagementService = new CarPowerManagementService(
            mHal.getPowerHal(), systemInterface);
    mCarSensorService = new CarSensorService(serviceContext, mHal.getSensorHal());
    mCarPackageManagerService = new CarPackageManagerService(serviceContext, mCarSensorService,
            mSystemActivityMonitoringService);
    mCarInputService = new CarInputService(serviceContext, mHal.getInputHal());
    mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService);
    mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService);
    mCarInfoService = new CarInfoService(serviceContext, mHal.getInfoHal());
    mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);
    mCarAudioService = new CarAudioService(serviceContext, mHal.getAudioHal(),
            mCarInputService, errorNotifier);
    mCarCabinService = new CarCabinService(serviceContext, mHal.getCabinHal());
    mCarHvacService = new CarHvacService(serviceContext, mHal.getHvacHal());
    mCarRadioService = new CarRadioService(serviceContext, mHal.getRadioHal());
    mCarNightService = new CarNightService(serviceContext, mCarSensorService);
    mInstrumentClusterService = new InstrumentClusterService(serviceContext,
            mAppFocusService, mCarInputService);
    mSystemStateControllerService = new SystemStateControllerService(serviceContext,
            mCarPowerManagementService, mCarAudioService, this);
    mCarVendorExtensionService = new CarVendorExtensionService(serviceContext,
            mHal.getVendorExtensionHal());
    mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext);
    mCarBluetoothService = new CarBluetoothService(serviceContext, mCarCabinService,
            mCarSensorService, mPerUserCarServiceHelper);
    if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
        mVmsSubscriberService = new VmsSubscriberService(serviceContext, mHal.getVmsHal());
        mVmsPublisherService = new VmsPublisherService(serviceContext, mHal.getVmsHal());
    }
    mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal());
    
    ...
    //ICarImpl.java
    public void init() {
        traceBegin("VehicleHal.init");
        mHal.init();
        traceEnd();
        traceBegin("CarService.initAllServices");
        for (CarServiceBase service : mAllServices) {
            service.init();
        }
        traceEnd();
    }

CarService.java的onCreate()方法new完一个ICarImpl对象会执行mICarImpl.init()方法初始化。
先对VehicleHal执行了init(),先是调用HalClient.getAllPropConfigs()从Vehicle HAL获取所有的属性,然后对各个service.takeSupportedProperties(properties)获取CarService支持的属性。
接着又对各个继承了CarServiceBase的Service执行service.init()方法。
比如PropertyHalServiceBase继承了CarServiceBase,在init()方法里面对各个属性执行了mVehicleHal.subscribeProperty(this, prop),然后调用了VehicleHal.java的subscribeProperty(HalServiceBase service, int property),接着调用HalClient.subscribe(SubscribeOptions… options),这样就把所有属性都subscribe了,这样CarService就能接收到Vehicle HAL发上来的所有属性变化。

VMS

VMS全称是Vehicle Monitor Service。正如其名称所示,这个服务用来监测其他进程。
在运行时,这个服务是一个独立的进程,在init.car.rc中有关于它的配置:

service vms /system/bin/vehicle_monitor_service
   class core
   user root
   group root
   critical

on boot
    start vms

这是一个Binder服务,并提供了C++和Java的Binder接口用来供其他模块使用。

CarVendorExtensionManager拓展

自定义Car Event属性增加可参考CarHvacManager.java和HvacHalService.java文件。
具体在CarVendorExtensionManager里面增加属性ID,然后在VendorExtensionHalService类似HvacHalService增加ManagerToHalPropIdMap并修改managerToHalPropId(int managerPropId)和halToManagerPropId(int halPropId)两个方法即可,这两个方法会在PropertyHalServiceBase.java里面使用到。

下面大致画了一下属性是怎么设置到Vehiclehal去的和回调是怎么上来的:
《Android O CarService》
set方法讲解:
CarVendorExtensionManager调用setProperty(Class propertyClass, int propId, int area, E value)方法将属性设置下去,会直接跑到CarPropertyManagerBase,在这会将propId,area,value三个参数组成CarPropertyValue参数并设置到CarPropertyServiceBase端。
接着会走到PropertyHalServiceBase,这里做的工作还是比较多的,首先获取到halPropId,这个halPropId是Vehiclehal定义生成的,在VendorExtensionHalService里面将CarVendorExtensionManager定义的属性与Vehiclehal定义的属性一一对应起来。toVehiclePropValue(CarPropertyValue carProp, int halPropId)方法会将CarPropertyValue参数转换成VehiclePropValue。
下一步就到了VehicleHal,再下一步就走到了HalClient,这里会调用到IVehicle,这个IVehicle就是HIDL的客户端,下面就走到Vehicle HAL里面去了。

get方法跟set方法是类似的。

Callback回调讲解:
从HalClient的onPropertyEvent(ArrayList propValues)方法就跑到VehicleHal文件onPropertyEvent()方法,这里有一个for循环HalServiceBase s.handleHalEvents(s.getDispatchList())将属性按模块分发上去,由于PropertyHalServiceBase是继承了HalServiceBase,所以PropertyHalServiceBase就能收到回调。
在PropertyHalServiceBase里面通过toCarPropertyValue(VehiclePropValue halValue, int propertyId)讲属性VehiclePropValue转换成CarPropertyValue。
下一步就走到CarPropertyServiceBase,进一步走到CarPropertyManagerBase的onEvent(CarPropertyEvent event)方法,接着调用dispatchEventToClient((CarPropertyEvent) msg.obj)将属性回调到CarVendorExtensionManager。

VehicleHal文件的onPropertyEvent()方法将属性按模块分发上去,比如SensorHalService也是继承了HalServiceBase,所以Sensor的属性就分发到SensorHalService回调上去了,并不走PropertyHalServiceBase。下一步就走到CarSensorService.onSensorEvents(List events)方法,最后调用SensorClient.dispatchSensorUpdate(clientEvents)回到了CarSensorManager.onSensorChanged(final CarSensorEvent event)。

参考:
谷歌文献
Android与汽车

    原文作者:他叫小黑
    原文地址: https://blog.csdn.net/u013082948/article/details/82858308
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞