2. Android Camera HAL架构演进:从HAL1到HAL3,Treble架构与HIDL/AIDL的引入
Android Camera HAL(硬件抽象层)是连接Android框架与底层Camera硬件的关键桥梁。随着Android系统对多摄像头、高帧率、计算摄影等需求的提升,HAL架构经历了从HAL1到HAL3的重大演进,并在Treble架构的推动下,引入了HIDL与AIDL作为新的接口定义语言。本章将系统梳理这一演进脉络,并重点分析Treble架构对Camera HAL通信模型的重塑。
2.1 Camera HAL1:单摄像头时代的经典架构
HAL1是Android早期(Android 4.x及之前)的标准Camera HAL接口。它采用同步阻塞模型,设计上主要面向单摄像头场景。
HAL1的架构模型如下图所示:
HAL1的主要局限性:
- 同步阻塞模型:每次操作(如预览帧获取)都会阻塞调用线程,无法充分利用多核CPU。
- 无Buffer管理抽象:Buffer分配、生命周期管理由HAL实现自行决定,框架无法统一调度。
- 单流限制:同一时间只能支持一个预览流或拍照流,无法支持多摄像头同时工作。
- 扩展性差:新增功能(如HDR、人脸检测)需要修改HAL接口,导致碎片化严重。
2.2 Camera HAL3:多摄像头与计算摄影的基石
Android 5.0(Lollipop)引入了Camera HAL3,这是一次颠覆性的架构升级。HAL3采用异步流水线模型,将Camera设备抽象为Capture Session和Capture Request,为多摄像头和计算摄影奠定了基础。
HAL3的核心组件关系如下图所示:
HAL3相比HAL1的关键改进:
| 维度 | HAL1 | HAL3 |
|---|---|---|
| 调用模型 | 同步阻塞 | 异步流水线 |
| 流支持 | 单流(预览或拍照) | 多流并行(预览、拍照、视频、YUV、Raw等) |
| Buffer管理 | HAL自行管理 | 框架通过Stream/DequeueBuffer统一管理 |
| 控制粒度 | 粗粒度(打开/关闭/预览/拍照) | 细粒度(每帧可配置AE/AWB/AF、Sensor模式、ISP参数) |
| 多摄像头 | 不支持 | 原生支持(每个CameraDevice独立) |
| 元数据 | 无标准化元数据 | android.hardware.camera2.CaptureMetadata |
2.3 Treble架构:解耦Framework与HAL
Android 8.0(Oreo)引入了Project Treble,这是Android系统架构的一次根本性重构。Treble的核心目标是将Android Framework与Vendor HAL解耦,使得OEM厂商可以独立升级Framework而不需要修改HAL实现。
Treble架构的关键变化:
- Vendor Interface:定义了Framework与Vendor实现之间的稳定接口。
- HAL Server/HAL Client模型:HAL实现运行在独立的Vendor进程(HAL Server)中,Framework通过Binder/RPC调用访问。
- HIDL(HAL Interface Definition Language):用于定义Vendor接口的IDL语言,支持跨进程通信。
Treble架构下的Camera HAL通信模型:
2.4 HIDL与AIDL的引入:接口定义语言的演进
Treble架构引入了两种接口定义语言:HIDL(HAL Interface Definition Language)和AIDL(Android Interface Definition Language)。两者在Camera HAL通信中扮演着不同角色。
2.4.1 HIDL:Vendor接口的标准语言
HIDL是Treble架构的原生IDL,专门用于定义Framework与Vendor HAL之间的接口。HIDL支持直通(Passthrough)和Binderized两种模式:
- 直通模式:HAL实现被编译为共享库,直接加载到调用进程(不跨进程),适用于性能敏感场景。
- Binderized模式:HAL实现运行在独立进程,通过Binder通信,提供更强的隔离性和安全性。
Camera HAL的HIDL接口定义示例:
// android.hardware.camera.provider@2.4::ICameraProvider.hal
package android.hardware.camera.provider@2.4;
interface ICameraProvider {
/**
* 获取所有可用的Camera设备ID列表
*/
getCameraIdList() generates (Status status, vec<string> cameraIds);
/**
* 获取指定Camera设备的接口
*/
getCameraDeviceInterface_V3_x(
string cameraId
) generates (Status status, ICameraDevice device);
};
2.4.2 AIDL:从Framework到Vendor的扩展
AIDL原本用于Android Framework内部进程间通信(如Service与App之间)。在Treble架构中,AIDL被扩展为支持Vendor接口定义,与HIDL形成互补:
| 维度 | HIDL | AIDL(Vendor扩展) |
|---|---|---|
| 设计目标 | Vendor接口标准化 | Framework内部通信 + Vendor接口 |
| 稳定性 | 严格版本化,向后兼容 | 依赖接口版本管理 |
| 性能 | 支持直通模式(零拷贝) | Binder通信(有拷贝开销) |
| 类型系统 | HIDL原生类型(vec、fmq等) | AIDL原生类型(List、Map等) |
| 适用场景 | Camera、Audio、Sensor等核心HAL | 系统服务、应用层通信、部分Vendor服务 |
| 多Camera支持 | 原生支持多CameraDevice实例 | 通过ServiceManager管理多实例 |
2.5 多Camera场景下的架构选择
在HAL3 + Treble架构下,多Camera场景的通信模型面临新的挑战:
- 多实例管理:每个Camera设备对应一个独立的HAL Server实例,需要协调多个实例间的资源(如ISP带宽、内存)。
- 同步与同步:多摄像头同时工作时,需要帧级同步(如双目视觉、深度计算)。
- Buffer共享:多摄像头可能共享同一Buffer Pool,需要高效的Buffer分配和回收机制。
- 跨进程开销:Binderized模式下的跨进程通信可能成为性能瓶颈,特别是在高帧率场景下。
针对这些挑战,HIDL和AIDL提供了不同的解决方案:
- HIDL FMQ(Fast Message Queue):用于高吞吐量的数据传递(如Camera帧数据),避免Binder的序列化开销。
- AIDL回调接口:支持异步通知,适用于多Camera事件分发。
- ServiceManager统一管理:通过ServiceManager注册和发现多个Camera HAL Server实例。