1. 初始化Camera HAL模块

任务说明

本案例目标是在Camera HAL层实现camera_module_t结构体的定义与初始化,完成模块API(open、get_number_of_cameras、get_camera_info)以及回调函数指针(set_callbacks)的赋值,使上层框架能够通过标准HAL接口访问到该模块。

核心实现

// camera_hal_module.c
#include <hardware/camera_common.h>
#include <hardware/hardware.h>
#include <stdlib.h>
#include <string.h>

// 前向声明
static int camera_device_open(const struct hw_module_t* module,
                              const char* id,
                              struct hw_device_t** device);
static int get_number_of_cameras(void);
static int get_camera_info(int id, struct camera_info* info);
static int set_callbacks(const camera_module_callbacks_t* callbacks);

// 模块实例
static struct hw_module_methods_t camera_module_methods = {
    .open = camera_device_open
};

// 回调函数指针(由框架注册)
static const camera_module_callbacks_t* g_callbacks = NULL;

// 相机信息静态数据
static struct camera_info g_camera_info[] = {
    {
        .device_id = "0",
        .facing = CAMERA_FACING_BACK,
        .orientation = 90,
        .resource_cost = 100,
        .conflicting_devices = NULL,
        .conflicting_devices_length = 0
    }
};

// camera_module_t 定义与初始化
struct 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 = "Example Camera HAL Module",
        .author = "Camera HAL Dev",
        .methods = &camera_module_methods,
        .dso = NULL,
        .reserved = {0}
    },
    .get_number_of_cameras = get_number_of_cameras,
    .get_camera_info = get_camera_info,
    .set_callbacks = set_callbacks,
    .get_vendor_tag_ops = NULL,
    .open_legacy = NULL,
    .set_torch_mode = NULL,
    .init = NULL,
    .reserved = {0}
};

// ---- 模块API实现 ----

static int camera_device_open(const struct hw_module_t* module,
                              const char* id,
                              struct hw_device_t** device)
{
    // 本案例仅完成模块初始化,设备打开逻辑在后续案例中实现
    (void)module;
    (void)id;
    (void)device;
    return -ENODEV;
}

static int get_number_of_cameras(void)
{
    return sizeof(g_camera_info) / sizeof(g_camera_info[0]);
}

static int get_camera_info(int id, struct camera_info* info)
{
    if (id < 0 || id >= get_number_of_cameras() || info == NULL) {
        return -EINVAL;
    }
    *info = g_camera_info[id];
    return 0;
}

static int set_callbacks(const camera_module_callbacks_t* callbacks)
{
    if (callbacks == NULL) {
        return -EINVAL;
    }
    g_callbacks = callbacks;
    return 0;
}

编译配置

// Android.bp
cc_library_shared {
    name: "camera.primary.example",
    vendor: true,
    relative_install_path: "hw",
    srcs: ["camera_hal_module.c"],
    shared_libs: [
        "libhardware",
        "liblog",
        "libcutils"
    ],
}

落地与验证

部署方式:将编译产物camera.primary.example.so推送至设备的/vendor/lib64/hw/目录(64位系统),并确保camera.hal1.packagelist或相关权限配置允许访问。

验证方法:

  1. 在设备端执行lshal或dumpsys media.camera,观察是否能够枚举到名为Example Camera HAL Module的模块;
  2. 编写小型测试程序调用hw_get_module(CAMERA_HARDWARE_MODULE_ID, ...)获取模块句柄,检查返回的camera_module_t指针非空;
  3. 调用get_number_of_cameras(),预期返回1;调用get_camera_info(0, &info),预期info.facing == CAMERA_FACING_BACK且info.orientation == 90;
  4. 调用set_callbacks(&mock_callbacks),预期返回0,且传入NULL时返回-EINVAL。

判定标准:上述测试均通过,且模块能够被系统HAL加载机制正常识别,即视为本案例目标达成。