车载技术开发—{Android CarFrameWork}
Android Automotive平台
Android Automotive是通过Android的通用框架,语言和API来实现的一个全栈,开源,高度可定制的平台。
Android Automotive与整个Android生态系统的关系
- Android Automotive是Android的一部分。 Android Automotive不是Android的分支或并行开发,它与手机,平板电脑等安卓设备上的Android具有相同的代码库,并且位于相同的存储库中。它基于经过10多年开发的强大平台和功能集,可利用现有的安全模型,兼容性程序,开发人员工具和基础架构,同时继续具有高度可定制性和可移植性,完全免费和开源的特点。
- Android Automotive扩展了Android 。在将Android打造为功能齐全的信息娱乐平台的过程中,我们添加了对汽车特定要求,功能和技术的支持。就像今天用于移动设备的Android一样,Android Automotive将是一个完整的汽车信息娱乐平台。
Android Automotive架构

Automotive
Android Automative是在原先Android的系统架构上增加了一些与车相关的(图中虚线框中绿色背景的)模块。
- Car App :包括OEM和第三方开发的App
- Car API :提供给汽车App特有的接口
- Car Service :系统中与车相关的服务,主要是基于CarProperty实现Vechile相关的一些策略
- Vehicle Network Service :汽车的网络服务
- Vehicle HAL :汽车的硬件抽象层描述,定义 OEM 可以实现的车辆属性的接口
Android CarAPI

CarAPI
· annotation:包含了两个注解。 · app · menu:车辆应用菜单相关API。 · cluster:仪表盘相关API。 · render:渲染相关API。 · content · pm:应用包相关API。 · diagnostic:包含与汽车诊断相关的API。 · hardware:车辆硬件相关API。 · cabin:座舱相关API。 · hvac:通风空调相关API。 · property:属性相关API(实现定制的property)。 · radio:收音机相关API。 · input:输入相关API。 · media:多媒体相关API。 · navigation:导航相关API。 · settings:设置相关API。 · vms:汽车监测相关API
这些api集合中,我们可以通过CarpropertyManager去实现定制的property功能,简要类图:

CarpropertyManager内部方法
- 通过registerListener注册自定义的propertyId以及property变更通知的callback

- 解注册CarpropertyEventListener

- 获取所有property, 返回一个元素类型是CarpropertyConfig的list

- 获取property状态

- 获取property value

- 设置property value

CarpropertyManager与service层交互的AIDL接口


需要注意的是ICarProperty是同步接口,ICarPropertyEventListener是异步接口。
onEvent传上来的是参数是CarPropertyEvent的list,CarPropertyEvent中包含event type与CarPropertyValue; eventType包含PROPERTY_EVENT_PROPERTY_CHANGE与PROPERTY_EVENT_ERROR,分别对应listener中的onPropertyChanged和PROPERTY_EVENT_ERROR, CarPropertyValue则包含具体的propId、propValue等具体属性信息。
Android CarService
代码目录: packages/services/Car/service
- CarService并非一个服务,而是一系列的服务。这些服务都在ICarImpl.java构造函数中列了出来

CarService启动流程

启动CarServiceHelperService
SystemServer启动过程中,在ActivityManagerService systemReady时,启动CarServiceHelperService。 代码:
android/frameworks/base/services/java/com/android/server/SystemServer.java
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {t.traceBegin("StartCarServiceHelperService");final SystemService cshs = mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);if (cshs instanceof Dumpable) {mDumper.addDumpable((Dumpable) cshs);}if (cshs instanceof DevicePolicySafetyChecker) {dpms.setDevicePolicySafetyChecker((DevicePolicySafetyChecker) cshs);}t.traceEnd();
}
private static final String CAR_SERVICE_HELPER_SERVICE_CLASS ="com.android.internal.car.CarServiceHelperService";
启动CarService
CarServiceHelperService在onStart时拉起CarServcie,加载Native库car-framework-service-jni。
代码:
android/frameworks/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java
public void onStart() {EventLog.writeEvent(EventLogTags.CAR_HELPER_START);
IntentFilter filter = new IntentFilter(Intent.ACTION_REBOOT);filter.addAction(Intent.ACTION_SHUTDOWN);mContext.registerReceiverForAllUsers(mShutdownEventReceiver, filter, null, null);mCarWatchdogDaemonHelper.addOnConnectionChangeListener(mConnectionListener);mCarWatchdogDaemonHelper.connect();Intent intent = new Intent();intent.setPackage("com.android.car");intent.setAction(CAR_SERVICE_INTERFACE);if (!mContext.bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,mHandler, UserHandle.SYSTEM)) {Slogf.wtf(TAG, "cannot start car service");}loadNativeLibrary();
}
void loadNativeLibrary() {System.loadLibrary("car-framework-service-jni");
}
代码:
android/packages/services/Car/car-lib/src/com/android/car/internal/common/CommonConstants.java
public static final String CAR_SERVICE_INTERFACE = "android.car.ICar";
代码:
android/packages/services/Car/service/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"package="com.android.car"coreApp="true"android:sharedUserId="android.uid.system">
<application android:label="@string/app_title"android:directBootAware="true"android:allowBackup="false"android:persistent="true"><service android:name=".CarService"android:singleUser="true"android:exported="true"><intent-filter><action android:name="android.car.ICar"/></intent-filter></service>
初始化ICarImpl
CarService在onCreate时先判断Vehicle HAL起来了,然后再初始化ICarImpl。 代码:
android/packages/services/Car/service/src/com/android/car/CarService.java
public void onCreate() {LimitedTimingsTraceLog initTiming = new LimitedTimingsTraceLog(CAR_SERVICE_INIT_TIMING_TAG,Trace.TRACE_TAG_SYSTEM_SERVER, CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS);initTiming.traceBegin("CarService.onCreate");
initTiming.traceBegin("getVehicle");mVehicle = getVehicle();initTiming.traceEnd();EventLog.writeEvent(EventLogTags.CAR_SERVICE_CREATE, mVehicle == null ? 0 : 1);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);}Slog.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName);EventLog.writeEvent(EventLogTags.CAR_SERVICE_CONNECTED, mVehicleInterfaceName);mICarImpl = new ICarImpl(this,mVehicle,SystemInterface.Builder.defaultSystemInterface(this).build(),mVehicleInterfaceName);mICarImpl.init();linkToDeath(mVehicle, mVehicleDeathRecipient);ServiceManager.addService("car_service", mICarImpl);SystemProperties.set("boot.car_service_created", "1");super.onCreate();initTiming.traceEnd(); // "CarService.onCreate"
}
private static IVehicle getVehicle() {final String instanceName = SystemProperties.get("ro.vehicle.hal", "default");
try {return android.hardware.automotive.vehicle.V2_0.IVehicle.getService(instanceName);} catch (RemoteException e) {Slog.e(CarLog.TAG_SERVICE, "Failed to get IVehicle/" + instanceName + " service", e);} catch (NoSuchElementException e) {Slog.e(CarLog.TAG_SERVICE, "IVehicle/" + instanceName + " service not registered yet");}return null;
}
代码:
android/packages/services/Car/car-lib/src/android/car/ICar.aidl
android/packages/services/Car/service/src/com/android/car/ICarImpl.java
初始化各个Car Services组件
ICarImpl构造函数中,构造了下面几个实现了CarServiceBase接口的Car Services组件,以及VehicleHal和CarStatsService;然后通过init函数进行初始化。
CarFeatureController
CarPropertyService
CarDrivingStateService
CarUxRestrictionsManagerService
CarUserService
CarOccupantZoneService
SystemActivityMonitoringService
CarPowerManagementService
CarUserNoticeService
CarPackageManagerService
PerUserCarServiceHelper
CarBluetoothService
CarInputService
CarProjectionService
GarageModeService
AppFocusService
CarAudioService
CarNightService
FixedActivityService
ClusterNavigationService
InstrumentClusterService
VmsBrokerService
CarDiagnosticService
CarStorageMonitoringService
CarLocationService
CarMediaService
CarBugreportManagerService
CarExperimentalFeatureServiceController
CarWatchdogService
CarDevicePolicyService
ClusterHomeService
CarEvsService
CarTelemetryService
CarActivityService
初始化各个Hal Services组件
VehicleHal构造函数中,构造了下面几个继承自HalServiceBase基类的Hal Services组件以及HalClient;然后通过init函数进行初始化。
PowerHalService
PropertyHalService
InputHalService
VmsHalService
UserHalService
DiagnosticHalService
ClusterHalService
EvsHalService
TimeHalService
代码:
android/packages/services/Car/service/src/com/android/car/hal/VehicleHal.java
VehicleHAL目录结构
下面是vehicle 2.0参考实现的目录结构。
android/hardware/interfaces/automotive/vehicle/2.0/
|-- default // 默认实现|-- common|-- include|-- vhal_v2_0 // .h|-- src // .cpp|-- impl|-- vhal_v2_0 // impl代码|-- proto // proto协议|-- tests|-- tests|-- Android.bp // 编译文件|-- VehicleService.cpp // main函数|-- android.hardware.automotive.vehicle@2.0-service.rc // init rc|-- android.hardware.automotive.vehicle@2.0-service.xml // matrix xml
|-- utils
|-- vts
|-- Android.bp // 编译文件
|-- IVehicle.hal // interface
|-- IVehicleCallback.hal // callback
|-- types.hal // types
Hidl代码有个明显的namespace规则,如下。
namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
namespace V2_0 {
// ...
} // namespace V2_0
} // namespace vehicle
} // namespace automotive
} // namespace hardware
} // namespace android
VehicleHAL启动流程
rc
VehicleHAL由init rc启动。 代码:
android/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-serviceclass early_haluser vehicle_networkgroup system inet
main
下面是VehicleHAL的main函数。 代码:
android/hardware/interfaces/automotive/vehicle/2.0/default/VehicleService.cpp
int main(int /* argc */, char* /* argv */ []) {auto store = std::make_unique<VehiclePropertyStore>();auto connector = std::make_unique<impl::EmulatedVehicleConnector>();auto userHal = connector->getEmulatedUserHal();auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal);auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());auto service = std::make_unique<VehicleHalManager>(hal.get());connector->setValuePool(hal->getValuePool());
configureRpcThreadpool(4, true /* callerWillJoin */);ALOGI("Registering as service...");status_t status = service->registerAsService();if (status != OK) {ALOGE("Unable to register vehicle service (%d)", status);return 1;}ALOGI("Ready");joinRpcThreadpool();return 1;
}
- VehiclePropertyStore:存储、访问和修改vehicle相关的配置及属性,VehiclePropertyValues存储在有序map中。使用了同步锁,线程安全。
- EmulatedVehicleConnector:VehicleHalClient与VehicleHalServer通信的连接器。
- EmulatedUserHal:User Hal。
- EmulatedVehicleHal:Vehicle Hal。
- VehicleEmulator:Vehicle Emulator。
- VehicleHalManager:This class is a thick proxy between IVehicle HIDL interface and vendor’s implementation.

以上为车机开发技术中的CarFrameWork学习;启动流程及原理介绍,更多的车载技术可以前往《车机开发技术手册》查看更多车载技术。
交互
CarService向上与App通过CarLib(aidl)交互,向下与VehicleHAL通过hidl交互,其中包括了一个很重要的概念:Property。 Property可以是静态的,也可以是变化后向上通报的,还可以是以一定的频率实时上报的。 下面以HVAC为例,说明HVAC的控制过程。
- 【App】调用CarLib中【CarHvacManager】的setBooleanProperty设置Property。
- 【CarHvacManager】调用CarLib中【CarPropertyManager】的setBooleanProperty。
- 【CarPropertyManager】将Property封装成CarPropertyValue后调用CarServcie中【ICarProperty-CarPropertyService】的setProperty。(aidl) 【CarPropertyService】调用CarServcie中【PropertyHalService】的setProperty。
- 【PropertyHalService】将CarPropertyValue封装成VehiclePropValue后调用CarServcie中【VehicleHal】的set。
- 【VehicleHal】调用CarServcie中【HalClient】的setValue。
- 【HalClient】调用VehicleHAL中【IVehicle-VehicleHalManager】的set。(hidl)
- 【VehicleHalManager】,首先,通过订阅这个Property的【Native HalClient】的callback即【IVehicleCallback-HalClient$VehicleCallback】的onPropertySet通知Property变更。(hidl callback)
- 【VehicleHalManager】,然后,调用【EmulatedVehicleHal】的set。
- 【EmulatedVehicleHal】检查Property后调用【VehicleHalClient】的setProperty。
- 【VehicleHalClient】与EmulatedVehicleConnector有关,调用【EmulatedVehicleConnector】的onSetProperty。
- 【EmulatedVehicleConnector】与VehicleHalServer有关,调用【VehicleHalServer】的onSetProperty。
最终,将Property或转换后的信号发到【Car ECU】。vehicle 2.0模拟实现是将Property存储到VehiclePropertyStore
相关文章:
车载技术开发—{Android CarFrameWork}
Android Automotive平台 Android Automotive是通过Android的通用框架,语言和API来实现的一个全栈,开源,高度可定制的平台。 Android Automotive与整个Android生态系统的关系 Android Automotive是Android的一部分。 Android Automotive不是…...
多城市二手车买卖发布管理小程序开发
多城市二手车买卖发布管理小程序开发 功能特性: 为你介绍二手车微信小程序的功能特性。 车辆分类搜索,支持按品牌、售价、年龄、上牌时间、排量等筛选。 车源发布,支持用户一键发布二手车,平台审核上线,发布可编辑、删除等操作。…...
企业级信息系统开发学习笔记1.2 初探Spring——利用组件注解符精简Spring配置文件
文章目录零、本讲学习目标一、课程引入二、打开项目 - SpringDemo三、利用组件注解符精简Spring配置文件(一)创建新包(二)复制四个类(三)修改杀龙任务类(四)修改救美任务类ÿ…...
37、基于51单片机乒乓球比赛系统设计
摘要 乒乓球游戏电路是一个对输入信号、输入时机正确与否的8个LED表示乒乓球球台和乒乓球,用数码管模拟显示器,显示比赛局数比分和每局玩家得分的电路。电路并不复杂,整体分为两个模块:一,游戏主模块;二&a…...
VMware虚拟机安装Win11最详细过程以及遇到的这台电脑无法运行Windows11的问题
准备工作 在使用VMware虚拟机安装Win11之前我们先把准备工作做好,以免后续思绪混乱导致出错。 1. 到VMware官网或点击链接下载正版VMware Workstation 16 Pro。 2. 双击打开安装包,点击下一步。 3. 阅读用户许可协议,勾选我接受许可协议中的…...
centos误删python2后怎么重新安装
此教程为离线安装 一. 先查询系统版本 cat /proc/version Linux version 3.10.0-1127.el7.x86_64 (mockbuildkbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ) #1 SMP Tue Mar 31 23:36:51 UTC 2020 二. 安装python2.7.5(已知原python版…...
Qt 开发使用VSCode 笔记2
在之前有写过使用VSCode开发QT的笔记 Qt 开发使用VSCode 在以前的基础上继续学习记录写下《Qt 开发使用VSCode 笔记2》 该笔记相比之前的Qt 开发使用VSCode新加了如下内容: 工作区的使用使用Natvis进行Qt感知对象可视化通过vscode创建QT Quick项目 工作区的使用 …...
查找算法复习
先序在了解查找算法之前,需要熟悉几个概念,不然后面容易产生理解错误。查找表:即被查找的对象,通常由几个关键字组成。关键字:就是数据项、字段的意思。关键字有主次之分,其中主关键字取值是唯一的。查找长…...
腾讯前端必会面试题(必备)
如何提取高度嵌套的对象里的指定属性? 有时会遇到一些嵌套程度非常深的对象: const school {classes: {stu: {name: Bob,age: 24,}} }像此处的 name 这个变量,嵌套了四层,此时如果仍然尝试老方法来提取它: const {…...
探访上汽通用武汉奥特能超级工厂
上汽通用汽车在电动化和智能网联化新技术领域投入了700亿大洋,武汉奥特能超级工厂就是其中一个重点项目。这个工厂已经投产,将成为上汽通用汽车的新能源生产基地,加速奥特能平台车型的推出。 最近别克推出了Electra E5,它是别克第…...
【Linux】线程函数和线程同步详细整理(金针菇般细)
目录 一,线程函数 1.获取当前线程ID 2.创建线程 3.退出线程 4.阻塞线程 5.分离线程 6.取消线程 7.线程比较 8.测试代码(线程函数总结) 二,线程同步 1.互斥锁 2.读写锁 3.条件变量 4.信号量 一,线程函数 …...
Python学习笔记6:抽象
抽象 函数 判断某个对象是否可调用,可使用内置函数callable >>> import math >>> x 1 >>> y math.sqrt >>> callable(x) False >>> callable(y) True斐波那契数组 def fibs(num): result [0, 1] for i i…...
自己手写一个redux
提起 Redux 我们想到最多的应该就是 React-redux 这个库,可是实际上 Redux 和 React-redux 并不是同一个东西, Redux 是一种架构模式,源于 Flux。 React-redux 是 Redux 思想与 React 结合的一种具体实现。 在我们使用 React 的时候,常常会遇…...
mysql调优参数
my.conf [client] port 端口 socket sokcet位置 [mysqld] basedir mysql位置 port 3306 socket sokcet位置 datadir data目录 pid_file mysqld.pid位置 bind_address 0.0.0.0 lower_case…...
JavaEE简单示例——再插入的同时获取插入的主键列
简单介绍: 在某些时候,我们在插入完成一条语句之后,我们会想要返回之前插入的这条语句的主键列的数据,进行下一步的展示或者修改,我们就可以使用MyBatis的主键回写功能,帮助我们获取插入成功的一条数据的主…...
sql语句练习
一、现有以下两张表:第一张表名为cust,其表结构如下:第二张表名为mark,其表结构如下:1) [5分]请写出计算 所有学生的英语平均成绩的sq|语句。2) [5分]现有五 个学生,其学号假定分别为11,22,33,44,55;请用一条SQL语句实现列出这五个…...
广州蓝景—结合chatGPT下的教育模式变化
最近爆火的人工智能AI聊天工具ChatGPT,不仅在互联网,更是在各行各业中,得到了广泛的传播,应该没有哪一个不知道它的存在,但其实你又是否知道,其实ChatGPT是一类模型的统称,随着人工智能的快速发…...
大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——shuffle机制
3.3.1Shuffle机制 Map方法之后,Reduce方法之前的数据处理过程称之为Shuffle。 3.3.2Partition分区 1、问题引出 要求将统计结果按照条件输出到不同文件中(分区)。比如:将统计结果按照手机归属地不同省份输出到不同文件中&#…...
4|无线传感器网络与应用|无线传感器网络原理及方法-许毅版|第3章:无线传感器网络通信-3.1协议结构 3.2物理层|青岛科技大学|课堂笔记
第3章:无线传感器网络通信3.1协议结构3.1.1 OSI参考模型1.网络通信协议MAC层和物理层采用IEEE 802.15.4协议*(1)物理层wsn物理层负责信号的调制和数据的收发,传输介质:无线电、红外线、光波等。(2)数据链路层wsn数据链路层负责数据成帧、帧检…...
关机时,如何控制systemd服务的关闭顺序
关机时,如何控制systemd服务的关闭顺序? 在工作中,我们通常遇到的问题是,如何控制systemd服务的启动顺序,同志们第一反应就会是使用Before或者After去进行控制。 问题来了,如果服务启动时没有顺序要求,但…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
