2. HAL层基础:HIDL与AIDL接口定义、QTI HAL Service启动流程、binder与hwbinder通信模型
2.1 HIDL 与 AIDL 接口定义
在 QTI 平台中,HAL 层接口定义经历了从 HIDL 到 AIDL 的演进。HIDL(HAL Interface Definition Language)是 Android 8.0 引入的接口定义语言,专为 Treble 架构设计,用于实现 Framework 与 HAL 之间的稳定接口。AIDL(Android Interface Definition Language)则从 Android 12 开始被推荐用于新的 HAL 模块,统一了跨进程通信的接口定义方式。
| 特性 | HIDL | AIDL(HAL 场景) |
|---|---|---|
| 引入版本 | Android 8.0 (Treble) | Android 12 (推荐) |
| 接口文件后缀 | .hal |
.aidl |
| 后端支持 | hwbinder + passthrough | binder + hwbinder |
| 包名规范 | android.hardware.xxx@X.Y |
android.hardware.xxx.IXxx |
| 服务注册 | hwservicemanager |
servicemanager (统一) |
| 稳定性 | 强(版本化接口) | 强(支持冻结接口) |
| 代码生成 | hidl-gen |
aidl-cpp |
2.1.1 HIDL 接口定义示例
以下是一个典型的 QTI 平台 HIDL 接口定义,用于控制摄像头传感器:
// types.hal
package android.hardware.camera.provider@3.5;
enum CameraDeviceStatus : int32_t {
PRESENT = 0,
ENUMERATING = 1,
NOT_PRESENT = 2
};
struct CameraMetadata {
vec<uint8_t> metadata;
int32_t tagCount;
};
// ICameraProvider.hal
package android.hardware.camera.provider@3.5;
interface ICameraProvider {
getCameraIdList() generates (vec<string> cameraIds);
getCameraDeviceInterface_V3(
string cameraId
) generates (ICameraDevice device, Status status);
setCallback(ICameraProviderCallback callback);
};
2.1.2 AIDL 接口定义示例
Android 12 之后,QTI 平台开始使用 AIDL 定义 HAL 接口,统一了与系统服务的通信方式:
// IMySensor.aidl
package android.hardware.mysensor;
interface IMySensor {
/**
* 获取传感器数据
* @param sensorId 传感器ID
* @return 传感器数据数组
*/
float[] readSensorData(int sensorId);
/**
* 注册传感器事件回调
*/
void registerCallback(IMySensorCallback callback);
/**
* 配置传感器采样率
* @param sensorId 传感器ID
* @param rateHz 采样率(Hz)
*/
void setSamplingRate(int sensorId, int rateHz);
}
迁移建议: 对于新开发的 QTI HAL 模块,优先使用 AIDL 定义接口。AIDL 支持更丰富的类型系统、默认方法实现和更简洁的代码生成流程。对于已有 HIDL 接口的模块,可通过兼容层逐步迁移。
2.2 QTI HAL Service 启动流程
QTI 平台的 HAL Service 启动流程遵循 Android Treble 架构规范,涉及 init 进程、hwservicemanager/servicemanager、HAL 守护进程等多个组件。以下流程图展示了典型的启动序列:
2.2.1 启动流程关键步骤
- init 进程解析 .rc 文件: 系统启动时,init 进程读取
/vendor/etc/init/目录下的 HAL 服务 .rc 文件,例如android.hardware.camera.provider@3.5-service.rc。 - 启动 HAL 守护进程: init 根据 .rc 文件中的
service声明,fork 并执行对应的 HAL 可执行文件,例如/vendor/bin/hw/android.hardware.camera.provider@3.5-service。 - 初始化接口: HAL 进程启动后,创建 HIDL/AIDL 接口实现对象,初始化硬件资源(如打开设备节点、分配共享内存)。
- 注册服务: 调用
hwservicemanager(HIDL)或servicemanager(AIDL)的注册接口,将服务实例注册到全局服务列表中。 - 进入事件循环: HAL 进程进入主循环,等待客户端通过 binder/hwbinder 发送请求。
死锁风险点: 在 HAL 服务初始化阶段,如果存在跨服务依赖(如 Camera HAL 依赖 Sensor HAL),且双方在注册服务时互相等待对方完成初始化,极易形成死锁。Perfetto 分析中应重点关注
onInit 阶段的线程状态。
2.3 Binder 与 HwBinder 通信模型
QTI 平台中存在两套跨进程通信机制:Binder(用于 Framework 层)和 HwBinder(用于 HAL 层)。理解两者的差异对于死锁排查至关重要。
| 特性 | Binder | HwBinder |
|---|---|---|
| 所属层 | Framework / 系统服务 | HAL 层(Treble) |
| 驱动 | /dev/binder |
/dev/hwbinder |
| 服务管理器 | servicemanager |
hwservicemanager |
| 线程池 | 默认 16 线程 | 默认 4 线程 |
| 事务优先级 | 支持优先级继承 | 支持优先级继承 |
| 死锁常见场景 | 跨服务循环调用 | HAL 线程池耗尽 + 同步回调 |
2.3.1 通信模型对比图
2.3.2 通信流程与死锁场景
正常通信流程:
- 客户端(如 SystemServer)通过 Binder 向 HAL 服务发送请求。
- HAL 服务从 HwBinder 线程池中分配一个线程处理请求。
- HAL 服务执行硬件操作,可能通过 HwBinder 调用其他 HAL 服务。
- 处理完成后,通过 Binder/HwBinder 返回结果给客户端。
典型死锁场景:
- 线程池耗尽: HwBinder 线程池默认只有 4 个线程。如果 4 个线程都在等待同步回调,而回调需要新的线程处理,则所有线程阻塞,形成死锁。
- 跨域循环依赖: Framework 通过 Binder 调用 HAL A,HAL A 通过 HwBinder 调用 HAL B,HAL B 又通过 Binder 回调 Framework 中的某个服务,形成 A→B→A 循环。
- 服务注册死锁: 两个 HAL 服务在
onInit阶段互相等待对方完成注册,导致双方均无法完成初始化。
排查建议: 在 Perfetto 分析中,重点关注以下信号:
1. HwBinder 线程池中所有线程处于
2. 线程堆栈显示在
3. 存在跨域(Binder ↔ HwBinder)的同步调用链。
4. 服务注册阶段出现超时或卡死。
1. HwBinder 线程池中所有线程处于
Binder: transaction 状态。2. 线程堆栈显示在
ioctl 调用上等待。3. 存在跨域(Binder ↔ HwBinder)的同步调用链。
4. 服务注册阶段出现超时或卡死。