前言
在之前的文章从应用工程师的角度再谈车载 Android 系统中提到了"CarService
是车载Android系统的核心服务之一,所有应用都需要通过CarService
来查询、控制整车的状态",不仅仅是车辆控制,实际上CarService
几乎就是整个车载Framework最核心的组件,这也让CarService
成了各种bug的重灾区,一部分原因就是开发同学对于CarService
的运行原理与实现方式理解的不够深,那么本篇我们就来讲解Android Automotive R上CarService
是如何实现。
本文提到的
CarService
主要是基于原生Android Automotive,实际量产的各种车载Android系统中由于业务、技术、人员配置等各方面原因会对CarService
做进一步的拆分,所以功能上会与原生的CarService
会存在差异。
CarService 概述
CarService 源码位置:/packages/services/Car/service/
简介
通过之前的文章我们了解到,Android系统主要应用于中控和副驾屏幕,原生的车载Android本质上可以看作是Android OS + Automotive Services + Automotive APPs组成的系统。用户会通过显示在中控屏幕上App,将对车辆的操作信息通过Car API 传递给Framework Service
,Service再通过HIDL将信息处理后传递给HAL Service
,HAL Service
再将数据处理后传递给MCU
,MCU
通过CAN bus
将信息传递给汽车上的各个ECU(中间忽略了一些不需要理解的步骤),然后由ECU控制汽车的机械零部件进行活动,这样就完成了一次从Android APP到车辆机械零部件间的通信。
HIDL是一种类似于AIDL的跨进程通信手段,主要应用于HAL层程序的跨进程通信。Google在Android 8中引入并在Android 10中废弃,Android 10 以后被AIDL取代。
以上通信过程起到承上启下作用的Framework Service就是我们的主角 — CarService
。
原生Android Automotive 系统里
CarService
实现的功能非常多,架构图里描述的只是其中的冰山一角,架构图描述的意义只是为了引出CarService
。
CarService 的组成
作为 Android Automotive 的核心进程,原生的CarService
业务量非常庞大,包含了许多与汽车相关的服务,主要有以下几个:
- CarPropertyService
此类实现ICarProperty
的binder接口。有助于更容易地创建处理车辆属性的多个Manager。
- CarInputService
CarInputService
通过车辆HAL监控和处理输入事件。
- CarLocationService
此服务在车辆停放时存储LocationManager
中最后一个已知位置,并在车辆通电时恢复该位置。
- CarMediaService
CarMediaService
管理汽车应用程序的当前活动媒体源。这与MediaSessionManager
的活动会话不同,因为同一时间内车内只能有一个活动源。
在车内,活动的媒体源不一定有活动的MediaSession
,例如,如果只是在浏览它。但是,该源仍然被视为活动源,并且应该是任何媒体相关UI(媒体中心、主屏幕等)中显示的源。
- CarPowerManagementService
汽车电源管理服务。控制电源状态并与系统的其他部分交互以确保其自身状态。
- CarProjectionService
汽车投屏服务。
- CarAudioService
负责与汽车音响系统交互的服务。
- AppFocusService
应用程序焦点服务确保一次只有一个应用程序类型的实例处于活动状态。
- GarageModeService
车库模式。车库模式启用车内空闲时间。
- InstrumentClusterService
负责与汽车仪表盘交互的服务。
- CarPackageManagerService
汽车包管理服务。
- CarUserService
汽车多用户服务。在启动时管理用户。包括:
- 创建用作驱动程序的用户。
- 创建用作乘客的用户。
- 首次运行时创建辅助管理员用户。
- 切换驾驶员。
- CarStorageMonitoringService
提供存储监视数据(如I/O统计数据)的服务。为了接收此类数据,用户需要实现IIoStatsListener
并根据此服务注册自己。
- CarBluetoothService
车载蓝牙服务-维护当前用户的蓝牙设备和配置文件连接。
- FixedActivityService
监控显示器顶部的Activity,并确保在固定模式下的Activity在崩溃或因任何原因进入后台时重新启动。此组件还监视目标包的更新,并在更新完成后重新启动它。
- CarBugreportManagerService
Bug report服务
- CarConfigurationService
该服务将查看系统上的默认JSON配置文件并解析其结果。该服务将查找映射到R.raw.car_config
的JSON文件。如果此值不存在或格式不正确,则此服务不会失败;相反,它返回各种配置的默认值。
- CarDiagnosticService
汽车诊断服务。工程模式会用到此服务。
- CarDrivingStateService
推断车辆当前驾驶状态的服务。它通过侦听CarPropertyService
的相关属性来计算驾驶状态。
- CarExperimentalFeatureServiceController
控制与ExperimentalCarService
的绑定以及实验功能的接口。
- CarFeatureController
控制汽车特性的部件。
- CarNightService
用于处理用于将车辆设置为夜间模式的事件。
- CarOccupantZoneService
用于实现CarOccupantZoneManager
API的服务。
- CarTestService
允许测试/模拟车辆HAL的服务。该服务直接使用车辆HAL API,因为车辆HAL模拟无论如何都需要直接访问该级别。
- CarUxRestrictionsManagerService
用户体验限制的服务。根据监听到的车辆当前驾驶状态,限制HMI显示。
- OccupantAwarenessService
一种服务,通过HAL边界监听占用者感知检测系统,并通过OccupantAwarenessManager
将数据暴露给Android中的系统客户端。
- SystemActivityMonitoringService
监控AMS新Activity或Service启动的服务。
- SystemStateControllerService
系统状态控制服务。原生系统中是一个空服务,并没有实现。
- CarMonitoringService
监视应用程序资源使用情况的服务。
- CarTrustedDeviceService
汽车服务中启用受信任设备功能的部分。可信设备是一项功能,其中远程设备注册为可信设备,可以授权Android用户而不是用户输入密码或PIN。
- CarUserNoticeService
向用户显示初始通知UI的服务。它仅在启用设置时启动它,并根据用户的请求通知UI自行关闭。
- VmsBrokerService
VMS客户端实现,使用HAL特定消息编码将VmsPublisher/VmsSubscriber API调用代理到车辆HAL。
- CarWatchdogService
实现CarWatchdogManager
API的服务。CarWatchdogService
作为汽车监控中介运行,它检查客户端的健康状况,并将结果报告给汽车监控服务器。
加粗的各个
Service
属于CarService
中比较重要的功能,以后都会单独开坑讲。往简单地说,车载Framework的功能性开发基本就是围绕着
CarService
中的这些服务做增改,如果能把所有这些服务和背后原理都理解透彻,车载Framework基本就算完事了。当然可能也有些过于理想化了,因为还有android自身的Framework需要修改,比如网络系统、蓝牙协议栈等等。
以上就是Android Automotive中CarService
支持的所有功能,虽然冠名了xxxService但这些服务其实并不是四大组件意义上的Service
,它们没有继承自android.app.Service
,相反它们都继承自ICarxxxx.Stub
,本质上属于AIDL接口的实现类。到这一步也可以看出CarService
本质上只是作为这些服务的容器而存在的,本身并没有实现业务逻辑上的功能。
既然这些Service都是AIDL接口的实现类,本质上就是AIDL的Server端,那应用就还需要通过相应的API SDK才能调用Server的方法,这个API SDK就是Car API。
Car API 使用方式
不同的公司或车机系统项目对于Car API的定位、实现并不相同,本文主要从原生Android Automotive的角度介绍。
Car API 源码地址:packages/services/Car/car-lib/
Car API 简介
在上面的介绍中,我们提到CarService
中各个服务本质上是AIDL接口的实现类,属于Server端,而对应的Client端就需要一个IBinder
对象来访问Server端的方法,这些IBinder
对象在Car API中被封装在一个个XXXManager
类中。
Car API与CarService
中的服务,名称上存在对应关系,所以很好理解。例如:CarWatchdogManager
对应CarWatchdogService
,CarMediaManager
对应CarMediaService
。
不过也有例外:CarInfoManager
、CarSensorManager
、CarHvacManager
、CarCabinManager
、CarVendorExtensionManager
都对应CarPropertyService
。但是在Android 11中这些Manager都已经过时,Google建议统一使用CarPropertyManager
。
实际项目中我们不一定要按照Google建议的那样编写Car API,可以按实际情况实施。我个人也经历过某个把Car API源码整个移除,从头重写CarService的项目。