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/base
和frameworks/Native
,以及其他SO库
调用。
3》
AIDL、HIDL
接口定义语言:是Android中binder机制
的具体实现,相应的binder域/dev/binder
、/dev/hwbinder
、/dev/vndbinder
;Android规范的接口定义语言,按照规范aidl/hidl文件自动生成相应代码文件。
Android 接口定义语言 相关Blog client端 / server端 AIDL
Android 接口定义语言 (AIDL) 客户端获取proxy: asInterface(android.os.IBinder obj)
服务端实现Stub:class Stub extends android.os.Binder
HIDL
Android 接口定义语言 (HIDL)
1.2 参考
1》
Binder IPC
通信机制
序号 文章名 概述 0 为什么 Android 要采用 Binder 作为 IPC 机制? 【Android,在争议中逃离 Linux 内核的 GPL 约束】 0 使用 Binder IPC 多个 Binder 域: /dev/binder
、/dev/hwbinder
、/dev/vndbinder
1 Binder系列1-Binder Driver /dev/binder
运行在Linux kernel2 Binder系列2-ServiceManager SM启动,添加/获取Service 3 Binder系列3-framework层 Zygote启动时AndroidRuntime::startReg中 register_jni_procs()
,JNI调用到Native4 Binder 域 关注/dev/vndbinder与/dev/binder共用一套libbinder,defaultServiceManager()获取前需要切换 5 Binder相关问题
2》
JNI
调用
Android JNI原理、Java本地调用(JNI)
3》
AIDL、HIDL
接口定义语言
Android 接口定义语言 相关Blog AIDL
Android 接口定义语言 (AIDL) HIDL
Android 接口定义语言 (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, };