目录
一,背景介绍
1.1 Android Automotive与整个Android生态系统的关系
1.2 Android Automotive架构
二,CarService启动流程
三,CarService源码分析
四. Car API 使用方式
4.1 编译 Car API
4.2 使用 Car API
Android Automotive OS 定义了标准的硬件抽象层HAL(Hardware Abstraction Layer)来规范各个子系统与Framework的调用接口, 并且通过CarService以及相关的Car API对上层应用提供标准编程接口。
Android Automotive是Android的一部分。 Android Automotive不是Android的分支或并行开发,它与手机,平板电脑等安卓设备上的Android具有相同的代码库,并且位于相同的存储库中。它基于经过10多年开发的强大平台和功能集,可利用现有的安全模型,兼容性程序,开发人员工具和基础架构,同时继续具有高度可定制性和可移植性,完全免费和开源的特点。
Android Automotive扩展了Android 。在将Android打造为功能齐全的信息娱乐平台的过程中,我们添加了对汽车特定要求,功能和技术的支持。就像今天用于移动设备的Android一样,Android Automotive将是一个完整的汽车信息娱乐平台。
Android Automative是在原先Android的系统架构上增加了一些与车相关的(图中虚线框中绿色背景的)模块。
细节代码如下:
路径:/frameworks/base/services/java/com/android/server/SystemServer.java
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
t.traceBegin("StartCarServiceHelperService");
mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
t.traceEnd();
}
后跳转到SystemServiceManager.java文件中的startService方法
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public SystemService startService(String className) {
final Class serviceClass;
try {
serviceClass = (Class)Class.forName(className);
} catch (ClassNotFoundException ex) {
Slog.i(TAG, "Starting " + className);
throw new RuntimeException("Failed to create service " + className
+ ": service class not found, usually indicates that the caller should "
+ "have called PackageManager.hasSystemFeature() to check whether the "
+ "feature is available on this device before trying to start the "
+ "services that implement it", ex);
}
return startService(serviceClass);
}
public T startService(Class serviceClass) {
final String name = serviceClass.getName();
....
try { //注释1
Constructor constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
....
startService(service);
return service;
...
}
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
//注释2 启动CarService
service.onStart();
.....
}
注释1处, 通过SystemServiceManager封装的方法来创建服务, 此处SystemServiceManager通过反射创建了CarServiceHelperService对象, 并调用其onStart方法, 进入到CarServiceHelperService.java文件中
public void onStart() {
Intent intent = new Intent();
intent.setPackage("com.android.car");
intent.setAction(CAR_SERVICE_INTERFACE);
if (!getContext().bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
UserHandle.SYSTEM)) {
Slog.wtf(TAG, "cannot start car service");
}
System.loadLibrary("car-framework-service-jni");
}
注释二处 在onStart方法中, 创建了一个Intent 设置包名 和 Action 并调用bindServiceAsUser创建和绑定关联CarService, 同时加载了相关的JNI库(car-framework-service-jni).
通过以上的源码片段, 我们知道Intent的目标包名为"com.android.car", action为"android.car.ICar", 源码全局搜索与之相匹配的Service
packages/services/Car/service/src/com/android/car/CarService.java
当服务启动之后, 首先调用其onCreate方法. CarService的onCreate方法实现如下:
@Override
public void onCreate() {
Log.i(CarLog.TAG_SERVICE, "Service onCreate");
//获取通知管理NotificationManager对象
mCanBusErrorNotifier = new CanBusErrorNotifier(this /* context */);
mVehicle = getVehicle();
if (mVehicle == null) {
throw new IllegalStateException("Vehicle HAL service is not available.");
}
try {
mVehicleInterfaceName = mVehicle.interfaceDescriptor();
} catch (RemoteException e) {
throw new IllegalStateException("Unable to get Vehicle HAL interface descriptor", e);
}
Log.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName);
mICarImpl = new ICarImpl(this,
mVehicle,
SystemInterface.Builder.defaultSystemInterface(this).build(),
mCanBusErrorNotifier,
mVehicleInterfaceName);
mICarImpl.init();
linkToDeath(mVehicle, mVehicleDeathRecipient);
ServiceManager.addService("car_service", mICarImpl);
//设置SystemProperty属性 carService已创建
SystemProperties.set("boot.car_service_created", "1");
super.onCreate();
}
主要做了两件事情:
1. 获取mVehicle 车辆相关的HIDL Binder远程对象;
2. 创建了mICarImpl对象, 并将其添加到ServiceManager管理的服务列表中.
这里的 ICarImpl起着创建并管理各个服务的作用. 在它的构造函数中,创建了各个服务的实例,并添加到服务列表中,源码如下:
packages/services/Car/service/src/com/android/car/ICarImpl.java
public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) {
mContext = serviceContext;
mSystemInterface = systemInterface;
mHal = new VehicleHal(vehicle);
mVehicleInterfaceName = vehicleInterfaceName;
//创建各种重要的服务
mUserManagerHelper = new CarUserManagerHelper(serviceContext);
final Resources res = mContext.getResources();
final int maxRunningUsers = res.getInteger(
com.android.internal.R.integer.config_multiuserMaxRunningUsers);
mCarUserService = new CarUserService(serviceContext, mUserManagerHelper,
ActivityManager.getService(), maxRunningUsers);
mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(),
systemInterface, mUserManagerHelper);
mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal());
....
//将重要的服务缓存到 CarLocalServices
CarLocalServices.addService(CarPowerManagementService.class, mCarPowerManagementService);
CarLocalServices.addService(CarUserService.class, mCarUserService);
CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService);
// 将创建的服务对象依次添加到一个list中保存起来
List allServices = new ArrayList<>();
allServices.add(mFeatureController);
allServices.add(mCarUserService);
.....
}
这些创建的服务就是上文介绍的汽车服务.
在上面的介绍中,我们提到CarService中各个服务本质上是AIDL接口的实现类,属于Server端,而对应的Client端就需要一个IBinder对象来访问Server端的方法,这些IBinder对象在Car API中被封装在一个个XXXManager类中。
在使用Car API之前,我们需要先将Car API编译成jar也就是CarLib,这样才能让其它的系统应用使用, 命令如下
make android.car android.car-system-stubs android.car-stubs
编译成功后的 android.car.jar 的输出路径为:
/out/soong/.intermediates/packages/services/Car/car-lib/android.car/android_common/javac/android.car.jar
获取Car对象的方法:
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
Car carClient = Car.createCar(context);
CarHvacManager manager = (CarHvacManager) carClient.getCarManager(Car.HVAC_SERVICE);
}
如果要获取车辆的相关信息,如车速, 车内空调温度,诊断信息, 或对车辆进行相关的控制,如升高和降低空调温度,控制座椅和车窗, 调节音量等,就要通过具体的Manager中的API和对应的服务来实现了.