车载核心服务CarService

发布时间:2024年01月12日

一:CarService简介

Google考虑更多是车载的独立性,需要与androidOS分开,有自己的独立性,才好针对车载拓展,还有就是复用性,他自己在一个单独的进程,区别于ams等。AAOS作为车载操作系统, 需要与车辆上其他的子系统互联互通

AAOS定义了,标准的硬件抽象层HAL(Hardware Abstraction Layer)来规范各个子系统与Framework的调用接口,并且通过CarService以及相关的Car API,对上层应用提供标准编程接口

AAOS并没有大刀阔斧的改变Android原有的整体架构, 几乎所有的核心服务(AMS, WMS, PKMS)与手机并无区别,采用的是同一套代源码, 所以我们可以将AAOS 理解为Android OS + Android Automotive Services更为贴切.传统的手机系统加上相关的汽车服务,构成了现在的AAOS, 而其中CarService就是提供汽车相关功能的最主要的模块

车载分层架构

说明

? ? ?应用层: app发出控制消息

carservice: carservice通过HIDL(类似aidl实现进层通信)将信息给到HAL Service,HAL Service将消息处理后传递给mcu

? ? ? ? ?mcu: 行车总大脑

? ?can总线: 实时消息传递

? ? ? ? ? ecu: 电子控制单元,具体的执行控件

二:CarService的启动流程

看看CarService源码位置

aosp12\packages\services\Car\service

CarService作为Android Automotive的核心服务,他是在SystemServer中启动的。SystemServer会在StartOtherServices()方法中让SystemServiceManager先通过反射的形式,创建出StartCarServiceHelperService这个对象,并调用其onStart方法, 进入到CarServiceHelperService.java文件中

最终在onStart()方法中启动CarService,并加载jni库为CarService提供必要的API

CarService的onCreate()

主要逻辑:

1:持有mVehicle对象我们才可以与Vehicle HAL层进行通信

Car AIP (客户端) ------> CarService ------> ICarImpl ------> VehicleHal ------> obd can .... 硬件

2:创建ICarImpl对象,并调用init方法,需要通过它才能拿到很多的Service,的IBinder客户端

创建各个核心服务对象,将创建的服务对象依次添加到一个list中保存起来,这里主要是为了方便Service之 间的相互访问。

3:很多的Service添加到ServiceManager中,所以Car API中才可能顺利得到 很多的Service 来使用

4:设定SystemProperty,将CarService设定为创建完成状态,只有包含CarService在内的所有的核心Service都完成初始化,才能结束开机动画并发送开机广播

三:如何使用CarService

使用方法:

步骤1: 通过Car.createCar()方法可以创建出Car的对象。

步骤2:Car.createCar()需要传入ServiceConnection,并在service连接成功后,获取想要的Manager 实例(binder的客户端)

步骤3:构建出Car对象后还需要调用connect()才会连接到CarService上。

步骤1说明

通过getPackageManager().hasSystemFeature(String string)判断系统是否支持特定的模块功能

if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {

Car carApiClient = Car.createCar(context, mCarServiceConnection);

}

步骤2说明

Car.createCar()需要传入ServiceConnection,并在service连接成功后,获取想要的Manager 实例,实现方式如下:

步骤3说明:

carApiClient.connect();

注意:connect()只能调用一次,如果当前已经处于连接状态,再次调用connect()会抛出异常,

client如果没有捕获该异常,则会引起client端程序崩溃(血的教训!)。

Car.java中通过绑定服务CarService成功后onBind方法返回ICarImpl实例,在启动流程中我们知道ICarImpl中已经拥有所有service的binder(stub)

Car.getCarManager()方法,最终调用到stub.asInterface()方法获取到客户端的Binder对象(proxy),缓存到容器方便以后使用。

如下图调用:

这三步是Android9之前的使用方法

Android10后直接使用

Car carClient = Car.createCar(context);

CarHvacManager manager = (CarHvacManager) carClient.getCarManager(Car.HVAC_SERVICE);

四:CarService系列服务介绍

谷歌在CarService中实现了许多与汽车密切相关的服务, 每个汽车服务, 也会有自己对应的客户端。

CarService对象只是获取各个Manager的媒介,它本身并不承担管理传感器.空调等具体的任务,

具体实现需要获取对应的Manager中API和对应服务来实现。

五:汽车服务运用

汽车服务 --- CarPropertyService 介绍

绝大部分与车辆硬件功能相关联的属性,如空调, 车舱功能, 车辆传感器等,都是通过CarPropertyService来读取或者设置的,CarPropertyManager 是CarPropertyService在客户端的代理, 通过CarPropertyManager提供的API,可以设置和获取车辆各个属性的状态;

CarPropertyService同时对应着 CarCabinManager, CarHvacManager,CarInfoManager,CarPropertyManager, CarSensorManager和 CarVendorExtensionManager这六个对象,可以说是一个服务分担多个角色. 所以在Android11时, 谷歌直接推荐使用CarPropertyManager 来对应CarPropertyService

六:编译car api

编译后可以供其他app使用

编译方式1:

1:source build/envsetup.sh

2:lunch sdk_car_x86_64-userdebug

3:make -j16

4:make android.car

编译成功后的jar存放在/out/soong/.intermediates/packages/services/Car/car

lib/android.car/android_common/javac/目录里哦

编译方式2:

make android.car-system-stubs

编译成功后的jar存放在/out/soong/.intermediates/packages/services/Car/car-lib/android.car

system-stubs/android_common/javac/目录里

实际项目中这种模式较为常用

编译方式3:

make android.car-stubs

三合一的方式:derry@ubuntu:~/AOSP12$ make android.car android.car-system-stubs android

car-stubs -j32a

编译成功后的jar存放在/out/soong/.intermediates/packages/services/Car/car-lib/android.car

stubs/android_common/javac/目录里。

编译出的CarLib库仅包含没有被@SystemApi修饰方法,而且方法同样不包含实现细节,是最严格的编

译模式。

此模式下编译出的CarLib甚至已经没有CarDiagnosticManager这个系统API了。

如何引入编译后的库?

参考:Android.bp - OpenGrok cross reference for /packages/apps/Car/Settings/Android.bp

在android.bp文件中加入引用

文章来源:https://blog.csdn.net/qq_34979546/article/details/135550467
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。