前面简单介绍了一下Android Automotive 的架构,具体Android Automotive 在系统的每个层,都做了哪些东西,这里总结一下。
Android Automotive 为系统定制了一些专门适用车载系统的应用,以代替传统的手机应用模块。
系统应用层的Application都位于源码目录下packages/apps/Car/
包含的应用如下
模块 | 描述 |
---|---|
Calendar | 日历 |
Cluster | 仪表板 |
CompanionDeviceSupport | |
Dialer | 电话 |
Hvac | 空调 |
LatinIME | 输入法 |
Launcher | 桌面 |
LinkViewer | 二维码 |
LocalMediaPlayer | 媒体播放服务 |
Media | 多媒体 |
Messenger | 消息 |
Notification | 通知 |
Radio | 收音机 |
RoataryController | 旋转控制器 |
Settings | 设置 |
SystemUpdater | ota升级 |
libs | 支持库 |
tests | 测试 |
系统框架层提供了多个模块,来对Android Automotive 进行支持,最重要的有一个服务CarService (com.android.car)
。
系统框架层的模块都位于源码目录下packages/services/Car/
CarService
是一个类似Android系统中SystemSever
的服务。它由一个服务启动,而里面又控制着数十个子模块服务。
CarService
中CarService
只作为服务的入口,具体的业务逻辑都在内部的子服务中处理,CarService
的子服务如下。
服务 | 描述 |
---|---|
AppFocusService | 应用程序焦点服务确保一次只有一个应用程序类型的实例处于活动状态 |
CarAudioService | 负责与汽车音响系统交互的服务 |
CarInputService | 通过车辆HAL监控和处理输入事件 |
CarNightService | 用于处理用于将车辆设置为夜间模式的事件 |
CarPackageManagerService | 处理包相关信息 |
CarPowerManagementService | 汽车电源管理服务类。控制电源状态并与系统的其他部分交互以确保其自身状态。 。 |
CarProjectionService | 投影服务?允许绑定到投影应用程序以提高其优先级。它还允许投影应用程序处理语音操作请求 |
CarServiceBase | base类接口 |
CarTestService | 允许测试/模拟车辆的VehicleHal。这个服务直接使用车辆HAL API |
GarageModeService | 车库模式的主服务容器 |
InstrumentClusterService | 负责与汽车仪表盘交互的服务 |
CarBluetoothService | 维护当前用户的蓝牙设备和配置文件连接。 |
CarDiagnosticService | 诊断相关 |
CarMonitoringService | 监视应用程序资源使用情况的服务 |
PerUserCarServiceHelper | 提供作为当前用户绑定/取消绑定到PerUserCarService的方法,为UserSwitch广播设置侦听器,并调用已注册回调的客户端。 |
SystemActivityMonitoringService | 用于监控AMS的新活动或服务启动的服务 |
SystemStateControllerService | 系统状态控制器服务, 目前是空实现 |
CarConfigurationService | 它将查看系统上的默认JSON配置文件并解析其结果 |
CarDrivingStateService | 推断车辆当前行驶状态的服务。它通过监听CarPropertyService中的相关属性来计算驱动状态 |
CarLocationService | 当汽车停驻时,此服务存储LocationManager中的最后一个已知位置,并在汽车通电时恢复该位置。 |
CarPropertyService | 处理车辆属性的管理器。 |
CarStorageMonitoringService | 提供存储监视数据(如I/O统计信息)的服务。为了接收这些数据,用户需要实现{@link IIoStatsListener},并针对该服务注册自己。 |
CarUserService | 汽车用户服务。在启动时管理用户。 |
CarUxRestrictionsManagerService | 监听车辆当前驾驶状态并将其映射到该驾驶状态的相应UX限制的服务 |
CarBugreportManagerService | 汽车错误报告服务 |
CarMediaService | 为汽车应用程序管理当前活动的媒体源。 |
CarTrustedDeviceService | 汽车服务中启用受信任设备功能的部分。可信设备是一种功能,远程设备注册为可信设备 |
CarUserNoticeService | 向用户显示初始通知UI |
FixedActivityService | 监视显示的顶部Activity |
CarExperimentalFeatureServiceController | 控件绑定到ExperimentalCarsService和实验功能的接口 |
CarFeatureController | 控制汽车特性的部件 |
CarOccupantZoneService | 实现CarOccupentZoneManager API的服务 |
CarWatchdogService | 实现CarWatchdogManager API的服务。作为汽车看门狗中介运行,它检查客户的健康状态和将结果报告给汽车看门狗服务器。 |
DriverDistractionExperimentalFeatureService | 驾驶员分心服务,用于利用驾驶员的意识,所需的驾驶环境意识,以暴露驾驶员当前分心水平的API。 |
IExperimentalCarImpl | 实现IExperimentalCar为实验特性 |
OccupantAwarenessService | 一种服务,通过HAL边界监听乘客感知检测系统 |
TestDemoExperimentalFeatureService | 测试实验功能的演示服务 |
VmsBrokerService | 消息代理服务,用于在客户端之间路由车辆映射服务消息, 地图导航相关 |
CarService
本质上是一个特殊的APP,它编译后生成CarService.apk
;在系统中,它是在/system/priv-app/CarService/CarService.apk
CarService
在启动启动时,由SystemServer
拉起
代码:frameworks/base/services/java/com/android/server/SystemServer.java
private static final String CAR_SERVICE_HELPER_SERVICE_CLASS =
"com.android.internal.car.CarServiceHelperService";
private void startOtherServices() {
mActivityManagerService.systemReady(() -> {
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
traceBeginAndSlog("StartCarServiceHelperService");
mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
traceEnd();
}
});
}
代码:frameworks/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java
private static final String CAR_SERVICE_INTERFACE = "android.car.ICar";
public class CarServiceHelperService extends SystemService {
@Override
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");
}
}
SystemServer
中ActivityManagerService.systemReady
后会通过SystemServiceManager
启动CarServiceHelperService
CarServiceHelperService
中绑定CarService
代码:packages/services/Car/service/AndroidManifest.xml
<service android:name=".CarService"
android:singleUser="true">
<intent-filter>
<action android:name="android.car.ICar" />
intent-filter>
service>
通过在CarService
的AndroidManifest
的配置,CarServiceHelperService
可以通过包名和action的名称实现和CarService绑定。
Car API 是Android系统为汽车应用提供的一套SDK接口(Android Automotive Library)。
源代码位于packages/services/Car/car-lib
目录下
Google官方的API文档在Android Q之后,也开始支持Android Automotive库。
链接地址: https://developer.android.google.cn/reference/android/car/package-summary
同CarService
一样Car API 也提供的多个模块对应不同的功能调用。
接口 | 说明 |
---|---|
Car | Car API入口,其它Manager要通过它获取 |
CarAudioManager | 处理音频的接口 |
CarHvacManager(@Deprecated) | 控制空调系统的接口(弃用) |
CarInfoManager | 从汽车中检索各种静态信息的接口 |
CarPackageManager | 提供专用的和包管理相关的接口 |
CarProjectionManager | 投屏管理接口 |
CarSensorManager(@Deprecated) | 监控汽车传感器的接口(弃用) |
CarAppFocusManager | 设置和监听当前应用焦点的接口 |
CarBluetoothManager | 提供和特定的汽车蓝牙管理器交互的接口 |
CarCabinManager(@Deprecated) | 控制汽车座舱系统的接口(弃用) |
CarDiagnosticManager | 监控诊断数据的接口 |
CarInstrumentClusterManager(@Deprecated) | 配合仪表控制的接口(弃用) |
CarNavigationStatusManager | 为仪表盘提供导航状态的接口 |
CarVendorExtensionManager(@Deprecated) | 访问厂商扩展车辆属性的接口(弃用) |
CarConfigurationManager | 显示存储在系统中的车辆配置值的接口 |
CarDrivingStateManager | 获取与驾驶状态相关信息的接口 |
CarPowerManager | 接收电源状态变化的接口 |
CarPropertyManager | 与车辆属性交互的接口 |
CarStorageMonitoringManager | 检索闪存信息的接口 |
CarUxRestrictionsManager | 获取驾驶过程中用户体验限制的接口 |
VmsSubscriberManager(@Deprecated) | 供地图服务订阅者使用的接口(弃用) |
CarBugreportManager | 报告错误的接口 |
CarMediaManager | 接收媒体音源变化的接口 |
CarTrustAgentEnrollmentManager(@Deprecated) | 授权可信任设备的接口(弃用) |
CarInputManager | 获取输入事件的接口 |
CarOccupantZoneManager | 获取汽车显示器和用户信息的接口 |
CarTestManagerBinderWrapper | 仅用于系统测试 |
CarUserManager | 管理用户的接口 |
CarWatchdogManager | 提供检查程序运行状态的接口 |
OccupantAwarenessManager | 获取成员感知数据的接口 |
VmsClientManager | 连接地图服务的接口 |
硬件抽象层主要是提供了一个native
服务[email protected]
,负责处理车辆相关的业务。
硬件抽象层的模块位于源码目录下hardware/interfaces/automotive/
VehicleService
是一个native
服务,代码实现在目录hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/
VehicleServices
是Android Automotive在硬件抽象层的入口。它通过initrc
启动。
代码:hardware/interfaces/automotive/vehicle/2.0/default/[email protected]
service vendor.vehicle-hal-2.0 /vendor/bin/hw/android.hardware.automotive.vehicle@2.0-service
class hal
user vehicle_network
group system inet
VehicleHalManager
是Android Automotive在硬件抽象层的API接口。代码在目录
hardware/interfaces/automotive/vehicle/2.0/default/common/
。
从硬件抽象层到系统框架层,也就是从VehicleService
到CarService
,从Android O版本开始使用了一种新的HIDL接口。
HIDL 是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL)。虽然从 Android 10 开始,HIDL 已废弃,Android 将在所有位置改用 AIDL。 但是Android Automotive的HIDL架构还保留着,直到Android 13才发生变化。
HIDL使用一种以.hal
为后缀文件作为接口定义,在Android Automotive中硬件抽象层到系统框架层使用IVehicle.hal
(代码路径:hardware/interfaces/automotive/vehicle/2.0/IVehicle.halhardware/interfaces/automotive/vehicle/2.0/IVehicle.hal
)来定义。
代码:hardware/interfaces/automotive/vehicle/2.0/IVehicle.hal
package android.hardware.automotive.vehicle@2.0;
import IVehicleCallback;
interface IVehicle {
/**
* Returns a list of all property configurations supported by this vehicle
* HAL.
*/
//返回这个vehicle hal支持的全部property属性
getAllPropConfigs() generates (vec<VehiclePropConfig> propConfigs);
/**
* Returns a list of property configurations for given properties.
*
* If requested VehicleProperty wasn't found it must return
* StatusCode::INVALID_ARG, otherwise a list of vehicle property
* configurations with StatusCode::OK
*/
getPropConfigs(vec<int32_t> props)
generates (StatusCode status, vec<VehiclePropConfig> propConfigs);
/**
* Get a vehicle property value.
*
* For VehiclePropertyChangeMode::STATIC properties, this method must always
* return the same value always.
* For VehiclePropertyChangeMode::ON_CHANGE properties, it must return the
* latest available value.
*
* Some properties like RADIO_PRESET requires to pass additional data in
* GET request in VehiclePropValue object.
*
* If there is no data available yet, which can happen during initial stage,
* this call must return immediately with an error code of
* StatusCode::TRY_AGAIN.
*/
get(VehiclePropValue requestedPropValue)
generates (StatusCode status, VehiclePropValue propValue);
/**
* Set a vehicle property value.
*
* Timestamp of data must be ignored for set operation.
*
* Setting some properties require having initial state available. If initial
* data is not available yet this call must return StatusCode::TRY_AGAIN.
* For a property with separate power control this call must return
* StatusCode::NOT_AVAILABLE error if property is not powered on.
*/
set(VehiclePropValue propValue) generates (StatusCode status);
/**
* Subscribes to property events.
*
* Clients must be able to subscribe to multiple properties at a time
* depending on data provided in options argument.
*
* @param listener This client must be called on appropriate event.
* @param options List of options to subscribe. SubscribeOption contains
* information such as property Id, area Id, sample rate, etc.
*/
subscribe(IVehicleCallback callback, vec<SubscribeOptions> options)
generates (StatusCode status);
/**
* Unsubscribes from property events.
*
* If this client wasn't subscribed to the given property, this method
* must return StatusCode::INVALID_ARG.
*/
unsubscribe(IVehicleCallback callback, int32_t propId)
generates (StatusCode status);
/**
* Print out debugging state for the vehicle hal.
*
* The text must be in ASCII encoding only.
*
* Performance requirements:
*
* The HAL must return from this call in less than 10ms. This call must avoid
* deadlocks, as it may be called at any point of operation. Any synchronization
* primitives used (such as mutex locks or semaphores) must be acquired
* with a timeout.
*
*/
debugDump() generates (string s);
};
IVehicle
接口支持功能如下
getAllPropConfigs | 返回这个vehicle hal 支持的全部车辆属性 |
getPropConfigs | 获取车辆属性配置 |
get | 获取一个车辆属性值 |
set | 设置一个车辆属性值 |
subscribe | 订阅一个车辆属性 |
unsubscribe | 取消订阅一个车辆属性 |
debugDump | 打印vehicle hal dump信息 |
通过update-makefiles.sh
可以创建编译HIDL文件的Android.bp。
代码路径:hardware/interfaces/update-makefiles.sh
假设创建一个helloworld
模块,在hardware/interfaces
下创建helloworld/1.0/IHelloWorld.hal
:
package android.hardware.helloworld@1.0;
interface IHelloWorld {
justTest(string name);
};
通过update-makefiles.sh
就可以在对应package
的目录下创建Android.bp:
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: "[email protected]",
root: "android.hardware",
vndk: {
enabled: true,
},
srcs: [
"IHelloWorld.hal",
],
interfaces: [
"[email protected]",
],
gen_java: true,
}
name
:模块的全名
root
:包根目录
interfaces
:编译过程中依赖的模块
gen_java
:是否编译为Java 使用的接口
当然,还有其他的参数,例如gen_java_constants
设为true
的时候会生成为Java 使用的Constants
类。
Android各层编译产物如下:
packages/services/Car/service
CarService(com.android.car)
/system/priv-app/CarService/CarService.apk
packages/services/Car/car-lib
android.car
/system/Framework/android.car.jar
hardware/interface/automotive/vehicle/2.0
[email protected]
android.hardware.automotive.vehicle-V2.0-java.jar
[email protected]
hardware/interface/automotive/vehicle/2.0/default
vhal_v2_0_defaults
vhal_v2_0_target_defaults
vhal_v2_0_common_headers
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]