1. 初始化Camera HAL模块

任务说明

本案例实现Android Camera HAL模块的加载与初始化,核心目标是:定义符合硬件抽象层规范的hw_module_t结构体,填充模块基本信息,并完成open函数指针的赋值,使上层Camera Service能够通过标准HAL接口成功加载并打开Camera设备。

模块头文件定义

// camera_hal.h
#ifndef ANDROID_CAMERA_HAL_H
#define ANDROID_CAMERA_HAL_H

#include <hardware/hardware.h>
#include <hardware/camera_common.h>
#include <cutils/log.h>

// 自定义Camera HAL模块结构体,扩展自hw_module_t
typedef struct camera_hw_module {
    hw_module_t common;
    // 可在此处添加厂商自定义字段
    int vendor_specific_value;
} camera_hw_module_t;

// HAL模块打开的设备句柄结构体
typedef struct camera_hw_device {
    hw_device_t common;
    // 设备相关操作函数指针将在后续案例中填充
    int (*device_specific_op)(struct camera_hw_device* dev);
} camera_hw_device_t;

// HAL模块入口点,由hw_get_module()调用
int camera_hal_open(const hw_module_t* module, const char* name, hw_device_t** device);

#endif // ANDROID_CAMERA_HAL_H

模块实现代码

// camera_hal.cpp
#define LOG_TAG "camera_hal"
#include "camera_hal.h"
#include <cutils/log.h>

// 前置声明:设备打开函数
static int camera_device_open(const hw_module_t* module, const char* name,
                              hw_device_t** device);

// 模块open函数指针赋值目标
static int camera_module_open(const hw_module_t* module, const char* name,
                              hw_device_t** device) {
    ALOGI("camera_module_open: name = %s", name);
    return camera_device_open(module, name, device);
}

// 静态模块实例,hw_module_t结构体填充
static struct hw_module_methods_t camera_module_methods = {
    .open = camera_module_open
};

// HAL_MODULE_INFO_SYM是hw_get_module()查找的符号
struct camera_hw_module 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 = "Camera HAL Module",
        .author = "Android Camera HAL Course",
        .methods = &camera_module_methods,
        .dso = nullptr,
        .reserved = {0}
    },
    .vendor_specific_value = 0x2019
};

// 设备打开实现:当前仅完成设备结构体分配与基础初始化
static int camera_device_open(const hw_module_t* module, const char* name,
                              hw_device_t** device) {
    if (module == nullptr || device == nullptr) {
        ALOGE("camera_device_open: invalid argument");
        return -EINVAL;
    }

    // 分配设备结构体内存
    camera_hw_device_t* dev = (camera_hw_device_t*)calloc(1, sizeof(camera_hw_device_t));
    if (dev == nullptr) {
        ALOGE("camera_device_open: failed to allocate memory");
        return -ENOMEM;
    }

    // 填充hw_device_t公共字段
    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = CAMERA_DEVICE_API_VERSION_2_4;
    dev->common.module = (hw_module_t*)module;
    dev->common.close = nullptr;  // close函数将在设备操作实现案例中赋值

    // 初始化厂商自定义字段
    dev->device_specific_op = nullptr;

    // 将设备指针返回给调用者
    *device = &dev->common;
    ALOGI("camera_device_open: device opened successfully");

    return 0;
}

Android.bp构建配置

// Android.bp
cc_library_shared {
    name: "camera.hello_hal",
    vendor: true,
    relative_install_path: "hw",
    srcs: ["camera_hal.cpp"],
    shared_libs: [
        "liblog",
        "libcutils",
        "libhardware",
    ],
    header_libs: ["libhardware_headers"],
}

编译与部署

# 在Android源码根目录执行
source build/envsetup.sh
lunch <your_target>
mmm hardware/camera_hal_course/

# 编译产物路径
# out/target/product/<device>/vendor/lib64/hw/camera.hello_hal.so

验证方法

编写以下测试程序验证模块加载与初始化是否成功:

// hal_test.cpp
#include <hardware/hardware.h>
#include <hardware/camera_common.h>
#include <cstdio>

int main() {
    const hw_module_t* module = nullptr;
    int ret = hw_get_module(CAMERA_HARDWARE_MODULE_ID, &module);
    if (ret != 0) {
        printf("FAIL: hw_get_module returned %d\n", ret);
        return -1;
    }

    // 验证模块结构体字段
    printf("Module id: %s\n", module->id);
    printf("Module name: %s\n", module->name);
    printf("Module api version: %d\n", module->module_api_version);
    printf("Module methods open: %p\n", module->methods->open);

    // 验证open函数指针已赋值
    if (module->methods->open == nullptr) {
        printf("FAIL: open function pointer is null\n");
        return -1;
    }

    // 尝试打开设备
    hw_device_t* device = nullptr;
    ret = module->methods->open(module, "0", &device);
    if (ret != 0 || device == nullptr) {
        printf("FAIL: device open returned %d\n", ret);
        return -1;
    }

    printf("PASS: HAL module loaded and device opened successfully\n");
    printf("Device tag: %d\n", device->tag);
    printf("Device module pointer: %p\n", device->module);

    return 0;
}

判定标准:

  1. 编译无错误,生成camera.hello_hal.so动态库;
  2. 测试程序执行后输出PASS: HAL module loaded and device opened successfully;
  3. 模块的id字段为"camera",methods->open非空;
  4. 设备打开后返回的hw_device_t结构体tag正确且module指针指向加载的模块实例。

预期输出(由代码逻辑直接推出):

Module id: camera
Module name: Camera HAL Module
Module api version: 512
Module methods open: 0x...
PASS: HAL module loaded and device opened successfully
Device tag: 1
Device module pointer: 0x...

本案例完成了HAL模块的静态定义、hw_module_t结构体填充、open函数指针赋值以及设备打开的基础实现。上层通过hw_get_module()即可加载该模块,并通过methods->open完成设备句柄的创建,为后续Camera设备操作函数的实现奠定基础。