1. 初始化Camera HAL模块
任务说明
本案例目标是在Android Camera HAL层实现模块初始化入口,完成HAL模块结构体定义、open函数注册及基础能力查询,使上层Camera Service能够通过标准HAL接口成功加载并打开相机模块。最终交付一个可编译的HAL模块骨架,支持查询相机设备数量与基本信息。
HAL模块结构定义
// camera_hal_module.c
#include <hardware/hardware.h>
#include <hardware/camera_common.h>
#include <cutils/log.h>
#define CAMERA_MODULE_API_VERSION CAMERA_MODULE_API_VERSION_2_4
#define CAMERA_DEVICE_API_VERSION CAMERA_DEVICE_API_VERSION_2_4
static int camera_device_count(const struct camera_module *module);
static int camera_get_vendor_tag_ops(vendor_tag_ops_t *ops);
static int camera_open_legacy(const struct hw_module_t *module,
const char *id, uint32_t halVersion,
struct hw_device_t **device);
static int camera_set_callbacks(const struct camera_module *module,
camera_module_callbacks_t *callbacks);
static int camera_get_physical_camera_info(const struct camera_module *module,
int camera_id,
camera_metadata_t **info);
static struct hw_module_methods_t camera_module_methods = {
.open = camera_module_open
};
struct camera_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "Demo Camera HAL Module",
.author = "Camera HAL Team",
.methods = &camera_module_methods,
.dso = NULL,
.reserved = {0}
},
.get_number_of_cameras = camera_device_count,
.get_camera_info = camera_get_camera_info,
.set_callbacks = camera_set_callbacks,
.get_vendor_tag_ops = camera_get_vendor_tag_ops,
.open_legacy = camera_open_legacy,
.set_torch_mode = NULL,
.init = NULL,
.reserved = {0}
};
核心函数实现
static int camera_device_count(const struct camera_module *module) {
(void)module;
// 当前仅模拟1个后置摄像头
return 1;
}
static int camera_get_camera_info(const struct camera_module *module,
int camera_id,
struct camera_info *info) {
(void)module;
if (camera_id < 0 || camera_id >= camera_device_count(NULL)) {
ALOGE("Invalid camera id: %d", camera_id);
return -ENODEV;
}
// 静态配置相机基本信息
info->device_version = CAMERA_DEVICE_API_VERSION;
info->device_type = CAMERA_DEVICE_TYPE_HAL;
info->resource_cost = 100;
info->conflicting_devices = NULL;
info->conflicting_devices_length = 0;
// 构造静态相机特征(仅包含必要字段)
static camera_metadata_t *static_metadata = NULL;
if (static_metadata == NULL) {
int32_t facing = CAMERA_FACING_BACK;
uint8_t orientation = 90;
static_metadata = allocate_camera_metadata(8, 16);
add_camera_metadata_entry(static_metadata,
ANDROID_LENS_FACING, &facing, 1);
add_camera_metadata_entry(static_metadata,
ANDROID_SENSOR_ORIENTATION, &orientation, 1);
}
info->static_camera_characteristics = static_metadata;
return 0;
}
static int camera_module_open(const struct hw_module_t *module,
const char *id,
struct hw_device_t **device) {
(void)module;
(void)id;
// 设备打开逻辑在案例2中实现,此处仅返回占位
*device = NULL;
ALOGI("camera_module_open called for id: %s", id);
return -ENODEV;
}
static int camera_set_callbacks(const struct camera_module *module,
camera_module_callbacks_t *callbacks) {
(void)module;
(void)callbacks;
return OK;
}
static int camera_get_vendor_tag_ops(vendor_tag_ops_t *ops) {
(void)ops;
return OK;
}
static int camera_open_legacy(const struct hw_module_t *module,
const char *id, uint32_t halVersion,
struct hw_device_t **device) {
(void)module; (void)id; (void)halVersion; (void)device;
return -ENOSYS;
}
static int camera_get_physical_camera_info(const struct camera_module *module,
int camera_id,
camera_metadata_t **info) {
(void)module; (void)camera_id; (void)info;
return -ENOSYS;
}
Android.bp构建配置
// Android.bp
cc_library_shared {
name: "camera.demo.hal",
vendor: true,
relative_install_path: "hw",
srcs: ["camera_hal_module.c"],
shared_libs: [
"libhardware",
"libcamera_metadata",
"libcutils",
"liblog"
],
header_libs: [
"libhardware_headers",
"libcamera_metadata_headers"
],
cflags: ["-Wall", "-Werror"],
proprietary: true,
}
编译与验证
在Android源码树中执行以下命令完成编译与验证:
# 编译HAL模块
source build/envsetup.sh
lunch <target>
m camera.demo.hal
# 验证模块加载(adb shell)
adb push ${OUT}/vendor/lib64/hw/camera.demo.hal.so /vendor/lib64/hw/
adb shell chmod 644 /vendor/lib64/hw/camera.demo.hal.so
adb shell "cat /vendor/lib64/hw/camera.demo.hal.so | grep -c 'HAL_MODULE_INFO_SYM'"
验证判定标准
- 编译通过:执行
m camera.demo.hal无错误,生成camera.demo.hal.so文件; - 符号检查:使用
readelf -s camera.demo.hal.so | grep HAL_MODULE_INFO_SYM确认符号存在且为GLOBAL类型; - 加载测试:在设备端执行
adb shell "cameraserver",日志中无Failed to load HAL module错误,且通过adb shell dumpsys media.camera可看到相机数量为1; - 信息查询:调用
getCameraInfo(0)返回的facing为BACK,orientation为90,与代码配置一致。