在 Android 的 Camera 架构中,数据结构是层层封装和映射的。从底层的 C 结构体 camera_module_t 到 Java 层的 CameraManager,中间经历了几次关键的转换。
下面我们将从下往上,梳理这个映射关系。
1. Framework 层:谁在管理 camera_module_t?
在 Camera Service(位于 frameworks/av/services/camera/libcameraservice/)中,并没有一个直接叫 camera_module_t 的变量,因为它被封装在了 HIDL/AIDL 接口 之后。
核心对应结构:CameraProviderManager
在 Framework 层,负责与 HAL 模块对接的核心类是 CameraProviderManager。
- 对应关系:
- HAL 层:
camera_module_t存在于厂商实现的.so文件中。 - Provider 层:一个名为
android.hardware.camera.provider@2.4(或更高版本)的独立进程会加载这个.so,并将其封装成 HIDL/AIDL 接口ICameraProvider。 - Framework 层:
CameraProviderManager维护了一组ProviderInfo对象。每一个ProviderInfo实际上就代表了一个底层的camera_module_t实例。
- HAL 层:
内部关键类:CameraProviderManager::ProviderInfo
这个类在 Framework 中保存了从 camera_module_t 获取的所有信息:
- 摄像头数量。
- 每个摄像头的 ID。
- 从
get_camera_info获取到的CameraCharacteristics(静态元数据)。
2. App 层:对应的接口是什么?
App 层不会看到任何关于“Module”的字眼,它通过 CameraManager 这个系统服务来间接调用 camera_module_t 提供的能力。
接口映射表
| 功能描述 | 底层 HAL (camera_module_t) | App 层 Java API (CameraManager) |
|---|---|---|
| 获取相机列表 | get_number_of_cameras() | getCameraIdList() |
| 获取相机特性 | get_camera_info() | getCameraCharacteristics(String cameraId) |
| 打开相机 | common.methods->open() | openCamera(String cameraId, ...) |
| 手电筒控制 | set_torch_mode() | setTorchMode(String cameraId, boolean enabled) |
| 热插拔回调 | set_callbacks() | registerAvailabilityCallback(...) |
3. 数据流转的全过程(以 getCameraIdList() 为例)
为了让你更直观地理解,我们看一次完整的调用链:
- App 层:调用
cameraManager.getCameraIdList()。 - Framework (Context):通过 Binder 调用
CameraService。 - Camera Service:询问其内部的
CameraProviderManager:“你现在手头有多少个摄像头?” - CameraProviderManager:遍历它管理的
ProviderInfo列表。 - HAL Provider 进程:通过 HIDL/AIDL 接口,最终调用到底层
.so库中camera_module_t结构体的get_number_of_cameras函数。 - 结果原路返回:从 HAL -> Provider -> CameraService -> App。
4. 关键数据结构的演变:camera_info -> CameraCharacteristics
这是一个非常重要的转换:
- HAL 层 (
camera_info): 在camera_module_t的get_camera_info中,返回的是struct camera_info。其中最核心的是static_camera_characteristics(这是一个camera_metadata_t类型的原始指针)。 - Framework 层 (
CameraMetadata): Camera Service 会读取这个原始指针,并将其反序列化为 C++ 的CameraMetadata对象。 - App 层 (
CameraCharacteristics): 在 Java 层,这个对象最终被封装成android.hardware.camera2.CameraCharacteristics。- 例子:你在 App 里调用
characteristics.get(CameraCharacteristics.LENS_FACING),最终获取的就是底层 HAL 在camera_info.facing中填写的那个值。
- 例子:你在 App 里调用
5. 总结
| 层级 | 对应实体/数据结构 | 角色 |
|---|---|---|
| App (Java) | CameraManager | 面向开发者的控制入口 |
| Framework (Native) | CameraService / CameraProviderManager | 管理员,协调多个 Provider |
| HAL 接口层 (HIDL/AIDL) | ICameraProvider | 跨进程的包装器 |
| HAL 实现层 (C/C++) | camera_module_t | 硬件能力的具体实现(总管) |
| 硬件设备层 | camera3_device_t | 具体的摄像头硬件实例 |
核心结论:
camera_module_t 在 Framework 中并没有等名的结构体,它被抽象成了 CameraProvider。App 层通过 CameraManager 间接消费 camera_module_t 提供的信息和功能。