车载 Android之 核心服务 - CarPropertyService 解析

news2024/11/17 7:36:16

重要类的源码文件名及位置:

  • CarPropertyManager.java

packages/services/Car/car-lib/src/android/car/hardware/property/

  • CarPropertyService.java

packages/services/Car/service/src/com/android/car/

类的介绍:

CarPropertyManager:是CarPropertyService在客户端的代理,通过 CarPropertyManager中 提供的 API,可以设置和获取车辆各个属性的状态。但在实际使用时,CarPropertyManager 却未必是开发者使用最频繁的对象。尤其是在 Android9平台上开发时,当开发者想控制 空调相关的功能的时候,也许会使用 CarHvacManager;当想获取车辆信息的时候,也许会 使用 CarInfoManager;当想获取车辆传感器数据的时候,会使用 CarSensorManager。但其 实无论是 CarHvacManager还是 CarInfoManager或是 CarSensorManager,它们最后都会 通过 CarPropertyManager来获取设置属性,在服务端对应的都是 CarPropertyService。通 过ICarImpl中getCarService方法也可以很清楚地发现这一点,在Android 10中,谷歌官方直接推荐使用CarPropertyManager;

CarPropertyService:绝大部分与车辆硬件相关联的属性,如空调、车舱功能、车辆传感器等都是通过CarPropertyService来读取或者设置的。

类的使用:

CarPropertyManager:在安卓9中CarPropertyManger还是隐藏(hide)接口,所以不会在公开的SDK中出现,但是它十分重要。而在Android 10中,CarPropertyManger变成了车辆属性的主要API,并允许任何运行在Android Automotive OS上的应用进行调用。初看CarPropertyManger会觉得很熟悉,它的方法包括(但不限于)以下这些:

boolean registerListener(CarPropertyEventCallback callback, int prop, float rate)
boolean isPropertyAvailable(int propId, int area) 
boolean getBooleanProperty(int prop, int area)
float getFloatProperty(int prop, int area)
int getIntProperty(int prop, int area)
int[] getIntArrayProperty(int prop, int area)
<E> CarPropertyValue <E> getProperty(Class <E> clazz, int propId, int area) 
<E> CarPropertyValue <E> getProperty(int prop, int area)
<E> void setProperty()(Class <E> clazz, int propId, int area,E val) 
void setBooleanProperty(int prop, int area, boolean val)
void setFloatProperty (int prop int area, float val)
void setIntProperty (int prop, int area, int val) 

看到这些方法,就会发现和 CarHvacManager、CarVendorExtensionManager等服务中 的方法定 义 很 类 似。在 使 用 方 法 上 和 之 前 提 到 的 几 个 服 务 也 是 一 样 的。其 实,无 论 是 CarInfoManager,还是 CarSensorManager或 CarHvacManager,它们的功能都可以直接通 过 CarPropertyManager来完成。

1.CarPropertyManager的用法

熟悉了 CarHvacManager、CarVendorExtensionManager等几个相关服务的用法之后, 在 CarPropertyManager的使用上,相信读者对相关方法已经很了解了。这里再做一些简单 的补充。 关于属 性 的 获 取,在 CarPropertyManager 中 除 了 getProperty 方 法 之 外,还 有 像 getBooleanProperty、getIntProperty这样明确属性类型的获取方法。其实这些方法只是对 于getProperty方法的封装,以getIntProperty为例,它的实现是这样的:

看上去在明确知道属性类型的情况下,getBooleanProperty、getIntProperty等方法在 使用上更加简洁。但是在这里,依然推荐开发者们使用getProperty来获取相应的属性值, 因为getProperty方法返回的是 CarPropertyValue对象,其不仅包含属性值,还包含属性的 状态,而getIntProperty等方法在属性不可用的情况下,返回的是默认值,这在有的时候会 导致读取的数据不正确。 下面以 NIGHT_MODE(昼夜模式)属性为例,说明使用getProperty方法的好处。

从这段源码中,可以很直观地看到使用getProperty方法,与getBooleanProperty方法 获取昼夜状态相比,可以更准确地判断当前属性的状态,并在属性不支持或不可用时,使用 更合理的处理逻辑。因此,虽然 getProperty方法会增加源码的数量,但在大部分情况下, 依然推荐大家使用该方式获取属性。

        在注册 监 听 属 性 变 化 方 面,CarPropertyManager 提 供 更 细 颗 粒 度 的 监 听 方 法, registerListener① 方法可以监听单个属性值的变化,开发者可以通过在注册监听器时传入 属性ID指定监听器所对应的属性。同时,可以指定数据上报的频率,与5.2节介绍的一样, 该频率与属性类型和其他监听器的频率有关,并不能保证数据会以传入的期望频率进行上 报。监听属性的方式,可参考以下源码:

CarPropertyManager.CarPropertyEventListener mCarPropertyEventListener = new CarPropertyManager.CarPropertyEventListener() {
        @Override
        public void onChangeEvent(CarPropertyValue value) {

        }

        @Override
        public void onErrorEvent(int propId, int zone) {
        }
    };

    mCarPropertyManager.registerListener(mCarPropertyEventListener,VehiclePropertyIds.PERF_VEHICLE_SPEED,/ * rate=* / 5);

2.CarPropertyManager的相关类

除了和 CarPropertyManager相关的这几个 Manager之外,在之前的例子中,还出现了 如 VehiclePropertyIds、CarPropertyValue、CarPropertyConfig等相关的辅助类,由于种类 繁多,有必要在这里梳理一下各个辅助类的作用。

(1)VehiclePropertyIds,CarPropertyManager都是通过属性ID来对应具体的功能的, 不同功能对应不同的ID,VehiclePropertyIds中列出了所有在 VehicleHAL 中定义的功能 属性,是AndroidAutomotiveOS官方定义的属性集合。

(2)VehicleAreaDoor,许多功能点都分多个区域,在设置、获取相应属性时,需要传入区域 参数,VehicleAreaDoor定义了与车门相关的区域值,在使用与车门相关的属性时配套使用。

(3)VehicleAreaMirror,与 VehicleAreaDoor类似,多区域定义,后视镜区域值。

(4)VehicleAreaSeat,多区域定义,座位区域值。

(5)VehicleAreaWheel,多区域定义,车胎区域值。

(6)VehicleAreaWindow,多区域定义,车窗区域值。

(7)VehicleAreaType,区域类型是用以区分一个属性所对应的位置的。对于非多区域 属性,往往使用 VEHICLE_AREA_TYPE_GLOBAL 作为其区域ID。每个区域属性都必 须使用预定义的区域类型,即车门、车窗、座椅、轮胎、后视镜中的一个。每种区域类型都有 一组在区域类型的枚举中定义的位标记,也就是前文中使用的像SEAT_ROW_1_LEFT 这 53 第 5 章 CarPropertyService———车辆属性服务 样具体的区域值。

(8)VehicleLightState,灯光状态,开、关、日间。

(9)VehicleLightSwitch,灯光切换,开、关、日间、自动。

(10)VehicleOilLevel,油量状态。

以上这些辅助类中,都定义了相关的静态变量,同时,这些值都与 VehicleHAL 的相关 定义一一对应,在 CarAPI中将其再次定义是为了方便上层应用使用。

        除了以上 几 个 定 义 静 态 变 量 的 辅 助 类 以 外,还 会 经 常 用 到 CarPropertyConfig 和 CarPropertyValue这两个模板类。CarPropertyConfig和 CarPropertyValue非常有用,通 过前者能获取到一个属性的静态参数,如取值范围、类型、支持的区域等;通过后者能获取 一个属性的值和状态。

        这里举两个简单的例子。

        (1)通过 CarPropertyManager获取当前车辆支持的属性(注意,需要拥有对应属性的 权限才能获取)。

CarPropertyConfig对象的成员变量如表5-4所示。

开发者可以通过以上成员变量对应的 get方法获取具体的值。对于区域属性来说, CarPropertyConfig中还封装了额外的方法方便开发者获取特定区域的取值,AreaConfig类 的getMinValue、getMaxValue方法可以返回某一属性特定区域的取值范围。

        (2)通过 CarPropertyManager获取当前的车速。

        CarPropertyValue对象的成员变量如表5-5所示。

虽然看上去很简单,但实际使用过程中会涉及较多的判断,开发者可以进一步对属性进 行封装管理,并总结一些有用的实践。CarPropertyConfig和 CarPropertyValue这两个类 同样 和 VehicleHAL 中 的 定 义 的 结 构 体 相 关 联,CarService 会 将 从 HAL 层 获 取 的 VehiclePropConfig和 VehiclePropValue① 分别转换为CarPropertyConfig和CarPropertyValue。

3.进一步了解 CarPropertyManager 

通过前文的介绍,读者应该已经了解了 CarPropertyManager的重要性。因此有必要进 一步了解 CarPropertyManager背后的原理,更全面地掌握它。 熟悉 Android的读者应该知道,在 Android中往往一个 Manager会对应一个Service,例如 ActivityManager对应着 ActivityManagerService;PackageManager对应着PackageManagerService。 它 们 运 行 在 不 同 的 进 程 中,通 过 Binder 这 一 IPC 机 制 进 行 通 信。 同 样 地,与 CarPropertyManager相对应的是 CarPropertyService这一服务。 同时,读者如果对车辆电子电器的架构有一定了解,那么应该知道,各个具体的功能往 往有对应的电子控制单元(ElectronicControlUnit,ECU)进行控制。例如,控制座椅位置 的命令,最终需要发送到负责控制座椅的 ECU 中才能使座椅移动。 因此,一次控制命令的调用过程大致如图5-1所示。

上层的应用通过 CarAPI提供的接口进行设置,最终通过车辆总线将命令发送给对应 的 ECU,ECU 返 回 结 果 给 CarService,并 通 过 回 调 通 知 相 关 应 用。 这 一 过 程 中 的 ① VehiclePropConfig和 VehiclePropValue定义在/hardware/interfaces/automotive/vehicle/2.0/types.hal文件中。 55 第 5 章 CarPropertyService———车辆属性服务 VehicleHAL非 常 重 要,它 指 的 是 制 造 商 实 现 的 硬 件 抽 象 层 服 务,实 现 了 Android AutomotiveOS定义的相关硬件抽象层接口。由于不同汽车制造商与ECU 的通信方式、标 准、数据格式都不尽相同,所以需要对其进行抽象,统一接口,而具体逻辑则由汽车制造商自 己实现。关于 VehicleHAL的具体内容,会在后面的章节再展开。 下面通过源码,进一步了解 CarPropertyManager中的具体实现,建议读者在阅读的同 时打开源码文件进行查看。 以下是 CarPropertyManager的构造函数实现:

在 CarPropertyManager的构造函数中,获得了ICarProperty的远程对象,通过该远程 对象就可以调用 CarPropertyService。关于 Binder机制的具体实现及 AIDL 的调用过程, 在此就不做展开了①。 再来看看 CarPropertyManager的setProperty的调用过程:

通过 mService对象,调用 CarPropertyService中对应的方法:

这里出现了一个新的对象 mHal,它是 PropertyHalService对象的实例。

接着调用 VehicleHal的set方法,虽然对象命名叫 VehicleHal,但该 VehicleHal对象 依然是在CarService进程中定义并创建的对象。还没有看到对 HAL层的Binder调用。接着往下:

VehicleHal中的set方法只是进一步调用了 HalClient对象的setValue方法。

在 HalClient的setValue方法中,终于发现这个 mVehicle对象是一个 HIDL调用的远 程对象,通过它,实际上调用的是抽象层 VehicleHal的实现。这里涉及了 Android8.0引入 的 HIDL机制,不详细展开了①。随着 HIDL 机制的引入,VehicleHal运行在独立的进程 中,由设备制造商或汽车制造商进行实现。

        以上就是一次完整的设置属性值的调用过程,可以看到设置命令最终将发送给制造商 实现的 VehicleHal进程,并由 VehicleHal最终完成该次调用。

        再来追踪 VehicleHal中的事件的传递过程。

        通过设置的流程,可以发现发起 HIDL调用的远程对象是被 HalClient对象所持有的, 与 VehicleHal的 直 接 交 互 是 在 HalClient 中 完 成 的。 因 此 事 件 的 向 上 传 递 也 是 从 HalClient开始的。在收到上报的事件之前,上层应用首先要注册相应的监听方法。

        当应用调用 CarPropertyManager的registerListener方法时,其会调用 CarPropertyService 的registerListener方法。

上述源码进一步 调 用 PropertyHalService的 subscribeProperty 方 法,中 间 会 再 经 过 VehicleHal.java的调用,最后调用 HalClient中的subscribe方法,调用的路径和设置的流 程是一样的。在此省略一些中间过程,直接来看 HalClient的subscribe方法的实现:

  这里将 mInternalCallback对象传递给了 Hal层。mInternalCallback对象的实例是继 承了IVehicleCallback.Stub的 HIDL桩对象,实现如下:              

通过IVehicleCallback,制造商实现的 VehicleHal进程就可以将事件传递给 CarService 进程了。有兴趣的读者可以进一步追踪当IVehicleCallback的onPropertyEvent方法被调 用后,事件又是如何传递给应用注册的监听器的。

        上文出现了一些新的对象,为了便于理解,整理上述类之间的关系,见图5-2。

在 CarService中虽然有 VehicleHal类,但该类并不直接调用 HIDL 方法,而是进一步 调 用 HalClient 封 装 的 方 法,HalClient 才 是 真 正 与 HAL 层 打 交 道 的 类。 同 时, PropertyHalService处理与 CarPropertyService相关的业务逻辑,在后面的内容中,还会接触 InputHalService、PowerHalService,VehicleHal会将不同的事件分发给对应的类进行处理。 总体来说,通过 CarPropertyService的层层调用,最后通过IVehicle与实现了车辆硬件 抽象层的进程通信。VehicleHal进程由各个厂家进行实现,再进一步将消息发送给关联的 ECU,实现控制功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1352533.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从信号处理角度彻底理解FFT

只想速览公式可以转到简明FFT公式 一、FFT起初用于解决的问题 分解复合信号 将复合信号视为若干正弦波与余弦波的叠加&#xff0c;如何得知某个正弦波/余弦波在该信号中的强度&#xff1f; 二、即答 用特定频率的正弦波/余弦波&#xff08;设其为a&#xff09;乘上复合信号…

Linux的引导过程与服务控制

一.开机启动的完整过程 引导过程&#xff1a; 1.bios加电自检 检测硬件是否正常&#xff0c;然后根据bios中的启动项设置&#xff0c;去找内核文件 服务器主机开机以后&#xff0c;将根据主板BIOS中的设置对CPU、内存、显卡、键盘灯设备进行初步检测&#xff0c;检测成功后根…

一个JSON.parse的问题,让我丢掉了字节的 offer!

前端训练营&#xff1a;1v1私教&#xff0c;终身辅导计划&#xff0c;帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer。微信在文章底部&#xff0c;欢迎来撩~~~~~~~~ Hello&#xff0c;大家好&#xff0c;我是 Sunday。 在几年前的一次字节跳动面试中&#xff0c…

HelloWorld搭建(第一种模型)

1.创建Springboot项目并且引入依赖 <!-- 引入RabbitMQ的相关依赖 --> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.7.2</version> </dependency> 2.第一种模式(直连…

企业生产安全指南,请点击文章查收!

随着科技的不断发展&#xff0c;视频监控系统在各个领域中扮演着越来越重要的角色。视频监控系统为企业和机构提供了强大的工具&#xff0c;以提高效率、增强安全性&#xff0c;并为决策制定提供实时数据支持。 客户案例 企业安全与生产管理 在现代企业环境中&#xff0c;保障…

产品|燕窝中的“秘密武器”——燕窝酸

前言 当提及燕窝&#xff0c;大部分人脑海中首先会闪过的大概是“宫廷圣品”、“名贵补品”等听上去十分高大上的形容词。然而随着现代人们生活水平的提高&#xff0c;燕窝已不再神秘&#xff0c;逐渐成为寻常百姓餐桌上的常见食品之一。据我国中医记载&#xff0c;燕窝具有养…

职场商务英语口语“自助餐”用英文怎么说?柯桥外语培训

“自助餐”用英语怎么说&#xff1f; ● 其实很简单&#xff0c;“自助餐”的英文就是&#xff1a;Buffet。 例句&#xff1a; At lunchtime, theres a choice between the buffet or the set menu.15857575376 午饭时&#xff0c;可以选择自助餐或套餐。 We are going to …

租赁小程序|北京租赁系统开发|租赁软件推动了行业发展

如今&#xff0c;租赁行业正在迅速发展&#xff0c;越来越多的商家和用户寻求更便捷、高效的租赁体验。租赁小程序作为一种科技创新的产物&#xff0c;为租赁行业带来了巨大的变革。本文将介绍租赁小程序的功能与特色&#xff0c;旨在让商家和用户更了解这一工具&#xff0c;为…

关于标准那些事——第六篇 四象之“朱雀”(要素的表述)

两仪生四象——东方青龙&#xff08;木&#xff09;、西方白虎&#xff08;金&#xff09;、南方朱雀&#xff08;火&#xff09;、北方玄武&#xff08;水&#xff09; 分别对应标准编写之四象——层次的编写、要素的编写、要素的表述、格式的编排。 今天来分享一下 要素的表…

Unity ShaderGraph 技能冷却转圈效果

Unity ShaderGraph 技能冷却转圈效果 前言项目场景布置代码编写ShaderGraph 连线总结 参考 前言 遇到一个需求&#xff0c;要展示技能冷却的圆形遮罩效果。 项目 场景布置 代码编写 Shader核心的就两句 // 将uv坐标系的原点移到纹理中心 float2 uv i.uv - float2(0.5, 0…

基于Springboot+vue医院管理系统(前后端分离)

最近有一些读者问我有没有完整的基于SpringbootVue的项目源码&#xff0c;今天给大家整理了一下&#xff0c;无偿分享给大家。 功能&#xff1a; 医生信息管理 换着信息管理 挂号信息管理 药物信息管理 检查项目管理 病床信息管理 排班信息管理 数据统计分析 开发工具…

仓储物流RFID智能管理设计解决方案

一、项目概况 1、项目背景 在物流管理中&#xff0c;仓储管理是至关重要的环节&#xff0c;传统的仓储管理存在诸多问题&#xff0c;如进出库操作混乱、库存报告延迟、货品属性不清晰、堆放混乱、盘点不准确等&#xff0c;这些问题需要通过基于信息化管理的技术进行彻底改造。…

「Qt Widget中文示例指南」如何实现一个日历?(一)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文中的CalendarWi…

开源MIT协议软件 - ChatGPT Admin Web

ChatGPT Admin Web 在团队和组织内共享使用人工智能的一站式解决方案。 ​编辑 ​编辑 ​编辑 CAW 是一个自托管网络应用程序&#xff0c;提供开箱即用的用户管理&#xff0c;包括后台界面以及可配置的支付计划和相关支付界面。 GitHub Sponsor / 爱发电 功能 Features …

React使用动态标签名称

最近在一项目里&#xff08;React antd&#xff09;遇到一个需求&#xff0c;某项基础信息里有个图标配置&#xff08;图标用的是antd的Icon组件&#xff09;&#xff0c;该项基础信息的图标信息修改后&#xff0c;存于后台数据库&#xff0c;后台数据库里存的是antd Icon组件…

【办公技巧】word文档怎么隐藏文字呢?word隐藏文字的四种方法!

Word文件制作完毕后&#xff0c;有些部分不想别让人看到&#xff0c;又不想删掉&#xff0c;把么我们可以隐藏文字&#xff0c;今天分享几个隐藏文字的方法给大家~ 方法一&#xff1a; 最简单的方法&#xff0c;将字体颜色与背景颜色设置为一致的&#xff0c;这样就达到了隐藏…

《Vue3 前端构建工具》 Vue-cli 与 Vite 创建项目的插件和配置对比

前言 2024 年 啦&#xff01;Vue2 也于 2023.12.31 寿终正寝 &#xff01; 然而我的 Vue3 升级一再拖延&#xff08;惭愧不已&#xff09;~ 赶起来吧~ 今天用 vue-cli 和 vite 分别创建了 Vue3 项目&#xff0c;具体实现步骤见如下两篇。 《基于 Vue Cli4.x Vue3 TS styl…

论文润色降重多少钱 智能写作

大家好&#xff0c;今天来聊聊论文润色降重多少钱 智能写作&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 标题&#xff1a;论文润色降重多少钱――了解市场行情与选择合…

【MPC学习笔记】02:MPC详细简介(Lecture 1_1 Unconstrained MPC)

本笔记来自北航诸兵老师的课程 课程地址&#xff1a;模型预测控制&#xff08;2022春&#xff09;lecture 1-1 Unconstrained MPC 接上一篇&#xff1a;【MPC学习笔记】01&#xff1a;MPC简介&#xff08;Lecture 1_1 Unconstrained MPC&#xff09; 文章目录 1 详细介绍1.1 状…

​ubuntu安装远程桌面 ​Xfce

本文最先发布在&#xff1a;https://www.itcoder.tech/posts/how-to-install-xrdp-on-ubuntu-20-04/ Xrdp 是一个微软远程桌面协议&#xff08;RDP&#xff09;的开源实现&#xff0c;它允许你通过图形界面控制远程系统。通过 RDP&#xff0c;你可以登录远程机器&#xff0c;并…