Android O CarService

Posted 他叫小黑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android O CarService相关的知识,希望对你有一定的参考价值。

本文基于android O源码。
主要介绍Android的CarService。


架构

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

从这幅图中我们可以看出,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/。这部分代码在8.1中已经给谷歌删减了。
  • 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:

从这个图中我们可以看到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去的和回调是怎么上来的:

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与汽车

以上是关于Android O CarService的主要内容,如果未能解决你的问题,请参考以下文章

IVICarService启动

IVICarService启动

IVICarService启动

Android汽车服务篇 CarAudioService

android sdk那里下载

csharp CarService.cs