接下来我们仿造振动器写一个简单的 AIDL HAL 模块。
AIDL 文件编写
首先,在 hardware/interfaces/ 路径下创建 aidl hal 项目目录:
cd hardware/interfaces
mkdir hello_aidl_hal
cd hello_aidl_hal
mkdir -p android/hardware/hello
接下来我们仿造振动器写一个简单的 AIDL HAL 模块。
首先,在 hardware/interfaces/ 路径下创建 aidl hal 项目目录:
cd hardware/interfaces
mkdir hello_aidl_hal
cd hello_aidl_hal
mkdir -p android/hardware/hello
创建 aidl 文件 frameworks/base/core/java/android/hardware/hello/IHelloHalManager.aidl:
package android.hardware.hello;
/**
* {@hide}
*/
interface IHelloHalManager {
void hellohal_write(String str);
String hellohal_read();
}
Linux 驱动实际就是一个 Linux 内核模块。
首先,我们需要理解什么是内核模块?简单来说,内核模块是一段 "固定格式" 的代码,像一个“插件”一样,linux 内核可以动态的加载并执行这段代码,也可以把这段代码编译进内核,在内核启动的时候来执行这段代码。
下面我们写一个简单的 linux 驱动,如果你对驱动开发还不太了解,可以先学习学习 Binder 的预备知识的Linux驱动章节。
我们还是以振动器的调用过程为主线,来分析振动器 HAL 的实现细节。
整体架构如下:

Android12 及以后,App 中可以通过以下代码操作振动器:
val vibratorManager = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
val vib = vibratorManager.defaultVibrator
if (vib.hasVibrator()) {
val vibrationEffect = VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)
vib.vibrate(vibrationEffect)
}
light hal 的调用流程与 Vibrator 基本移植,主要区别是 light 直接用 java 和 hal 通信,没有用 jni。接下来我们分析一下 SystemServer 中的 light 硬件服务与 hal 通信的过程。
整体架构如下:

在 SystemServer 的 startBootstrapServices 方法中找到 LightsService 的启动过程:
在 HIDL HAL 中我们聊过 Same-Process HALs,这类 hal 的调用对性能要求高,一般直接链接,不适用跨进程的方式来调用。
在 AIDL HAL 中,与之对应的是 stable-c HAL。stable-c HAL 就是一个对外接口稳定的 so 库。
接着我们来看一个源码中的 stable-c HAL, hardware/interfaces/graphics/mapper

Passthrough HALs 的存在,主要是为了复用传统 HAL 的实现。HAL 层以进程的形式存在,内部有一个 HwBinder 服务端对象,对外提供 HwBinder 远程调用服务。Framework 通过 HwBinder 远程调用到 HAL 中的函数,这些函数会去加载传统 HAL 实现来操作具体硬件。整体架构如下:

有的 HAL 模块有性能需求,调用它们不能太慢了,有的 hal 模块,是给当前进程提供某种功能,需要在当前进程下执行,跨进程通信的方式不能满足其需求。这类 HAL 以 so 库的形式存在,Framework 层会直接链接这些 so 库,以保证调用的性能。这类 Hal 称之为 Same-Process HALs,整体架构如下:

HIDL HAL 的整体架构如下图所示:

接下来我们就来完成一个从驱动到 App 的完整 HIDL HAL 实现示例。
本节的任务是在内核中实现一个简单的驱动,并完成一个应用层 Native 程序来测试我们的驱动是否正常工作。
HIDL HAL 的整体架构如下图所示:

上一节我们实现了一个简单的驱动,本节继续从下往上实现一个简单的 HIDL HAL 模块
这部分内容主要是在HIDL Hal 开发指南3 —— HIDL HAL 实例程序基础上做一些修改,添加驱动访问的代码。