Android Automotive (2) System Architecture
I briefly introduced the architecture of Android Automotive, specifically what Android Automotive has done in each layer of the system, and here is a summary.
system application layer
Android Automotive has customized some applications for the system that are specially suitable for the vehicle system to replace the traditional mobile application modules.
Applications in the system application layer are all located in the source code directorypackages/apps/Car/
Included applications are as follows
module | describe |
---|---|
Calendar | calendar |
Cluster | Dashboard |
CompanionDeviceSupport | |
dialer | Telephone |
Hvac | air conditioner |
LatinIME | Input |
Launcher | desktop |
LinkViewer | QR code |
LocalMediaPlayer | media playback service |
Media | multimedia |
Messenger | information |
Notification | notify |
Radio | radio |
RoataryController | rotary controller |
Settings | set up |
SystemUpdater | ota upgrade |
libs | support library |
tests | test |
System framework layer
The system framework layer provides multiple modules to support Android Automotive, the most important one is a service CarService (com.android.car)
.
The modules of the system framework layer are all located in the source code directorypackages/services/Car/
CarService
It is a SystemSever
service similar to that in the Android system. It is started by a service, which controls dozens of submodule services.
CarService
CarService
It CarService
is only used as the entrance of the service, and the specific business logic is processed in the internal sub-services. CarService
The sub-services are as follows.
Serve | describe |
---|---|
AppFocusService | The application focus service ensures that only one instance of an application type is active at a time |
CarAudioService | Service responsible for interacting with the car audio system |
CarInputService | Monitor and process input events through the vehicle HAL |
CarNightService | Used to handle events for setting the vehicle to night mode |
CarPackageManagerService | Processing package related information |
CarPowerManagementService | Automotive power management services. Controls power state and interacts with other parts of the system to ensure its own state. . |
CarProjectionService | Projection Service - Allows binding to a projection application to raise its priority. It also allows the projection app to handle voice action requests |
CarServiceBase | base class interface |
CarTestService | A VehicleHal that allows testing/simulating vehicles. This service uses the vehicle HAL API directly |
GarageModeService | The main service container in Garage mode |
InstrumentClusterService | The service responsible for interacting with the car dashboard |
CarBluetoothService | Maintains the current user's Bluetooth device and profile connections. |
CarDiagnosticService | Diagnosis related |
CarMonitoringService | A service that monitors application resource usage |
PerUserCarServiceHelper | Provides methods to bind/unbind to PerUserCarService as the current user, set up listeners for UserSwitch broadcasts, and call clients that have registered callbacks. |
SystemActivityMonitoringService | Service to monitor AMS for new activity or service startup |
SystemStateControllerService | System state controller service, currently an empty implementation |
CarConfigurationService | It will look at the default JSON configuration file on the system and parse its results |
CarDrivingStateService | A service that infers the current driving state of a vehicle. It calculates the driving state by monitoring the relevant properties in CarPropertyService |
CarLocationService | This service stores the last known location in the LocationManager when the car is parked and restores that location when the car is powered on. |
CarPropertyService | A manager that handles vehicle properties. |
CarStorageMonitoringService | Provides a service for storing monitoring data such as I/O statistics. In order to receive this data, users need to implement {@link IIoStatsListener} and register themselves against the service. |
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启动
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
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
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
VehicleHalManager
是Android Automotive在硬件抽象层的API接口。代码在目录
hardware/interfaces/automotive/vehicle/2.0/default/common/
。
HAL接口语言
从硬件抽象层到系统框架层,也就是从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
通过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
- 编译模块:
- 代码库:
- HIDL
HIDL接口编译的库会生产JAVA和C++两套代码给系统框架层和硬件抽象层调用。- 代码库:
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]
- 可执行文件
- 代码库: