本文基于Android O源码。
主要介绍Android的CarService。
Android Automative的整体架构如下图所示:
从这幅图中我们可以看出,Android Automative是在原先Android的系统架构上增加了一些与车相关的(图中中间部分)模块。
包括:
有关更多详情,请参阅车辆属性。
/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目录下。
开发汽车专有的App自然需要专有的API。这些API对于其他平台(例如手机和平板)通常是没有意义的。所以这些API没有包含在Android Framework SDK中。
下面这张大图大致列出了Car API:
从这个图中我们可以看到Car API主要包括:
android.car:包含了与车相关的基本API。例如:车辆后视镜,门,座位,窗口等。
CarCabinManager: 管理车窗,座椅,窗户等信息。
CarPackageManager:允许应用对系统范围内的package进行控制,允许添加黑白名单以便允许或者阻止APP的运行,例如在高速状态下禁止video应用等。
CarAppFocusManager:允许应用获取系统当前的焦点应用,例如导航或者语音是否处于active状态。
CarInfoManager:获取车辆静态信息,例如制造商,VehicleID,生产日期等。
CarVendorExtensionManager:自定义car event可以放到CarVendorExtensionManager中进行管理。
CarService集中在一个App中。这个App需要非常高的权限,所以这是一个系统App。其Manifest开头如下:
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全称是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接口用来供其他模块使用。
自定义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与汽车