1. 传感器HAL框架初探

任务目标

在Android源码树中创建一个传感器HAL模块,实现传感器列表的静态注册。本案例聚焦于HAL模块的骨架搭建与传感器ID的静态声明,不涉及数据上报与动态事件处理。

环境准备

需要一台已配置Android源码编译环境的Linux主机(推荐Ubuntu 18.04+),源码版本建议使用Android 9.0(Pie)或更高。确保source build/envsetup.sh与lunch已正常执行,且具备mmm单模块编译能力。

目录结构创建

在源码树hardware/interfaces/下创建自定义HAL目录(以sensors_demo为例):

hardware/interfaces/sensors_demo/
├── Android.bp
├── sensors_demo.h
└── sensors_demo.cpp

关键完整代码

sensors_demo.h — 定义HAL模块与设备结构体:

#ifndef SENSORS_DEMO_H
#define SENSORS_DEMO_H

#include <hardware/hardware.h>
#include <hardware/sensors.h>

__BEGIN_DECLS

#define SENSORS_DEMO_HAL_ID "sensors_demo"

struct sensors_demo_device_t {
    struct sensors_poll_device_1 common;
    /* 扩展字段可在此添加 */
};

__END_DECLS

#endif // SENSORS_DEMO_H

sensors_demo.cpp — 实现HAL模块入口与静态传感器列表:

#define LOG_TAG "sensors_demo"
#include <log/log.h>
#include <hardware/hardware.h>
#include <hardware/sensors.h>
#include "sensors_demo.h"

/* 静态注册两个虚拟传感器:加速度计与温度计 */
static struct sensor_t const demo_sensor_list[] = {
    {
        .name = "Demo Accelerometer",
        .vendor = "AOSP",
        .version = 1,
        .handle = 0x1001,
        .type = SENSOR_TYPE_ACCELEROMETER,
        .maxRange = 19.6f,
        .resolution = 0.01f,
        .power = 0.5f,
        .minDelay = 10000,
        .fifoReservedEventCount = 0,
        .fifoMaxEventCount = 0,
        .stringType = SENSOR_STRING_TYPE_ACCELEROMETER,
        .requiredPermission = "",
        .maxDelay = 200000,
        .flags = SENSOR_FLAG_CONTINUOUS_MODE,
        .reserved = {}
    },
    {
        .name = "Demo Thermometer",
        .vendor = "AOSP",
        .version = 1,
        .handle = 0x1002,
        .type = SENSOR_TYPE_AMBIENT_TEMPERATURE,
        .maxRange = 100.0f,
        .resolution = 0.1f,
        .power = 0.3f,
        .minDelay = 1000,
        .fifoReservedEventCount = 0,
        .fifoMaxEventCount = 0,
        .stringType = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE,
        .requiredPermission = "",
        .maxDelay = 100000,
        .flags = SENSOR_FLAG_ON_CHANGE_MODE,
        .reserved = {}
    }
};

static int sensors_demo_close(struct hw_device_t *dev) {
    if (dev) free(dev);
    return 0;
}

static int sensors_demo_open(const struct hw_module_t *module,
                             const char *name,
                             struct hw_device_t **device) {
    if (strcmp(name, SENSORS_HARDWARE_POLL) != 0)
        return -EINVAL;

    struct sensors_poll_device_1 *poll_dev =
        (struct sensors_poll_device_1 *)calloc(1, sizeof(*poll_dev));
    if (!poll_dev) return -ENOMEM;

    poll_dev->common.tag = HARDWARE_DEVICE_TAG;
    poll_dev->common.version = SENSORS_DEVICE_API_VERSION_1_1;
    poll_dev->common.module = (struct hw_module_t *)module;
    poll_dev->common.close = sensors_demo_close;

    /* 静态注册:直接返回传感器列表 */
    poll_dev->get_sensors_list = [](struct sensors_poll_device_1 *dev,
                                     struct sensor_t const **list) {
        *list = demo_sensor_list;
        return ARRAY_SIZE(demo_sensor_list);
    };

    /* 其余poll接口暂置空,仅保证结构完整 */
    poll_dev->activate = nullptr;
    poll_dev->setDelay = nullptr;
    poll_dev->poll = nullptr;
    poll_dev->batch = nullptr;
    poll_dev->flush = nullptr;

    *device = &poll_dev->common;
    return 0;
}

static struct hw_module_methods_t sensors_demo_methods = {
    .open = sensors_demo_open,
};

struct sensors_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = SENSORS_MODULE_API_VERSION_0_1,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = SENSORS_HARDWARE_MODULE_ID,
        .name = "Demo Sensors HAL",
        .author = "AOSP",
        .methods = &sensors_demo_methods,
        .dso = nullptr,
        .reserved = {0},
    },
    .get_sensors_list = [](struct sensors_module_t *module,
                           struct sensor_t const **list) {
        *list = demo_sensor_list;
        return ARRAY_SIZE(demo_sensor_list);
    },
};

Android.bp — 模块编译配置:

cc_library_shared {
    name: "sensors.demo",
    vendor: true,
    relative_install_path: "hw",
    srcs: ["sensors_demo.cpp"],
    shared_libs: [
        "liblog",
        "libhardware",
    ],
    header_libs: ["libhardware_headers"],
    cflags: ["-Wno-unused-parameter"],
}

编译与验证

在源码根目录执行:

source build/envsetup.sh
lunch aosp_arm64-userdebug
mmm hardware/interfaces/sensors_demo/

编译通过后,检查输出文件:

ls $OUT/vendor/lib64/hw/sensors.demo.so

验证方法:将生成的sensors.demo.so推送到设备或模拟器的/vendor/lib64/hw/目录,重启system_server或直接调用SensorManager的getSensorList()接口,观察是否出现名为"Demo Accelerometer"与"Demo Thermometer"的两个传感器。若使用模拟器,可通过adb shell dumpsys sensorservice查看已注册的传感器列表。

判定标准

  • 编译无错误,生成sensors.demo.so动态库;
  • 设备端sensorservice能成功加载该HAL模块;
  • 通过dumpsys sensorservice或应用层API能枚举出上述两个静态注册的传感器,且名称、类型、vendor字段与代码定义一致。
传感器HAL静态注册架构 应用层 SensorManager.getSensorList() Framework SensorService / JNI HAL Interface sensors.h / sensors_poll_device_1 sensors.demo HAL HAL_MODULE_INFO_SYM get_sensors_list() 静态传感器数组 demo_sensor_list[] handle: 0x1001, 0x1002 hw_get_module() 返回指针 关键流程 1. sensorservice 通过 hw_get_module 加载 sensors.demo.so 2. 调用 get_sensors_list() 获取静态注册的传感器数组 → 3. 应用层可枚举