Android 应用层 到 HAL 层

news2024/11/16 21:30:14

Android 应用层 到 HAL 层

  • 1、相关知识点
    • 1.1 概要
    • 1.2 参考
  • 2、拿SensorService举例
    • 2.1 Android Apps ==> Android Framework阶段
    • 2.2 Android Framework内部阶段
      • 2.2.1 frameworks/base
      • 2.2.2 frameworks/native
    • 2.3 Android Framework ==> HAL 阶段
      • 2.3.1 旧版 HAL

1、相关知识点

1.1 概要

如下 AOSP软件堆栈架构图 主要跨两个阶段 Android Apps ==> Android Framework ==> HAL,这种IPC跨进程通信Android中必须要了解的相关知识点:1》Binder IPC通信机制;2》JNI调用;3》AIDL、HIDL接口定义语言

1》Binder IPC通信机制

IPC 域说明
/dev/binder框架/应用进程之间的 IPC,使用 AIDL 接口
/dev/hwbinder框架/供应商进程之间的 IPC,使用 HIDL 接口
供应商进程之间的 IPC,使用 HIDL 接口
/dev/vndbinder供应商/供应商进程之间的 IPC,使用 AIDL 接口

2》JNI调用
就是Java与C/C++互相调用,这不是Android系统所独有的,而是Java所有。Android表现:frameworks/baseframeworks/Native,以及其他SO库调用。

3》AIDL、HIDL接口定义语言:是Android中binder机制的具体实现,相应的binder域/dev/binder/dev/hwbinder/dev/vndbinder;Android规范的接口定义语言,按照规范aidl/hidl文件自动生成相应代码文件。

Android 接口定义语言相关Blogclient端 / server端
AIDLAndroid 接口定义语言 (AIDL)客户端获取proxy:asInterface(android.os.IBinder obj)
服务端实现Stub:class Stub extends android.os.Binder
HIDLAndroid 接口定义语言 (HIDL)在这里插入图片描述

AOSP软件堆栈架构图

1.2 参考

1》Binder IPC通信机制

序号文章名概述
0为什么 Android 要采用 Binder 作为 IPC 机制?【Android,在争议中逃离 Linux 内核的 GPL 约束】
0使用 Binder IPC多个 Binder 域:/dev/binder/dev/hwbinder/dev/vndbinder
1Binder系列1-Binder Driver/dev/binder运行在Linux kernel
2Binder系列2-ServiceManagerSM启动,添加/获取Service
3Binder系列3-framework层Zygote启动时AndroidRuntime::startReg中register_jni_procs(),JNI调用到Native
4Binder 域关注/dev/vndbinder与/dev/binder共用一套libbinder,defaultServiceManager()获取前需要切换
5Binder相关问题

2》JNI调用
Android JNI原理、Java本地调用(JNI)

3》AIDL、HIDL接口定义语言

Android 接口定义语言相关Blog
AIDLAndroid 接口定义语言 (AIDL)
HIDLAndroid 接口定义语言 (HIDL)

Android 8.0 重新设计了 Android 操作系统框架(在一个名为“Treble”的项目中),以便让制造商能够以更低的成本更轻松、更快速地将设备更新到新版 Android 系统。在这种新架构中,HAL 接口定义语言(HIDL,发音为“hide-l”)指定了 HAL 和其用户之间的接口,让用户无需重新构建 HAL,就能替换 Android 框架。在 Android 10 中,HIDL 功能已整合到 AIDL 中。此后,HIDL 就被废弃了,并且仅供尚未转换为 AIDL 的子系统使用。

在 Android 11 中,还支持使用 AIDL 编写的 HAL。所有 AIDL HAL 都是绑定的。
- 绑定的 HAL 。 HAL 以 HAL 接口定义语言 (HIDL) 或 Android 接口定义语言 (AIDL) 表示。这些 HAL 取代了早期 Android 版本中使用的传统 HAL 和遗留 HAL。在 Binderized HAL 中,Android 框架和 HAL 使用 Binder 进程间通信 (IPC) 调用相互通信。所有搭载 Android 8.0 或更高版本的设备必须仅支持绑定化 HAL。
-直通 HAL 。 HIDL 包装的传统 HAL 或旧版 HAL这些 HAL 包装现有的 HAL,并且可以在绑定和相同进程(直通)模式下为 HAL 提供服务。升级到 Android 8.0 的设备可以使用直通 HAL。

2、拿SensorService举例

2.1 Android Apps ==> Android Framework阶段

Android Apps ==> Android Framework阶段通过Android API调用,就是App编程调用的Android SDK


Activity中调用
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
获取加速度传感器Sensor.TYPE_ACCELEROMETER


更多查看APP获取Sensor对象-Android12;参考代码如下

public class SensorActivity extends Activity implements SensorEventListener {
    private final SensorManager mSensorManager;
    private final Sensor mAccelerometer;

    public SensorActivity() {
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }

    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    public void onSensorChanged(SensorEvent event) {
    }
}

2.2 Android Framework内部阶段

2.2.1 frameworks/base

Android Framework内部阶段:通过JNI调用Native层,如Android JNI原理、Java本地调用(JNI)中javac -h ./ xxx.java (javah是1.8及以前版本)生成相应xxxNative.h文件,

SersorManager.java对应相关代码:(在SystemServer启动时System.loadLibrary("android_servers");加载so库
frameworks/base/core/java/android/hardware/SensorManager.java
frameworks/base/core/java/android/hardware/SystemSensorManager.java
frameworks/base/core/jni/android_hardware_SensorManager.cpp
libnativehelper/include/nativehelper/JNIHelp.h
libnativehelper/include_jni/jni.h
frameworks/base/core/jni/core_jni_helpers.h

private static native boolean nativeGetSensorAtIndex(long nativeInstance,
		Sensor sensor, int index);

在这里插入图片描述

ssize_t count = mgr->getSensorList(&sensorList);

在这里插入图片描述

2.2.2 frameworks/native

通过binder IPC跨进程通信机制defaultServiceManager()获取到对应服务调用。如调用到服务frameworks/native/services/sensorservice

SersorManager.cpp对应相关代码:(SensorService.cpp 继承BinderService、BnSensorServer、Thread,初始化时添加到defaultServiceManager()中,更多查看SensorService启动-Android12
frameworks/native/libs/sensor/SensorManager.cpp
frameworks/native/libs/binder/include/binder/IServiceManager.h
frameworks/native/libs/binder/IServiceManager.cpp
frameworks/native/services/sensorservice/SensorService.cpp


这里的Bp端Bn端(BnSensorServer/BnSensorServer)手动撸代码,不是自动生成,所以这里关注transact()/onTransact()
frameworks/native/libs/sensor/include/sensor/ISensorServer.h
frameworks/native/libs/sensor/ISensorServer.cpp

NativeSensorService::NativeSensorService(JNIEnv* env, jobject listener)
      : mProximityActiveListenerDelegate(new ProximityActiveListenerDelegate(env, listener)) {
    if (base::GetBoolProperty("system_init.startsensorservice", true)) {
        sp<IServiceManager> sm(defaultServiceManager());
        mService = new SensorService();
        sm->addService(String16(SensorService::getServiceName()), mService,
                       false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
    }
}
Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.sensors", value, "0");
    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
            mSensors.getUserDebugSensors() : mSensors.getUserSensors();
    Vector<Sensor> accessibleSensorList;

    bool isCapped = isRateCappedBasedOnPermission(opPackageName);
    for (size_t i = 0; i < initialSensorList.size(); i++) {
        Sensor sensor = initialSensorList[i];
        if (isCapped && isSensorInCappedSet(sensor.getType())) {
            sensor.capMinDelayMicros(SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS / 1000);
            sensor.capHighestDirectReportRateLevel(SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL);
        }
        accessibleSensorList.add(sensor);
    }
    makeUuidsIntoIdsForSensorList(accessibleSensorList);
    return accessibleSensorList;
}

SensorService服务 通过frameworks/native/services/sensorservice/SensorService.cpp获取

SensorDevice& dev(SensorDevice::getInstance());
ssize_t count = dev.getSensorList(&list);

SensorDevice.cpp连接HAL层,如connectHidlServiceV2_1()

SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_1() {
   HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
   sp<V2_1::ISensors> sensors = V2_1::ISensors::getService();

   if (sensors == nullptr) {
       connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
   } else {
       mSensors = new ISensorsWrapperV2_1(sensors);
       connectionStatus = initializeHidlServiceV2_X();
   }

   return connectionStatus;
}

2.3 Android Framework ==> HAL 阶段

通过HIDL (Android 接口定义语言 (HIDL))文件hidl-gen 编译器自动生成,如继承实现#include <android/hardware/sensors/2.1/ISensors.h>

在这里插入图片描述在这里插入图片描述

2.3.1 旧版 HAL

hardware/libhardware/include/hardware/sensors.h
hardware/libhardware/modules/sensors/dynamic_sensor/sensors.cpp

旧版 HAL:HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现。借助 HAL,您可以顺利实现相关功能,而不会影响或更改更高级别的系统。本页面介绍了自 Android 8.0 开始已不再支持的旧版架构。对于 Android 8.0 及更高版本,请参阅 HAL 概览。

HAL 模块代表打包的 HAL 实现,这种实现存储为共享库 (.so file)。hardware/libhardware/include/hardware/hardware.h 头文件可定义一个代表模块的结构体 (hw_module_t),其中包含模块的版本、名称和作者等元数据。Android 会根据这些元数据来找到并正确加载 HAL 模块。

另外,hw_module_t 结构体还包含指向另一个结构体 hw_module_methods_t 的指针,后面这个结构体包含指向相应模块的 open 函数的指针。此 open 函数用于与相关硬件(此 HAL 是其抽象形式)建立通信。每个硬件专用 HAL 通常都会使用该特定硬件的附加信息来扩展通用的 hw_module_t 结构体。

实现 HAL 并创建模块结构体时,您必须将其命名为 HAL_MODULE_INFO_SYM

struct sensors_module_t HAL_MODULE_INFO_SYM = {
   .common = {
           .tag = HARDWARE_MODULE_TAG,
           .version_major = 1,
           .version_minor = 0,
           .id = SENSORS_HARDWARE_MODULE_ID,
           .name = "Google Dynamic Sensor Manager",
           .author = "Google",
           .methods = &sensors_module_methods,
           .dso  = NULL,
           .reserved = {0},
   },
   .get_sensors_list = get_sensors_list,
   .set_operation_mode = set_operation_mode,
};

在这里插入图片描述

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

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

相关文章

前段搜索框不请求接口隐藏数据

项目介绍&#xff1a;uview-ui 1.x的&#xff0c;并且使用语言切换功能&#xff08;i18n&#xff0c;hbuilder新建项目选择i18n项目&#xff09;&#xff0c;因为是h5项目&#xff0c;所以使用location.reload()进行刷新 效果图&#xff1a; 主要判断在 v-if“!keyword || i…

Git 之 reset --hard 回退/回滚到之前的版本代码后,后悔了,如何在恢复之后的版本的方法简单整理

Git 之 reset --hard 回退/回滚到之前的版本代码后&#xff0c;后悔了&#xff0c;如何在恢复之后的版本的方法简单整理 目录 Git 之 reset --hard 回退/回滚到之前的版本代码后&#xff0c;后悔了&#xff0c;如何在恢复之后的版本的方法简单整理 一、简单介绍 二、操作步骤…

Redis是什么?(详细安装步骤)

一、Redis简介&#x1f349; 背景 在Web应用发展的初期&#xff0c;那时关系型数据库受到了较为广泛的关注和应用&#xff0c;原因是因为那时候Web站点基本上访问和并发不高、交互也较少。而在后来&#xff0c;随着访问量的提升&#xff0c;使用关系型数据库的Web站点多多少少…

代码随想录二刷 day38 | 动态规划之 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

day38 509. 斐波那契数1 确定dp数组以及下标的含义2 确定递推公式3 dp数组如何初始化4 确定遍历顺序5 举例推导dp数组 70. 爬楼梯1 确定dp数组以及下标的含义2 确定递推公式3 dp数组如何初始化4 确定遍历顺序5 举例推导dp数组 746. 使用最小花费爬楼梯1 确定dp数组以及下标的含…

Golang每日一练(leetDay0113) 奇偶链表、链表随机节点

目录 328. 奇偶链表 Odd Even Linked-list &#x1f31f;&#x1f31f; 382. 链表随机节点 Llinked-list Random Node &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日…

docker安装php GD库

故事是这样的&#xff1a; 公司采购了一套商城源码&#xff0c;使用的是 TP5&#xff0c;同事先行&#xff0c;用宝塔部署到生产环境&#xff0c;运行正常。后面我忙完手里的项目&#xff0c;也加入其中&#xff0c;我本地使用的是 docker 当我部署好开始运行时&#xff0c;发…

初学mybatis(三)ResultMap及分页

学习回顾&#xff1a;初学mybatis&#xff08;二&#xff09; 一、查询为null问题 要解决的问题&#xff1a;属性名和字段名不一致 环境&#xff1a;新建一个项目&#xff0c;将之前的项目拷贝过来 1、查看之前的数据库的字段名 2、Java中的实体类设计 public class User {pri…

Redis各数据类型操作命令

一、Redis数据类型及命令 &#xff08;一&#xff09;String 类别命令描述命令示例备注取/赋值操作赋值set key valueset lclkey lclvalue取值 get keyget lclkey取值并赋值getset key valuegetset lclkey1 lclvalue1获取原值&#xff0c;并设置新的值仅当不存在时赋值setnx k…

服务器解析漏洞与cms靶场搭建教程

文章目录 一、解析漏洞定义二、Kali安装docker并搭建DVWA靶场三、Win7 IIS7漏洞复现四、BEES靶场搭建五、CPMS靶场搭建六、SDCMS靶场搭建 一、解析漏洞定义 解析漏洞主要是一些特殊文件被Apache、IIS、Nginx等Web服务器在某种情况下解释成脚本文件格式并得以执行而产生的漏洞 …

The Company Requires Superficial StudyPHP 变量的使用 ③

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; PHP MYSQL &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

基于Java电动车租赁网站设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

信号链噪声分析20

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 所有模数转换器(ADC)都有一定量的“折合到输入端噪声”&#xff0c;可以将其模拟为与无噪声 ADC 输入串联的噪声源。折合到输入端噪声与量化噪声不同&#xff0c;后者仅在 ADC 处理交流 信号时出现。多数情况下&#x…

嵌入式中C++开发的基本操作方法

第一&#xff1a;面向对象 1、配置环境 虚拟机上网&#xff08;ping www.baidu.com&#xff09;sudo apt-get update //更新软件包sudo apt-get install -f //更新软件依赖sudo apt-get install g //安装c编译器 2、C发展 c98,第一版 c03,c11,c17 3、为什么学习C 4、面向对…

python包的研究

目录 json的方法timecollectionsdatetimetimestampsocket json的方法 json.load&#xff1a;表示读取文件&#xff0c;返回python对象 json.dump&#xff1a;表示写入文件&#xff0c;文件为json字符串格式&#xff0c;无返回 json.dumps&#xff1a;将python中的字典类型转换…

11-Vue常见优化手段

前言&#xff1a; 永远不要过早优化&#xff0c;见招拆招 使用key 对于通过循环生成的列表&#xff0c;应给每个列表项一个稳定且唯一的key,这有利于在列表变动时&#xff0c;尽量少的删除&#xff0c;新增&#xff0c;改动元素 index作为key值是唯一的&#xff0c;但不够稳…

STM32外设系列—sg90(舵机)

文章目录 一、sg90简介二、引脚连接三、控制方法四、程序设计4.1 配置定时器4.2 编写控制程序 五、360舵机 一、sg90简介 首先介绍说一下什么是舵机。舵机是一种位置&#xff08;角度&#xff09;伺服的驱动器。适用于一些需要角度不断变化的&#xff0c;可以保持的控制系统。…

threejs物理效果和声音

个人博客地址: https://cxx001.gitee.io 一、Threejs中如何创建物理场景 threejs中创建物理场景我们用它的扩展库&#xff1a;Physijs。它可以使场景中的对象有重力效果&#xff0c;可以相互碰撞&#xff0c;施加力之后可以移动&#xff0c;还可以通过合页和滑块在移动过程中…

LeetCode 打卡day44--完全背包问题及其应用

一个人的朝圣 — LeetCode打卡第44天 知识总结 Leetcode 518. 零钱兑换 II题目说明代码说明 Leetcode 377. 组合总和 Ⅳ题目说明代码说明 知识总结 今天结束了完全背包问题, 完全背包问题与01背包问题的区别在于可以无限次的使用物品的数量. 其和01背包的差别在于, 01背包先遍…

Leetcode-每日一题【707. 设计链表】

题目 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 prev 以指示链表中的上一…

Spring Boot 中的 @Id 注解是什么,原理,如何使用

Spring Boot 中的 Id 注解是什么&#xff0c;原理&#xff0c;如何使用 在 Spring Boot 中&#xff0c;Id 注解是一个非常重要的注解&#xff0c;它用于映射实体类中的主键字段。本文将介绍 Id 注解的作用、原理和使用方法。 1. Id 注解的作用 在 Spring Boot 中&#xff0c;…