3. Camera特性枚举基础:CameraCharacteristics类、getAvailableCameraCharacteristics()方法、静态元数据获取
Camera特性枚举是CTS测试中验证HAL功能正确性的第一步。Android Camera框架通过CameraCharacteristics类暴露设备的静态能力,这些能力由HAL在初始化时填充,并最终由getAvailableCameraCharacteristics()方法返回给上层。本章将深入解析这一基础数据通路。
3.1 CameraCharacteristics类:静态元数据的容器
CameraCharacteristics是Android Camera API中用于描述单个摄像头设备固定属性的不可变类。它本质上是一个键值对(Key-Value)映射,每个Key对应一个特定的元数据字段,Value则包含该字段的具体数值或结构。
| 特性 | 说明 |
|---|---|
| 不可变性 | 一旦由CameraManager创建,其内容在设备生命周期内不会改变。 |
| 线程安全 | 支持在多线程环境下安全读取,无需额外同步。 |
| 键值对存储 | 内部使用CameraCharacteristics.Key<T>作为索引,支持基本类型、数组及自定义结构。 |
| 来源 | 数据最终由HAL层的camera_info结构体中的static_metadata字段提供。 |
CameraCharacteristics对象不为空,且所有在API文档中标记为REQUIRED的Key都必须存在并返回有效值。例如,INFO_SUPPORTED_HARDWARE_LEVEL是所有摄像头设备必须提供的Key。
3.2 getAvailableCameraCharacteristics():获取静态元数据的入口
getAvailableCameraCharacteristics(String cameraId)是CameraManager类的核心方法。它接收一个摄像头ID字符串,返回该摄像头对应的CameraCharacteristics对象。如果指定的摄像头ID无效,则抛出CameraAccessException异常。
该方法的工作流程涉及从Framework到HAL的跨进程调用:
- 应用层调用:通过
CameraManager.getCameraCharacteristics(id)发起请求。 - CameraService处理:CameraService根据cameraId查找对应的设备实例,并调用HAL接口获取静态元数据。
- HAL填充数据:HAL实现
get_camera_info()函数,返回包含static_metadata的camera_info结构体。 - 元数据反序列化:CameraService将HAL返回的原始字节流解析为Framework层的
CameraMetadata对象,再封装为CameraCharacteristics。
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
try {
String[] cameraIdList = manager.getCameraIdList();
for (String cameraId : cameraIdList) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
// 获取硬件支持级别
Integer level = characteristics.get(
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
// 获取朝向信息
Integer facing = characteristics.get(
CameraCharacteristics.LENS_FACING);
Log.d("CTS_Camera", "Camera " + cameraId +
" level=" + level + " facing=" + facing);
}
} catch (CameraAccessException e) {
Log.e("CTS_Camera", "Failed to access camera: " + e.getMessage());
}
3.3 静态元数据获取:从HAL到Framework的数据流
静态元数据的获取是CTS测试中验证HAL实现完整性的关键环节。下图展示了从HAL层到应用层的完整数据流:
3.4 关键静态元数据枚举
在CTS测试中,以下静态元数据是必须验证的核心特性,它们直接反映了HAL实现的功能完整性:
| Key常量 | 数据类型 | 描述 | CTS验证要求 |
|---|---|---|---|
INFO_SUPPORTED_HARDWARE_LEVEL |
Integer | 摄像头硬件支持级别(LEGACY/LIMITED/FULL/LEVEL_3/EXTERNAL) | 必须存在,且值在定义范围内 |
LENS_FACING |
Integer | 摄像头朝向(FRONT/BACK/EXTERNAL) | 必须存在,且值合法 |
SENSOR_INFO_ACTIVE_ARRAY_SIZE |
Rect | 有效像素阵列区域 | 必须存在,宽高必须大于0 |
SCALER_AVAILABLE_STREAM_CONFIGURATIONS |
StreamConfiguration[] | 支持的输出/输入流配置列表 | 必须包含至少一个输出配置 |
REQUEST_AVAILABLE_CAPABILITIES |
int[] | 设备支持的高级能力列表 | 必须包含BACKWARD_COMPATIBLE |
- 缺失必选Key:HAL未填充
android.info.supportedHardwareLevel,导致Framework层抛出异常。 - 枚举值越界:
LENS_FACING返回了未定义的整数值(如3),导致CTS测试失败。 - 流配置为空:
SCALER_AVAILABLE_STREAM_CONFIGURATIONS返回空数组,导致无法创建任何CameraCaptureSession。
3.5 特性枚举的CTS测试策略
针对CameraCharacteristics的CTS测试通常采用以下策略:
- 完整性检查:遍历所有在API中标记为
REQUIRED的Key,验证其是否存在于返回的CameraCharacteristics中。 - 类型检查:验证每个Key对应的Value类型是否与API定义一致(例如,
LENS_FACING必须是Integer)。 - 范围检查:对于枚举类型的Key,验证其值是否在定义的合法范围内(例如,
INFO_SUPPORTED_HARDWARE_LEVEL的值必须在0~4之间)。 - 一致性检查:验证不同Key之间的依赖关系是否成立(例如,如果
REQUEST_AVAILABLE_CAPABILITIES包含RAW,则SENSOR_INFO_RAW_BITS必须存在)。
public static void testRequiredKeysExist(CameraCharacteristics chars) {
// 定义必选Key列表
List<CameraCharacteristics.Key<?>> requiredKeys = Arrays.asList(
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL,
CameraCharacteristics.LENS_FACING,
CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE,
CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES
);
for (CameraCharacteristics.Key<?> key : requiredKeys) {
Object value = chars.get(key);
if (value == null) {
throw new AssertionError("Missing required key: " + key.getName());
}
}
Log.i("CTS_Camera", "All required keys present.");
}
3.6 静态元数据与HAL功能验证的关联
CameraCharacteristics中枚举的特性直接决定了HAL需要实现的功能集合。例如:
- 硬件支持级别:如果
INFO_SUPPORTED_HARDWARE_LEVEL为FULL,则HAL必须支持全帧率处理、手动传感器控制等高级功能。 - 能力列表:如果
REQUEST_AVAILABLE_CAPABILITIES包含CONSTRAINED_HIGH_SPEED_VIDEO,则HAL必须实现高速视频录制相关的数据流和参数。 - 流配置:
SCALER_AVAILABLE_STREAM_CONFIGURATIONS中列出的每个输出尺寸和格式,HAL都必须能在实际预览或拍照时正确输出。
因此,CTS测试的第一步就是通过getAvailableCameraCharacteristics()获取完整的静态元数据,然后根据这些元数据动态生成后续的功能测试用例。这种“先枚举,后验证”的策略确保了测试的全面性和自适应性。