Android Automotive (二)系统架构

前面简单介绍了一下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

CarServiceCarService只作为服务的入口,具体的业务逻辑都在内部的子服务中处理,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启动

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");
    }
}
  1. SystemServerActivityManagerService.systemReady后会通过SystemServiceManager启动CarServiceHelperService
  2. 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>

通过在CarServiceAndroidManifest的配置,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服务android.hardware.automotive.vehicle@2.0-service,负责处理车辆相关的业务。

硬件抽象层的模块位于源码目录下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/android.hardware.automotive.vehicle@2.0-service.rc

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接口语言

从硬件抽象层到系统框架层,也就是从VehicleServiceCarService,从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 haldump信息

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: "android.hardware.helloworld@1.0",
    root: "android.hardware",
    vndk: {
        enabled: true,
    },
    srcs: [
        "IHelloWorld.hal",
    ],
    interfaces: [
        "android.hidl.base@1.0",
    ],
    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
  • 编译模块:android.hardware.automotive.vehicle@2.0
  • 编译产物:
  • android.hardware.automotive.vehicle-V2.0-java.jar
  • android.hardware.automotive.vehicle@2.0.so
  • 硬件抽象层
  • 代码库: hardware/interface/automotive/vehicle/2.0/default
  • 编译模块:
  • vhal_v2_0_defaults
  • vhal_v2_0_target_defaults
  • vhal_v2_0_common_headers
  • android.hardware.automotive.vehicle@2.0-manager-lib
  • android.hardware.automotive.vehicle@2.0-default-impl-lib
  • android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib
  • android.hardware.automotive.vehicle@2.0-server-common-lib
  • android.hardware.automotive.vehicle@2.0-server-impl-lib
  • android.hardware.automotive.vehicle@2.0-service
  • 编译产物:
  • 可执行文件 android.hardware.automotive.vehicle@2.0-service
  • 动态库 android.hardware.automotive.vehicle@2.0-manager-lib.so
  • 静态库 android.hardware.automotive.vehicle@2.0-default-impl-lib.a