转载出处:https://blog.csdn.net/wangjun7121/article/details/61916427
/*
Sensor 整体框架:
Sensor app开发一般会包含五步:【后面有详细流程介绍】
【1】. 获取sensor manager对象;
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
【2】. 获取sensor object;
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
【3】. 定义eventListener:
mLightSensorListener = new SensorEventListener()
【4】. 注册eventListener;
mSensorManager.registerListener(mLightSensorListener, mLightSensor,
LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
【5】. 卸载eventListener;
mSensorManager.unregisterListener(mLightSensorListener);
【1】 【3】:调用注册的回调进行数据处理
| | 【App】
--------|---------------------------------------------------|---------------------------------
SystemSensorManager |
| |
| | 【Java】【Framework】
------|------------------------------------ jni ----------|---------------------------------
【客户端】 "sensorservice" 【服务器】 BitTube[socket] 【C++】
SensorManager <---- Binder ----> SensorService |
| |
SensorDevice ----- // 创建一个线程轮询 HAL 获得数据
| // 然后通过套接字发给需要的进程
|
HAL:平台相关的传感器操作库
|[mtk:hwmsen] // input 上报有数据,设备节点读数据
-------------------------------------------------------------------------------------------
| MTK:hwmsen | 【kernel】
--------------------------------------------------
[传感器驱动1] [传感器驱动2] ... [传感器驱动N] |
--------------------------------------------------
传感器硬件
相关类关系:
Sensor(Java): 代表着一个传感器,包含传感器的各种信息如名称、类别等,直接对应 native 层的 sensor_t
SensorEvent(Java): 传感器上报的参数数据信息。Sensor 的采样值、精确度、时间戳以及数据来源于哪个传感
器等信息封装在 Java 类 SensorEvent
SensorEventListener(Java): 数据监听器接口,它有两个成员函数接口,用于处理传感器精度变化和上报的传感
器采样数据。应用开发者编写它的一个子类以实现对 SensorEvent 的监听,从而对它们做出
相应的处理。
SystemSensorManager(Java):应用程序通过它使用系统的各种传感器?
SensorManager(C++): Binder 客户端,通过 Binder 通信与 SensorService 服务通信,请求其服务
SensorService(C++): 注册 Binder 服务类,他调用 SensorDevice 类获取传感器参数,返回给 Binder 客户端
HardwareSensor(C++): 通过 SensorService 类与 HAL 层平台实现的传感器管理库通信,逻辑上代表传感器硬件。
SensorDevice(C++):用于与 HAL 层平台实现的管理传感器的库通信,用来获得传感器数据等
SensorFusion(C++): 对加速计,磁场计和陀螺仪三个物理传感器的数据进行综合处理
SensorEventQueue(C++): 通过 BitTube 进行套接字通信,进行传感器数据的收发工作
Receiver(C++): 接收 SensorService 通过 BitTube 套接发来的数据,然后调用 Java 类 SensorEventQueue::dispatchSensorEvent()
让其进行数据分发,调用 app 注册的监听函数进行处理
目前系统支持的传感器类型:[hardware/libhardware/include/hardware/sensors.h]
加速计:TYPE_ACCELEROMETER 返回 x/y/z 轴上的加速度数值,通常由物理的 G-Sensor 提供。
重力加速度:TYPE_GRAVITY 返回 x/y/z 轴上的重力加速度数据
线性加速度:TYPE_LINERA_ACCELERATION 不考虑地球重力加速度后的 x/y/z 轴上的加速度,因此:
【加速计 = 重力加速度 + 线性加速度】
陀螺仪:TYPE_GYROSCOPE 返回 x/y/z 轴上的角速度,用于测量设备自身的旋转运动。陀螺仪的基本原理是
一个旋转的物体在不受外力影响时,其旋转轴方向保持稳定。
磁场计:TYPE_MAGNETIC_FIELD 即电子指南针,返回 x/y/z 轴上的磁场强度和方向,主要用于测量设备的东西
南北方位。
方位计:TYPE_ORIENTATION 返回方位角(Azimuth, 围绕 z 轴,磁场的北方向为 0,东方向为 90度)、俯仰角
(Pitch, 围绕 x 轴的旋转)、滚转角(Roll,围绕 y 轴的旋转)。
【由加速计和磁场计的数据经过计算得到】
光线传感器: TYPE_LIGHT 获取外部环境的光线强度,可根据它自动调节手机屏幕亮度。
环境温度计:TYPE_AMBIENT_TEMPERATURE 外界环境的温度。
相对温度计:TYPE_RELATIVE_HUMIDITY 外界环境的空气温度。
距离传感器:TYPE_PROXIMITY 判断外部物体与手机设备的远近,如用于接听电话时判断耳朵靠近后关闭屏幕。
压力计:TYPE_PRESSURE 返回当前的压强。
旋转矢量计:TYPE_ROTATION_VECTOR 一个逻辑上的传感器,综合了加速器和磁场传感器的返回值,屏幕旋转依
据它上报的数据。
应用层使用传感器:
1. 获得系统传感器管理器:
SensorManger = getSystemService(Contex.SENSOR_SERVICE)
2. 获得光感传感器对象:
Sensor = SensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
3. 创建一个传感器监听器:
SensorEventListener = new SensorEventListener
4. 注册传感器监听器:
SensorManager.registerListener()
HAL 层涉及相关结核体:
HAL 层数据结构:
// 传感器模块结构体:内部封装【hw_module_t】,用于定位和获得 HAL 层封装的【hw_device_t】结构体操作硬件
// 仅是针对 hw_module_t 增加了一个 get_sensors_list()
// 函数,用于获得传感器列表【hw_module_t 相关介绍在 【HAL - 硬件抽象层】文档中】
// 【 hw_module_t 主要作用】:模块属性
// 1. 在动态库中定位,因为会声明变量明为 HAL_MODULE_INFO_SYM,用于打开动态库时通过
// dlsym() 来获得定义的结构体入口,从而可以获得动态库入口。
// 2. 打开初始化硬件,返回包含操作函数的结构体, 能初始化是因为 hw_module_t.hw_module_methods_t.open()
// 指向了一个打开函数,用于初始化打开硬件设备, 返回对应的硬件操作结构体 hw_device_t 指针。
//
// HAL 规定不能直接使用 hw_module_t 结构体
// 因此需要为 hw_device_t 外再套一层结构体(这也是 HAL 要求的)
/
struct sensors_module_t {
// 【hw_module_t】:主要用于定位动态库入口以及找到初始化的 open() 函数,获得包括硬件操作函数集的 hw_device_t 结构体
struct hw_module_t common;
// // 描述 HAL 模块的 hw_module_t 结构体:
// typedef struct hw_module_t{
// uint32_t tag; // 模块的 Tag, 值必须是 HARDWARE_MODULE_TAG
// uint16_t version_major; // 模块主版本号
// uint16_t version_minor; // 模块从版本号
// const char *id; // 模块的 ID,通过该 ID 可以找到当前模块
// const char *name; // 模块名称
// const char *author; // 模块作者
// struct hw_module_methods_t *methods; // 与模块相关的函数指针, 都包含在 hw_module_methods_t 结构体中
// // hw_module_methods_t 结构体定义:
// // typedef sturct hw_module_methods_t{
// // int (*open)(const struct hw_module_t* module, const char* id, struct hw_device_t** device);
// // }hw_module_methods_t
// void* dso; // 模块的 dso,保存当前打开的动态库的句柄 dlopen() 返回的
// uint32_t reserved[32-7]; // 保留的空间
// } hw_module_t
// 用于获取传感器的列表
int (*get_sensors_list)(struct sensors_module_t* module,
struct sensor_t const** list);
};
// 传感器操作结构体:内部封装 【hw_device_t】,用于具体操作硬件,获取硬件数据
// 【 hw_device_t 作用】: 设备操作
// 1. 实现具体的硬件接口操作,因为它外部封装了硬件操作函数,如 set_val()/get_val()
// 2. 关闭设备。因为 hw_deice_t.close() 指向了设备关闭函数。
//
typedef struct sensors_poll_device_1 {
union {
///
// 兼容 0.1 版本接口
struct sensors_poll_device_t v0;
// struct sensors_poll_device_t {
// struct hw_device_t common;
// int (*activate)(struct sensors_poll_device_t *dev,
// int handle, int enabled);
// int (*setDelay)(struct sensors_poll_device_t *dev,
// int handle, int64_t ns);
// int (*poll)(struct sensors_poll_device_t *dev,
// sensors_event_t* data, int count);
// };
struct
{
struct hw_device_t common;
int (*activate)(struct sensors_poll_device_t *dev, // 使用传感器,写 1 使用, 写 0 除能
int handle, int enabled);
int (*setDelay)(struct sensors_poll_device_t *dev, // 设置传感器事件周期,单位 ns,具体含义参见触发模式
int handle, int64_t period_ns); // continuous: setDelay() sets the sampling rate.
// on-change: setDelay() limits the delivery rate of events
// one-shot: setDelay() is ignored. it has no effect.
// special: see specific sensor type definitions
int (*poll)(struct sensors_poll_device_t *dev, // 返回包含传感器值的数组
sensors_event_t* data, int count);
};
};
//
// 让给定传感器进入缓冲模式(batch mode),积累一定数据后,再在超时时上报,并设置上报事件超时时间,单位 ns【需要硬件支持缓冲】
int (*batch)(struct sensors_poll_device_1* dev, int handle, int flags, int64_t period_ns, int64_t timeout);
//
// 刷新 batch mode 的数据缓冲区(丢弃?),并在缓冲区后跟一个 sensors_event_meta_data_t 数据
int (*flush)(struct sensors_poll_device_1* dev, int handle);
void (*reserved_procs[8])(void);
} sensors_poll_device_1_t;
//
// Sensoer 设备结构体:每个 sensor 设备都应该有个
//
struct sensor_t {
const char* name; // 传感器名称
const char* vendor; // 传感器厂家信息
int version; // 硬件+驱动版本号
int handle; // 传感器句柄
int type; // 传感器类型
float maxRange; // 最大范围
float resolution; // 解析度:传感器值的步进单位
float power; // 传感器的耗电量,单位 mA
int32_t minDelay; // 根据传感器触发方式而定的采样周期值,中断不需要,轮询才需要?
// continuous: minimum sample period allowed in microseconds
// on-change : 0
// one-shot :-1
// special : 0, unless otherwise noted
uint32_t fifoReservedEventCount; // 此传感器上报事件所拥有的独有 events 缓冲区大小
uint32_t fifoMaxEventCount; // 此传感器与其他传感器共享的 events 缓冲区大小
void* reserved[6];// 保留字段,必须为 0
};
///
// 每个传感器上报的数据都由此结构体表示
//
typedef struct sensors_event_t {
int32_t version; // sensors_event_t 结构体的大小,因为不同传感器,上报的 sensors_event_t 大小不一样
int32_t sensor; // 传感器标志符
int32_t type; // 传感器类型
int32_t reserved0; // 保留位
int64_t timestamp; // 时间戳,单位 ns
///
// 用联合体来表征不同传感器数据的结构体
union {
union {
float data[16];
sensors_vec_t acceleration; // 加速度值,单位 m/s^2
sensors_vec_t magnetic; // 磁通量,单位 uT
sensors_vec_t orientation; // 方向角,单位度
sensors_vec_t gyro; // 角加速度,单位 rad/s(每秒多少转)
// typedef struct
// {
// union
// {
// float v[3];
// struct
// {
// float x;
// float y;
// float z;
// };
// struct
// {
// float azimuth;
// float pitch;
// float roll;
// };
// };
// int8_t status;
// uint8_t reserved[3];
// } sensors_vec_t;
float temperature; // 摄氏温度值
float distance; // 距离,单位 cm
float light; // 亮度,单位 lux(勒克斯)
float pressure; // 压力值,单位 hPa(百帕)
float relative_humidity; // 相对温度百分比
uncalibrated_event_t uncalibrated_gyro; // 未校准的角加速度,单位 rad/s
uncalibrated_event_t uncalibrated_magnetic; // 未校验的磁通量,单位 mT
// typedef struct
// {
// union
// {
// float uncalib[3];
// struct
// {
// float x_uncalib;
// float y_uncalib;
// float z_uncalib;
// };
// };
// union
// {
// float bias[3];
// struct
// {
// float x_bias;
// float y_bias;
// float z_bias;
// };
// };
// } uncalibrated_event_t;
meta_data_event_t meta_data; // 必须为 0,奇怪
// typedef struct meta_data_event {
// int32_t what;
// int32_t sensor;
// } meta_data_event_t;
};
union {
uint64_t data[8];
uint64_t step_counter; // 步进值
} u64;
};
uint32_t reserved1[4];
} sensors_event_t;
///
// 有个遗憾的问题:
// sensorservice 应该是在 Main_sensorservice.cpp (frameworks\native\services\sensorservice)
// 中进行初始化的,因为在这里进行了线程库的添加以及 Binder 服务的注册。
// 但是自始至终都没有找到这个可执行文件在哪里被调用的,下面的分析只看到了 Binder 服务的注册,
// 并没有看到线程库的添加。
// Main_sensorservice.cpp 根据同目录下的 Android.mk 可以看到当前程序编译生成了 sensorservice 这个可
// 执行程序,放在了 /system/bin 目录下,可惜没有看到调用处。
///
【Sensor 初始化流程】:
zygote
SystemServer::main()
///
// 1. 注册安卓服务使用的 Jni 函数, 比如自己添加启动有服务也需要添加
// 这里会注册下面用到的 jni 函数 nativeInit() 用过初始化传感器服务
System.loadLibrary("android_servers");
//
// Jni: Onload.cpp (frameworks\base\services\jni)
// 确定调用上面函数依据:原因是其同文件夹下的 Android.mk 有以下一句话:
// LOCAL_MODULE:= libandroid_servers
JNI_OnLoad(JavaVM* vm, void* reserved)
// 注册了下面用到的 jni 函数
register_android_server_SystemServer(env);
// com_android_server_SystemServer.cpp (frameworks\base\services\jni)
register_android_server_SystemServer(JNIEnv* env)
return jniRegisterNativeMethods(env, "com/android/server/SystemServer", gMethods, NELEM(gMethods));
// static JNINativeMethod gMethods[] = {
// // name, signature, funcPtr
// { "nativeInit", "()V", (void*) android_server_SystemServer_nativeInit },
// };
///
// Initialize native services.
// 2. 启动 SensorService 服务类,他会创建一个线程,循环调用 HAL 层的平台传感器
// 操作库,获得传感器数据,然后通过套接字发给需要的进程。
// 注册 "sensorservice" 服务到 servermanger 进程中进行管理
nativeInit();
//
// com_android_server_SystemServer.cpp (frameworks\base\services\jni)
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
//
// 【重点】:启动 sensor service
// 实际上就是 C++ 层通过 Binder 实际服务端的流程:参考 【Binder 文件夹下内容】
// Start the sensor service
SensorService::instantiate();
// SensorService.h (frameworks\native\services\sensorservice)
// class SensorService : public BinderService<SensorService>,
// public BnSensorServer,
// protected Thread
BinderService::instantiate()
publish()
// 1. 首先获得 service manager 进程的 Binder 代理对象
sp<IServiceManager> sm(defaultServiceManager())
// 2. 注册服务到 service manager 进程中
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated)
// SERVICE 在此位是一个模板,其实上指向 SensorService
// 所以 SERVICE::getServiceName() 实际上是 SensorServicegetServiceName()
// 返回要注册的服务名为:【"sensorservice"】重点!!!下面会用到。
// 注册的服务对象类:new SERVICE() 实际上是 new SensorService()
// 【重点中的重点】:new SERVICE()是强引用 sp sensorservice,
// 所以会调用到 SensorService::onFirstRef()
// addService 函数原型如下:IServiceManager.h (frameworks\native\include\binder)
// addService( const String16& name, const sp<IBinder>& service, bool allowIsolated = false) = 0;
///
// 这里首先会获得 HAL 层中的平台传感器操作库,然后创建一个线程,循环通过 HAL 中
// 的平台传感器操作库获得传感器的值,然后通过套接字发给其他需要的进程
// C++: SensorService.cpp (frameworks\native\services\sensorservice)
SensorService::onFirstRef()
// 获得 SensorDevice 的单实例对象,这里因为是第一次,所以会调用 SensorDevice 构造函数
// 来初始化 SensorDevice 类对象, 他会获得 HAL 层平台相关的传感器操作库,并获得库中相关
// 函数与平台声明的传感器列表,保存在键值对中并关闭所有传感器
SensorDevice& dev(SensorDevice::getInstance());
//
// C++:SensorDevice.cpp (frameworks\native\services\sensorservice)
SensorDevice::SensorDevice() : mSensorDevice(0), mSensorModule(0)
//
// 获得 HAL 层的 Sensor 动态库, 平台相关,用于管理平台上用的传感器的
// 主要从系统路径中加载一个模块 ID 为 sensor 的动态库,
// 第二个参数是我们所要获得的 hw_module_t, 这里获得的对应结构体为:sensors_module_t
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule);
//
// 有关 HAL 查找流程,可见 【HAL - 硬件抽象层】
//
// 这里通过硬件抽象层 HAL,获得动态库 sensor.<可变后缀>.so
// 然后返回了一个 hw_module_t 指针类型的变量,在 MTK 的平台上,
// 对应的动态库实现 HAL 文件路径为:
// HAL: Sensors_hwmsen.c (mediatek\hardware\sensor)
// 返回的结构体为:
// struct sensors_module_t HAL_MODULE_INFO_SYM = {
// .common = {
// .tag = HARDWARE_MODULE_TAG,
// .version_major = 1,
// .version_minor = 0,
// .id = SENSORS_HARDWARE_MODULE_ID,
// .name = "MTK SENSORS Module",
// .author = "The Android Open Source Project",
// .methods = &sensors_module_methods,
// },
// // 此操作函数是 sensor 特别添加的
// .get_sensors_list = sensors__get_sensors_list,
// };
// 获得 sensor 动态库成功: sensors_module_t
// 然后调用 HAL 代码中 hw_module_t.hw_module_methods_t.open() 函数
// 用于获得 平台相关的具体操作传感器的函数集,然后获得平台声明的传感器列表
// 保存到一个键值对数组中,关闭所有传感器
if (mSensorModule)
// 调用 hw_module_t.hw_module_methods_t.open() 初始化模块,返回
// 模块的操作函数集:hw_device_t 被封装的结构体:sensors_data_context_t
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
// 初始化模块,最终调用的是 hw_module_t.hw_module_methods_t.open()
// 指向了一个打开函数,用于初始化打开硬件设备, 返回对应的硬件操作结构体 hw_device_t 指针
return module->methods->open(module, SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
///
//HAL: Sensors_hwmsen.c (mediatek\hardware\sensor)
open_sensors(const struct hw_module_t* module, const char* name, struct hw_device_t** device)
// 1. 分配一个 sensors_data_context_t 结构体,MTK 封装 sensors_poll_device_t 类型
// struct sensors_data_context_t {
// struct sensors_poll_device_t device;
// int events_fd; // dev/input/hwmdata 文件句柄
// int device_io_fd; // /dev/hwmsensor 文件句柄
// uint32_t active_sensors;
// sensors_event_t sensors[MAX_ANDROID_SENSOR_NUM]; // HAL 层临时保存数据用
// uint32_t pendingSensors; //
// int (*activate)(struct sensors_data_context_t *dev,int handle, int enabled);
// int(*set_delay)(struct sensors_data_context_t *dev, int handle, int64_t ns);
// int( *poll)(struct sensors_data_context_t *dev, sensors_event_t* values, int count);
// };
//
// 2. 设置 sensors_data_context_t 结构体
///
// 【驱动相关】: 查找打开 /dev/input/hwmdata 输入节点!!!
// 此节点正对应 MTK 内核添加的 sensor 中间层
///
dev->events_fd = open_input(O_RDONLY);
dev->device_io_fd = open(HWM_SENSOR_DEV, O_RDONLY); // 打开 /dev/hwmsensor 设备节点
/
// MTK 自己添加实现的
dev->activate = hwm__activate;
dev->set_delay = hwm__set_delay;
dev->poll = hwm__poll;
///
// hw_device_t 用到的关闭函数
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = 0;
dev->device.common.module = (struct hw_module_t*)module;
dev->device.common.close = data__close;
///
// android 系统调用的: 用于中转到 MTK 自己添加实现的函数
dev->device.activate = control__activate;
dev->device.setDelay = control__setDelay;
dev->device.poll = data__poll;
///
// 3. 通过指针的指针返回设置好的 sensors_data_context_t 结构体
*device = &dev->device.common;
///
// 4. 创建线程用于调试
pthread_create(&thread, NULL,sensors_debug, (void*)dev);
///
// 获得 sensor 操作函数成功: sensors_data_context_t
// 然后获得平台声明的所有传感器列表,将其保存到键值对
// 然后关闭所有传感器
if (mSensorDevice)
// 调用路径为 sensors_module_t.get_sensors_list()
// 返回平台声明定义有的传感器列表
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
/
// //HAL: Sensors_hwmsen.c (mediatek\hardware\sensor)
static int sensors__get_sensors_list(struct sensors_module_t* module, struct sensor_t const** list)
*list = sSensorList;
return sizeof(sSensorList)/sizeof(sSensorList[0]);
///
// MTK 传感器清单定义位置:
// Hwmsen_custom.c (mediatek\custom\hongyu82_wet_kk\hal\sensors\sensor)
// struct sensor_t sSensorList[MAX_NUM_SENSORS] =
// {
// // MT6516 the spec follows ADXL345
// {
// .name = "MT6516 3-axis Accelerometer",
// .vendor = "The Android Open Source Project",
// .version = 1,
// .handle = ID_ACCELEROMETER,
// .type = SENSOR_TYPE_ACCELEROMETER,
// .maxRange = 32.0f,
// .resolution = 4.0f/1024.0f,
// .power =130.0f/1000.0f,
// .reserved = {}
// },
// };
/
// 将获得的传感器 sensor_t 结构体的列表添加到一个键值对数组中
// 保存的是 《传感器句柄,Info类》
// 然后调用 sensors_data_context_t.activate( snensor 操作函数集,要操作的传感器句柄,使能(1)/除能(0))
// 关闭所有传感器
mActivationCount.setCapacity(count);
for (size_t i=0 ; i<size_t(count) ; i++)
mActivationCount.add(list[i].handle, model);
mSensorDevice->activate(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), list[i].handle, 0)
///
//HAL: Sensors_hwmsen.c (mediatek\hardware\sensor)
control__activate(struct sensors_poll_device_t *dev, int handle, int enabled)
// 中转到 MTK 自己添加实现的函数中去处理
struct sensors_data_context_t* ctx = (struct sensors_data_context_t*)dev;
return ctx->activate((struct sensors_data_context_t*)dev,handle, enabled);
hwm__activate(struct sensors_data_context_t *dev, int handle, int enabled)
// 1. 如果需要使能传感器
if(enabled == 1)
// 通过 ioctl() 控制驱动层的 hwmsen 模块使能传感器
// 让 hwmsen 模块开始通过上报数据
ioctl("/dev/hwmsensor", HWM_IO_ENABLE_SENSOR, &handle)
// 如果使能的是 方位计,则需要先打开加速度与磁传感器,因为
// 【方位计由加速计和磁场计的数据经过计算得到】
else
///
// 2. 如果需要除能传感器
// 如果除能的是方位计,则需要关闭加速度与磁传感器
// 通过 ioctl() 控制驱动层的 hwmsen 模块除能传感器
ioctl(dev->device_io_fd, HWM_IO_DISABLE_SENSOR, &handle)
//
// 如果初始化成功,成功获得了 HAL 层两个核心结构体:
// mSensorModule = sensors_module_t
// mSensorDevice = sensors_data_context_t
// 位于 HAL: Sensors_hwmsen.c (mediatek\hardware\sensor)
// 如果通过 HAL 层的平台动态库获得传感器列表,然后根据传感器列表,将其注册到系统中
// 管理,并根据已有的硬件传感器类型,注册几个虚拟传感器到系统,创建一个进程循环检查
// 硬件传感器的值,上报上来,处理后从中获得虚拟传感器的值,然后通过套接字发送给监听
// 传感器值的进程
if (dev.initCheck() == NO_ERROR)
///
// 调用 sensors_module_t.get_sensors_list() 获得 MTK 平台声明的传感器列表
// 具体操作函数文件位于:
// HAL: Sensors_hwmsen.c (mediatek\hardware\sensor)
ssize_t count = dev.getSensorList(&list);
/
// 如果平台有定义传感器列表的话,遍历传感器列表,注册传感器
// 将其添加到 SensorDevice 的列表中进行管理, 注册完传感器后,
// 创建一个线程,循环调用 HAL 层的平台传感器操作库获得传感器上报值
// 然后再处理硬件传感器值获得虚拟传感器的值,最后再通过套接字,将
// 传感器的值发给客户端进程
// 【注意】:传感器列表是 sensor_t 类型的
if (count > 0)
for (ssize_t i=0 ; i<count ; i++)
// 将 HAL 层的 sensor_t 结构初始化一个 HardwareSensor 类,
// 然后为 HardwareSensor::mSensor 创建一个 Sensor 类对象
// 并将其添加到 SensorService 类中的列表中去管理
registerSensor( new HardwareSensor(list[i]) );
// 主要是初始化 SensorFusion 类,获得 HAL 层的平台声明的传感器列表,然后
// 将一些传感器句柄保存到内部变量里,并初始化了内部的 Fusion 类变量设置为0
const SensorFusion& fusion(SensorFusion::getInstance());
//
// SensorFusion.cpp (frameworks\native\services\sensorservice)
SensorFusion::SensorFusion()
// 获得平台声明的传感器列表
ssize_t count = mSensorDevice.getSensorList(&list);
// 遍历平台上声明的传感器列表,根据 HAL 层的 sensor_t 结构体初始化 Sensor 类
// 保存到 SensorFusion 类中
if (count > 0)
for (size_t i=0 ; i<size_t(count) ; i++)
// SensorFusion::mAcc 保存加速度传感
// SensorFusion::mMag 保存磁传感器
// SensorFusion::mGyro 保存陀螺仪传感器
// SensorFusion::uncalibratedGyro 保存未校准陀螺仪传感器
// 如果有 SensorFusion::uncalibratedGyro 对象,则将其赋值给 SensorFusion::mGyro
// 设置陀螺仪传感器的事件上报时间与周期等,然后初始化 Fusion 类的成员变量,将其设置为 0
mEstimatedGyroRate = 200;
mTargetDelayNs = 1000000000LL/mEstimatedGyroRate;
mFusion.init();
// 如果有陀螺仪,则注册虚拟传感器,如果系统没有对应的实体传感器的话
// 【陀螺仪可以模拟这么多?】注册就是创建一个类对象添加到 SensorService::mVirtualSensorList
// 虚拟的传感器列表中
if (hasGyro)
aSensor = registerVirtualSensor( new RotationVectorSensor() );
Sensor sensor = registerSensor(s);
mVirtualSensorList.add( s );
aSensor = registerVirtualSensor( new GravitySensor(list, count) );
aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
aSensor = registerVirtualSensor( new OrientationSensor() );
registerVirtualSensor( new CorrectedGyroSensor(list, count) );
registerVirtualSensor( new GyroDriftSensor() );
// 获得 /proc/sys/net/core/wmem_max 中保存的值,设置本地通信用的
// 套接字的缓冲区大小
fopen("/proc/sys/net/core/wmem_max", "r");
fgets(line, sizeof(line), fp)
sscanf(line, "%u", &mSocketBufferSize);
fclose(fp);
/
// 执行 Thread::run() 函数,会创建一个子进程,然后执行到 SensorService::thread
/
// 这里会启动一个线程,在线程内创建一个循环通过 HAL 层,轮询获得底层传感器
// 上报的数据,然后根据硬件传感器的数据,获得虚拟传感器的数据,最后将传感器的
// 数据,通过套接字发给需要传感器值的进程客户端
run("SensorService", PRIORITY_URGENT_DISPLAY);
//
// C++: Threads.cpp (system\core\libutils)
Thread::run(const char* name, int32_t priority, size_t stack)
androidCreateRawThreadEtc(_threadLoop, this, name, priority, stack, &mThread)
pthread_create(&thread, &attr, (android_pthread_entry)entryFunction, userData);
///
// 新进程执行 Thread::_threadLoop() 函数
// C++: Threads.cpp (system\core\libutils)
Thread::_threadLoop(void* user)
result = self->threadLoop();
//
// 【核心函数】
// 调用到了 SensorService::threadLoop() 函数
// C++: SensorService.cpp (frameworks\native\services\sensorservice)
///
SensorService::threadLoop()
do {
//
// 调用 SensorDevice::poll(),在他里面调用 HAL 层的平台
// 封装的上报上来的操作结构体 sensors_data_context_t 结构体
// 用于操作轮询硬件,获得传感上报的数据,传感器数据先判断 input
// 节点是否有传感器事件,如果有,再通过读相应设备节点获得数据,并上报
count = device.poll(buffer, numEventMax);
//
// HAL: Sensors_hwmsen.c (mediatek\hardware\sensor)
data__poll(struct sensors_poll_device_t *dev, sensors_event_t* data, int count)
// 中转到 MTK 自己添加实现的函数中
struct sensors_data_context_t* ctx = (struct sensors_data_context_t*)dev;
return ctx->poll((struct sensors_data_context_t*)dev,data, count);
hwm__poll(struct sensors_data_context_t *dev, sensors_event_t* values, int count)
//
// 如果已经有数据了,则直接上报数据给上层
// 数据是保存在 sensors_data_context_t.sensors[] 数组中的
// 标志有没有数据则是通过 sensors_data_context_t.pendingSensors 中
// 的位来表示
if(dev->pendingSensors)
return pick_sensor(dev, values, count);
while(mask & (num <= count)){
// 如果当前标志位标志有数据,则上报上去
if(dev->pendingSensors & (1<<i))
dev->pendingSensors &= ~(1<<i);
*values = dev->sensors[i];
}
// read the input event
// 读取输入事件,判断是否有事件上报,读取的事件节点为:
// 【dev/input/hwmdata】 文件句柄
// 如果有事件,则判断是否为传感器事件,则读取节点:
// 【/dev/hwmsensor】 文件句柄
// 获得传感器数据。
// 【从这里可以看出底层仅是通过 input 上报有事件发生,而传感器数据
// 则通过设备节点上报的】
nread = read(fd_event, &event, sizeof(event));
// 如果有数据且为 Sensor 类型数据,则通过 ioctl() 获得数据
if(nread == sizeof(event))
if(event.type == EV_REL)
if((event.code == EVENT_TYPE_SENSOR) && (event.value != 0))
// 读取的数据节点为:/dev/hwmsensor 文件句柄
res = ioctl(fd_io, HWM_IO_GET_SENSORS_DATA, &sensors_data);
// 读取传感器数据,放入到 sensors_data_context_t.sensors[] 数组中保存
for(i =0; i < MAX_ANDROID_SENSOR_NUM; i++)
// 置位标志位,表示有数据
dev->pendingSensors |= 1 << i;
dev->sensors[i].sensor = sensors_data.data[i].sensor;
。。。
//
// 如果有数据了,则将数据上报给上层
if(dev->pendingSensors)
return pick_sensor(dev, values, count);
// 这里判断是否有移动传感器,如果有,需要获得休眠锁?
// 保存最近一次各个传感器的值
recordLastValue(buffer, count);
/
// handle virtual sensors
// 处理虚拟传感器,这里会首先调用 SensorFusion 类来加工处理来自硬件传感器上报的数据,
// 然后遍历注册的虚拟传感器,调用具体虚拟传感器的处理函数,从加工过的数据中获得虚拟
// 传感器的值,然后将虚拟传感器的值和硬件传感器上报的数据一起缓冲起来。
if (count && vcount)
// 获得注册的虚拟传感器
const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
getActiveVirtualSensors());
const size_t activeVirtualSensorCount = virtualSensors.size();
// 如果有注册的虚拟传感器,并且 SensorFusion 类使能了,调用 SensorFusion::process()
// 获得处理获得的硬件传感器值来获得虚拟传感器的值,虚拟传感器的值是通过加工硬件传
// 感器值获得的
if (activeVirtualSensorCount)
SensorFusion& fusion(SensorFusion::getInstance());
if (fusion.isEnabled())
// 遍历所有虚拟传感器,通过然后通过 SensorFusion 类处理硬件上报的传感器的值
// 从而接下来可以让具体虚拟传感器类处理,来获得具体虚拟传感器的值
for (size_t i=0 ; i<size_t(count) ; i++)
fusion.process(event[i]);
///
// C++: SensorFusion.cpp (frameworks\native\services\sensorservice)
SensorFusion::process(const sensors_event_t& event)
// 1. 如果是陀螺仪传上来的值
if (event.type == mGyro.getType())
mFusion.handleGyro(vec3_t(event.data), dT);
// 2. 如果是磁传感器传上来的值
else if (event.type == SENSOR_TYPE_MAGNETIC_FIELD)
mFusion.handleMag(mag);
// 3. 如果是加速度传感器传上来的值
else if (event.type == SENSOR_TYPE_ACCELEROMETER)
mFusion.handleAcc(acc);
// 遍历之前注册的所有的虚拟传感器列表,然后调用具体虚拟传感器类的 process() 函数,处理
// SensorFusion 加工过的数据,设置虚拟传感器的值,并和硬件传感器上报的数据一起,添加到
// 缓冲区中
for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++)
for (size_t j=0 ; j<activeVirtualSensorCount ; j++)
SensorInterface* si = virtualSensors.valueAt(j);
if (si->process(&out, event[i]))
buffer[count + k] = out;
// send our events to clients...
// 首先获得需要获得传感器值的客户端的列表,然后遍历列表,调用 SensorEventConnection::sendEvents()
// 将传感器的数据发送给客户端,具体发送通道是通过 BitTube 实现的, 而 BitTube 是基于套接字
// 进行通信的
const SortedVector< wp<SensorEventConnection> > activeConnections(getActiveConnections());
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i<numConnections ; i++)
p<SensorEventConnection> connection(activeConnections[i].promote());
if (connection != 0)
connection->sendEvents(buffer, count, scratch);
// C++: SensorService.cpp (frameworks\native\services\sensorservice)
SensorService::SensorEventConnection::sendEvents(sensors_event_t const* buffer, size_t numEvents, sensors_event_t* scratch)
。。。。
// 这个函数的函数是通过此函数通过 BitTube 类发送数据给客户端
ssize_t size = SensorEventQueue::write(mChannel, reinterpret_cast<ASensorEvent const*>(scratch), count);
///
// C++: SensorEventQueue.cpp (frameworks\native\libs\gui)
SensorEventQueue::write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents)
BitTube::sendObjects(tube, events, numEvents);
//
// C++: BitTube.h (frameworks\native\include\gui)
sendObjects(const sp<BitTube>& tube, T const* events, size_t count)
return sendObjects(tube, events, count, sizeof(T));
ssize_t size = tube->write(vaddr, count*objSize);
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
。。。
// Some sensors need to be auto disabled after the trigger
cleanupAutoDisabledSensor(connection, buffer, count);
// We have read the data, upper layers should hold the wakelock.
// 上报完数据了,释放上面获得的休眠锁
if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
}while (count >= 0 || Thread::exitPending());
}
/
// 3. 调用到 PowerManagerService 电源服务类中,创建一个 SystemSensorManager
// 他会调用 SensorManager 通过 Binder 通信请求 SensorService 返回传感器列表,
// 然后保存在 Java 类的 Sensor 类的列表中
ServerThread thr = new ServerThread();
thr.initAndLoop();
//
// SystemServer.java (frameworks\base\services\java\com\android\server)
ServerThread::initAndLoop()
power.systemReady(twilight, dreamy);
///
// PowerManagerService.java (frameworks\base\services\java\com\android\server\power)
PowerManagerService::systemReady()
/
// 创建 SystemSensorManager 服务, 他会通过 jni 调用 C++ 层的 SensorManager 类,
// 让其通过 Binder 通信请求 SensorService 类服务,返回传感器列表,保存在 Java
// 中的传感器列表 sFullSensorsList 中
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
/
// SystemSensorManager 继承的抽象类 SensorManager,后者定义了一些传感器参数,比如各个传感器对应的标识值等
abstract class SensorManager
SystemSensorManager extends SensorManager
{
// 入口构造函数
SystemSensorManager(Context context, Looper mainLooper)
{
// native 层的类初始化,只是获得了 Sensor.java 类的成员变量的位置 ID, 用于在下面
// 创建一个 Sensor 类 java 对象时,jni 中通过 ID 来设置 Java 对象的成员变量
nativeClassInit();
/
// android_hardware_SensorManager.cpp (frameworks\base\core\jni)【文件名以 Java 包类取的】
nativeClassInit (JNIEnv *_env, jclass _this)
/
// 查找包名为:android.hardware.sensor 的类,Java 包名取名方法:
// 如:
// package android.hardware;
// 则会打包成 android.hardware.[文件名].jar
// 引用时就直接:
// import android.hardware.[文件名]
// 【注意】打包的那个 Java 类文件,必须有个跟文件名同名的类。
// 这里获得 android.hardware.sensor.jar 包中的 sensor 类对象
// Java: Sensor.java (frameworks\base\core\java\android\hardware)
jclass sensorClass = _env->FindClass("android/hardware/Sensor");
//
// 获得 sensor Java 类的成员变量值
SensorOffsets& sensorOffsets = gSensorOffsets;
sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;");
sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;");
sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I");
sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I");
sensorOffsets.type = _env->GetFieldID(sensorClass, "mType", "I");
sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F");
sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F");
sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F");
sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I");
sensorOffsets.fifoReservedEventCount = _env->GetFieldID(sensorClass, "mFifoReservedEventCount", "I");
sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount", "I");
// 初始化传感器列表,首先会创建一个 Sensor 类对象,然后
// 通过 jni 调用 SensorManager 让其通过 Binder 通信请求 SensorService
// 类服务,获得传感器列表,在 jni 层设置 Java 层的 Sensor 类
// 对象
final ArrayList<Sensor> fullList = sFullSensorsList;
do {
//
// 创建一个 Sensor 类对象代表一个传感器
Sensor sensor = new Sensor();
///
// 调用 jni 函数,获得传感器列表,这里实际上是调用 SensorManager 通过
// Binder 通信,请求 SensorService 服务进程进行服务, 首先获得传感器列表
// 然后根据传感器列表中的值,设置 Sensor 类成员变量
// SystemSensorManager 通过 Binder
i = nativeGetNextSensor(sensor, i);
///
// Jni: android_hardware_SensorManager.cpp (frameworks\base\core\jni)
nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next)
//
// 初始化 C++ 层的 SensorManager ,单实例模式,这里
// 会通过 Binder 通信查找上面的注册的服务 SensorService
// 提供服务的,通过 Binder 通信请求服务获得传感器列表,
// 然后给 SensorManager::mSensorList 类成员分配内存,用于
// 保存获得的传感器列表,
SensorManager& mgr(SensorManager::getInstance());
///
// C++:SensorManager.h (frameworks\native\include\gui)
// 【文件夹名称有点奇怪,不过底下确实包含一些 sensor 框架用的文件】
// class SensorManager : public ASensorManager, public Singleton<SensorManager>
// 这里调用的是其父类的单实例初始化函数
// C++: Singleton.h (system\core\include\utils)
Singleton::getInstance()
// TYPE: 是类型模板,这里代表 SensorManager
TYPE* instance = sInstance;
if (instance == 0) {
instance = new TYPE();
/
// C++: SensorManager.cpp (frameworks\native\libs\gui)
SensorManager::SensorManager() : mSensorList(0)
// 类内部变量赋值
assertStateLocked();
SensorManager::assertStateLocked()
/
// 用于获得 sensorserver 的 Binder 代理对象,这个服务是在上面的
// SensorService 中进行服务处理的。
if (mSensorServer == NULL)
// try for one second
const String16 name("sensorservice");
for (int i=0 ; i<4 ; i++)
status_t err = getService(name, &mSensorServer);
/
// IServiceManager.h (frameworks\native\include\binder)
getService(const String16& name, sp<INTERFACE>* outService)
// 获得 C++ 层的 service manager 进程的通信句柄 0
// 用于与 service manager 进程进行 Binder 通信,可以查找服务
// 获得对应的注册服务的句柄
const sp<IServiceManager> sm = defaultServiceManager();
if (sm != NULL) {
// 这是就通过 Binder 通信,查找上面注册的 sensorservice 服务
// 获得其用于通信的 Binder 代理对象,然后转换成上层接口,用于请求 sensorservice
// 服务进程处理服务请求
*outService = interface_cast<INTERFACE>(sm->getService(name));
if ((*outService) != NULL) return NO_ERROR;
}
///
// 这里定义声明一个内部类,应该用于 Binder 死亡监控
class DeathObserver : public IBinder::DeathRecipient
{
SensorManager& mSensorManger;
virtual void binderDied(const wp<IBinder>& who) {
ALOGW("sensorservice died [%p]", who.unsafe_get());
mSensorManger.sensorManagerDied();
}
public:
DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
}
// 应该是注册死亡监控
mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
mSensorServer->asBinder()->linkToDeath(mDeathObserver);
// 首先获得传感器列表,然后在 SensorManager 分配空间,保存传
// 感器列表
mSensors = mSensorServer->getSensorList();
size_t count = mSensors.size();
mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
for (size_t i=0 ; i<count ; i++) {
mSensorList[i] = mSensors.array() + i;
}
sInstance = instance;
}
return *instance;
// 调用 SensorManager::getSensorList() 获得保存在 SensorManager::mSensorList
// 中的传感器列表
size_t count = mgr.getSensorList(&sensorList);
///
// SensorManager.cpp (frameworks\native\libs\gui)
SensorManager::getSensorList(Sensor const* const** list)
// 这个只会在第一次调用的时候调用,通过 Binder 请求
// SensorService 服务,然后给 SensorManager 类分配内存
// 保存传感器列表。
if (assertStateLocked() == NO_ERROR)
*list = mSensorList;
return mSensors.size();
/
// Java: Sensor.java (frameworks\base\core\java\android\hardware)
// 从传感器列表中中取出一项,填充 JAVA 层的 Sensor 类对应成员变量
Sensor const* const list = sensorList[next];
const SensorOffsets& sensorOffsets(gSensorOffsets);
jstring name = env->NewStringUTF(list->getName().string());
jstring vendor = env->NewStringUTF(list->getVendor().string());
env->SetObjectField(sensor, sensorOffsets.name, name);
env->SetObjectField(sensor, sensorOffsets.vendor, vendor);
env->SetIntField(sensor, sensorOffsets.version, list->getVersion());
env->SetIntField(sensor, sensorOffsets.handle, list->getHandle());
env->SetIntField(sensor, sensorOffsets.type, list->getType());
env->SetFloatField(sensor, sensorOffsets.range, list->getMaxValue());
env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
env->SetFloatField(sensor, sensorOffsets.power, list->getPowerUsage());
env->SetIntField(sensor, sensorOffsets.minDelay, list->getMinDelay());
env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
list->getFifoReservedEventCount());
env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount, list->getFifoMaxEventCount());
next++;
/
// 将初始化好的 Sensor 对象放入列表中
if (i>=0) {
//Log.d(TAG, "found sensor: " + sensor.getName() +
// ", handle=" + sensor.getHandle());
fullList.add(sensor);
sHandleToSensor.append(sensor.getHandle(), sensor);
}
} while (i>0);
}
}
【安卓 APP 获取传感器数据流程】:
Sensor app开发一般会包含五步:
1. 获取 sensor manager 对象;
/
// 此函数会创建一个 SystemSensorManager 对象,上面有介绍,他会调用 SensorManger
// 通过 Binder 请求 SensorService 服务返回【传感器列表】, 保存在 SystemSensorManager 中
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
// ContextImpl.java (frameworks\base\core\java\android\app)
getSystemService(String name)
//
// 调用的 apk 启动,创建 contextimpl 对象静态块中注册的服务
// 注册时会添加到一个键值对数组中,调用就是从中查找
///
// registerService(SENSOR_SERVICE, new ServiceFetcher() {
// // 重写了 ServiceFetcher 类的 createService() 函数 ,
// // 这样下面调用 ServiceFetcher::getService() 函数里会
// // 调用重写的函数,创建服务类
// public Object createService(ContextImpl ctx) {
// /
// // 【重点】
// // 创建一个 SystemSensorManager 对象,上面有介绍
// // 他会调用 SensorManager 通过 Binder 通信请求 SensorService
// // 返回【传感器列表】,然后保存在 Java 类的 Sensor 类的列表中
// return new SystemSensorManager(ctx.getOuterContext(),
// ctx.mMainThread.getHandler().getLooper());
// }});
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
ContextImpl::ServiceFetcher::getService(ContextImpl ctx)
// 如果已经创建过服务类,则添加到缓冲区中,方便下次本应用
// 调用时不用重得获得
if (cache.size() == 0)
cache.add(null);
// 尝试从缓冲区中获得,如果已经创建过的话,则会返回
else
service = cache.get(mContextCacheIndex);
// 调用注册时覆写的 createService() 函数,创建服务类
service = createService(ctx);
// 将创建的类对象添加到缓冲区中,方便下次调用
cache.set(mContextCacheIndex, service);
2. 获取 sensor object;
/
// 查找第一步获得的传感器列表,返回对应的传感器的 Sensor 类对象
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
///
// SensorManager 是 SystemSensorManager 的父类,这里调用父类函数
// SensorManager.java (frameworks\base\core\java\android\hardware)
SensorManager::getDefaultSensor(int type)
List<Sensor> l = getSensorList(type);
return l.isEmpty() ? null : l.get(0);
3. 定义 eventListener:
// 定义了 SensorEventListener 类接口,主要主要是重写了onSensorChanged()
// 和 onAccuracyChanged() 方法,当所监听的sensor有数据上报会自动调用
// onSensorChanged() 进行处理。这里的 handleLightSensorEvent() 就是用来
// 处理 light sensor 上报的数据。
private final SensorEventListener mLightSensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (mLightSensorEnabled) {
final long time = SystemClock.uptimeMillis();
final float lux = event.values[0];
handleLightSensorEvent(time, lux);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Not used.
}
};
4. 注册 eventListener;
// 函数会一直调用到 C++ 层,创建一个套接字,接收 SensorService 发
// 过来的传感器数据,然后一层层调用,最后调用注册的监听函数处理传感器数据
mSensorManager.registerListener(mLightSensorListener, mLightSensor, LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
/
// SensorManager.java (frameworks\base\core\java\android\hardware)
registerListener(SensorEventListener listener, Sensor sensor, int rateUs, Handler handler)
{
int delay = getDelay(rateUs);
// 主要调用子类 SystemSensorManager 覆写的函数
return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
//
// SystemSensorManager.java (frameworks\base\core\java\android\hardware)
registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags)
queue = new SensorEventQueue(listener, looper, this);
//父类构造
SensorEventQueue::SensorEventQueue(SensorEventListener listener, Looper looper, SystemSensorManager manager)
super(looper, manager);
///父类
BaseEventQueue::BaseEventQueue(Looper looper, SystemSensorManager manager)
nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch);
/
// Jni:android_hardware_SensorManager.cpp (frameworks\base\core\jni)
nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, jfloatArray scratch)
// 获得系统的 SensorManager 对象,他会通过 Binder 通信请求 SensorService
// 提供服务,通过 SensorService 操作平台定义的 HAL 动态库操作硬件
SensorManager& mgr(SensorManager::getInstance());
// 创建一个 SensorEventQueue 对象,这个主要通过 BitTube 操作套接字,
// 接收 SensorService 发来的传感器数据
sp<SensorEventQueue> queue(mgr.createEventQueue());
// 与 Java 层的 SensorEventQueue 对应
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
// 创建了一个 Receiver 类,这样会导致 Receiver::onFirstRef() 函数被调用
sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQ, scratch);
//
// android_hardware_SensorManager.cpp (frameworks\base\core\jni)
Receiver : public LooperCallback
{
onFirstRef()
{
///
// 监听上面的 SensorEventQueue 中的 BitTube 中的套接字,
// 当有数据时,调用 LooperCallback 子类重载的 handleEvent()
// 函数进行数据分发上报
mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
//
// 调用 Receiver 覆写的函数处理上报来的传感器数据
Receiver::handleEvent(int fd, int events, void* data)
// 当有数据时,通过 jni 方法,调用 Java 类 的函数处理数据
while ((n = q->read(buffer, 16)) > 0)
env->CallVoidMethod(mReceiverObject,
gBaseEventQueueClassInfo.dispatchSensorEvent,
buffer[i].sensor,
mScratch,
buffer[i].vector.status,
buffer[i].timestamp);
//
// Java: SystemSensorManager.java (frameworks\base\core\java\android\hardware)
SensorEventQueue::dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp)
switch (t.sensor.getType())
case Sensor.TYPE_MAGNETIC_FIELD:
case Sensor.TYPE_ORIENTATION:
。。。
//
// 调用 app 覆写的函数
mListener.onAccuracyChanged(t.sensor, t.accuracy);
//
// 调用 app 覆写的函数
mListener.onSensorChanged(t);
}
}
mCloseGuard.open("dispose");
}
5. 卸载 eventListener;
mSensorManager.unregisterListener(mLightSensorListener);
*/