3. 获取相机信息
任务说明
本案例实现 Android Camera HAL 中的 get_camera_info 回调,用于向 Camera Service 上报相机设备的基本信息。需要填充 camera_info_t 结构体中的设备 ID、朝向、资源成本等字段,并确保返回的相机数量与设备列表一致。
核心代码实现
// camera_hal.cpp
#include <hardware/camera_common.h>
#include <hardware/camera.h>
#include <cutils/log.h>
#include <vector>
#include <string>
#define CAMERA_DEVICE_ID_0 "0"
#define CAMERA_DEVICE_ID_1 "1"
// 设备列表:本 HAL 暴露两个摄像头
static std::vector<std::string> g_device_list = {
CAMERA_DEVICE_ID_0,
CAMERA_DEVICE_ID_1
};
// 静态相机信息表(实际项目中可从配置或驱动读取)
static camera_info_t g_camera_info[] = {
{
.device_id = const_cast<char*>(CAMERA_DEVICE_ID_0),
.device_version = CAMERA_DEVICE_API_VERSION_1_0,
.facing = CAMERA_FACING_BACK,
.orientation = 90,
.resource_cost = 100,
.conflicting_devices = nullptr,
.conflicting_devices_length = 0,
},
{
.device_id = const_cast<char*>(CAMERA_DEVICE_ID_1),
.device_version = CAMERA_DEVICE_API_VERSION_1_0,
.facing = CAMERA_FACING_FRONT,
.orientation = 270,
.resource_cost = 100,
.conflicting_devices = nullptr,
.conflicting_devices_length = 0,
}
};
// HAL 模块回调:返回相机数量
static int get_number_of_cameras(void) {
return static_cast<int>(g_device_list.size());
}
// HAL 模块回调:填充相机信息
static int get_camera_info(int camera_id, struct camera_info *info) {
if (camera_id < 0 || camera_id >= static_cast<int>(g_device_list.size())) {
ALOGE("Invalid camera_id: %d", camera_id);
return -EINVAL;
}
if (info == nullptr) {
ALOGE("info is null");
return -EINVAL;
}
*info = g_camera_info[camera_id];
ALOGI("get_camera_info: id=%d, device_id=%s, facing=%d, orientation=%d",
camera_id, info->device_id, info->facing, info->orientation);
return 0;
}
// 模块定义
static hw_module_methods_t g_module_methods = {
.open = [](const struct hw_module_t* module, const char* id,
struct hw_device_t** device) -> int {
// 本案例聚焦 get_camera_info,open 实现从略
return -ENOSYS;
}
};
camera_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_2_4,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "Demo Camera HAL",
.author = "Camera HAL 100 Cases",
.methods = &g_module_methods,
.dso = nullptr,
.reserved = {0},
},
.get_number_of_cameras = get_number_of_cameras,
.get_camera_info = get_camera_info,
.set_callbacks = nullptr,
.get_vendor_tag_ops = nullptr,
.open_legacy = nullptr,
.set_torch_mode = nullptr,
.init = nullptr,
.reserved = {0},
};
关键实现说明
get_camera_info 回调接收两个参数:camera_id 表示查询的相机序号,info 为输出参数。实现中先做边界检查,再通过结构体赋值将预定义的 g_camera_info 内容拷贝到输出参数。设备 ID 使用字符串 "0" 和 "1",与 g_device_list 一一对应。朝向字段分别设置为后置(CAMERA_FACING_BACK)和前置(CAMERA_FACING_FRONT),orientation 表示图像顺时针旋转角度。resource_cost 设为 100 表示满资源占用,conflicting_devices 为空表示无互斥设备。
编译与验证
# 编译(Android 源码树内)
mmm hardware/libhardware/modules/camera/
# 或使用 ndk-build 独立编译(需适配 Android.mk)
# 验证方式:编写单元测试调用 get_camera_info
# 1. 调用 get_number_of_cameras() 应返回 2
# 2. 对 camera_id=0 调用 get_camera_info,检查:
# - device_id == "0"
# - facing == CAMERA_FACING_BACK
# - orientation == 90
# - resource_cost == 100
# 3. 对 camera_id=1 调用 get_camera_info,检查:
# - device_id == "1"
# - facing == CAMERA_FACING_FRONT
# - orientation == 270
# 4. 对 camera_id=2 调用应返回 -EINVAL
# 5. 传入 nullptr 作为 info 应返回 -EINVAL
判定标准:上述 5 项检查全部通过,且 get_camera_info 返回 0 时 info 结构体各字段与预期一致,即视为实现正确。本案例代码可直接编译进 HAL 模块,通过 Camera Service 的 ICameraService::getCameraInfo 路径进行端到端验证。