4. 摄像头ID与朝向枚举:CameraCharacteristics.LENS_FACING、前后摄区分、逻辑摄像头与物理摄像头
4.1 核心概念与枚举定义
在 Android Camera CTS 测试中,摄像头 ID 是标识每个摄像头的唯一字符串,而朝向(Facing)则通过 CameraCharacteristics.LENS_FACING 静态信息枚举。HAL 层必须正确上报这些信息,否则 CTS 用例将直接失败。
| 枚举值 | 常量名 | 含义 | 典型应用场景 |
|---|---|---|---|
| 0 | LENS_FACING_FRONT |
前置摄像头,屏幕同侧 | 自拍、视频通话 |
| 1 | LENS_FACING_BACK |
后置摄像头,屏幕异侧 | 拍照、录像、扫码 |
| 2 | LENS_FACING_EXTERNAL |
外接摄像头(USB/UVC) | 外接相机、工业检测 |
CTS 验证要点: 测试框架通过
CameraManager.getCameraIdList() 获取所有 ID,再对每个 ID 调用 getCameraCharacteristics() 读取 LENS_FACING。若返回非法值或与物理布局矛盾,则判定为 HAL 实现缺陷。
4.2 前后摄区分与 CTS 验证逻辑
CTS 通过以下步骤严格区分前后摄:
- 枚举所有摄像头 ID,构建 ID 列表。
- 对每个 ID 读取
CameraCharacteristics.LENS_FACING。 - 验证前置摄像头数量 ≤ 后置摄像头数量(非强制但常见)。
- 检查
LENS_FACING_EXTERNAL设备是否支持热插拔事件。
常见失败场景: 部分 OEM 将前置摄像头错误上报为
LENS_FACING_BACK,导致 CTS 用例 testCameraFacing 失败。HAL 开发者应核对 sensor 物理安装方向与枚举值的一致性。
4.3 逻辑摄像头与物理摄像头
Android 10(API 29)引入逻辑摄像头(Logical Camera)概念,用于多摄系统。逻辑摄像头对应一个虚拟 ID,内部聚合多个物理摄像头(Physical Camera)。
| 特性 | 逻辑摄像头 | 物理摄像头 |
|---|---|---|
| ID 类型 | 虚拟 ID,对外暴露 | 物理 ID,通过 getPhysicalCameraIds() 获取 |
| LENS_FACING | 继承自主物理摄像头 | 各自独立朝向 |
| 典型场景 | 广角+超广角融合 | 单个 sensor 独立工作 |
| CTS 验证 | 检查 REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA |
验证物理 ID 存在且可打开 |
HAL 实现警告: 逻辑摄像头必须至少包含 2 个物理摄像头,且所有物理摄像头的
LENS_FACING 必须相同。若混合前置与后置物理摄像头,CTS 将直接报错。
4.4 逻辑摄像头架构与 CTS 枚举
CTS 通过以下步骤验证逻辑摄像头:
- 调用
CameraCharacteristics.getPhysicalCameraIds()获取物理 ID 集合。 - 若集合非空,则检查
REQUEST_AVAILABLE_CAPABILITIES是否包含LOGICAL_MULTI_CAMERA。 - 遍历每个物理 ID,读取其
LENS_FACING,确保与逻辑摄像头一致。 - 验证物理摄像头可独立打开并输出数据流。
4.5 CTS 测试用例示例
以下代码片段展示 CTS 如何枚举摄像头 ID 并验证朝向:
// 获取 CameraManager
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] ids = manager.getCameraIdList();
for (String id : ids) {
CameraCharacteristics chars = manager.getCameraCharacteristics(id);
Integer facing = chars.get(CameraCharacteristics.LENS_FACING);
// 验证朝向枚举值合法
assertNotNull(facing);
assertTrue(facing == CameraCharacteristics.LENS_FACING_FRONT ||
facing == CameraCharacteristics.LENS_FACING_BACK ||
facing == CameraCharacteristics.LENS_FACING_EXTERNAL);
// 验证逻辑摄像头物理 ID 朝向一致性
Set<String> physicalIds = chars.getPhysicalCameraIds();
if (physicalIds != null && !physicalIds.isEmpty()) {
for (String physId : physicalIds) {
CameraCharacteristics physChars = manager.getCameraCharacteristics(physId);
Integer physFacing = physChars.get(CameraCharacteristics.LENS_FACING);
assertEquals(facing, physFacing);
}
}
}
CTS 测试项对照:
android.hardware.camera2.cts.CameraCharacteristicsTest#testLensFacing 和 testLogicalMultiCamera 是本章核心用例。HAL 开发者应确保所有摄像头 ID 的 LENS_FACING 与物理布局严格匹配,逻辑摄像头物理 ID 朝向必须统一。
4.6 常见问题与避坑指南
- ID 重复或缺失: HAL 返回的 ID 列表必须连续且唯一,CTS 会检查 ID 数量与
getCameraIdList()一致性。 - 朝向与旋转矛盾:
LENS_FACING_FRONT的摄像头通常需要镜像输出,若 HAL 未正确设置SCALER_CROP_REGION或JPEG_ORIENTATION,CTS 图像测试会失败。 - 外接摄像头热插拔: 对于
LENS_FACING_EXTERNAL,CTS 要求支持CameraManager.AvailabilityCallback回调,HAL 必须正确触发onCameraAvailable和onCameraUnavailable。 - 逻辑摄像头物理 ID 不可打开: 部分 HAL 将物理 ID 注册为逻辑摄像头的子设备,但未实现独立 open() 路径,导致 CTS 打开物理摄像头失败。
调试建议: 使用
dumpsys media.camera 查看当前系统所有摄像头 ID、朝向和逻辑/物理关系。对比 CTS 日志中的 getCameraIdList 输出与 HAL 实现,快速定位枚举不一致问题。