android sensor 框架分析---服务端

来源:互联网 发布:linux怎么用vi创建文件 编辑:程序博客网 时间:2024/05/01 09:18

前言:

相对于其他模块, Sensor的API还是非常简洁的.对Sensor的开发也很简单。Android 6.0 系统支持的传感器

多达26种,加速度传感器 (accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、

陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和

距离传感器(proximity)等等, Sensor.java 中有相关定义。

 

服务端的代码路径如下,

frameworks\native\services\sensorservice

HAL对应的代码如下,

hardware\libhardware\include\hardware\ sensor.h

hardware\qcom\sensors

其他代码对应路径

frameworks\native\libs\gui

1,概述

Sensor架构图如下,


主要包括2个进程,服务端和客户端。

Sensor的整体逻辑非常清晰,一个控制流,一个数据流。

 

2 sensor服务端

开始一直以为sensor服务进程向很多守护进程一样通过init.rc配置文件启动,后来才发现是通过systemserver进程启动,

并且运行于systemserver进程中,就像systemserver中的各种服务一样,只是通过C/C++实现而已。

启动流程图如下,


SystemServer对应的为com_android_server_SystemServer.cpp,其实, SystemServer中只有一个native方法,

就是startSensorService,说了这么多, com_android_server_SystemServer.cpp就是为了启动sensor服务才有的。

sensorInit方法如下,

void* sensorInit(void *arg) {    ALOGI("System server: starting sensor init.\n");    // Start the sensor service    SensorService::instantiate();//new SensorService对象    ALOGI("System server: sensor init done.\n");    return NULL;}

SensorService的onFirstRef方法中,主要逻辑如下,

1,获取SensorDevice对象,

SensorDevice& dev(SensorDevice::getInstance());

2, 获取Sensor列表

ssize_t count = dev.getSensorList(&list);

3,sensor注册

for (ssize_t i=0 ; i<count ; i++) {     registerSensor( new HardwareSensor(list[i]) );

首先为每一个sensor注册一个对应的HardwareSensor。

然后对有些sensor,注册特殊的sensor,例如,

aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );

4,启动服务

mAckReceiver = new SensorEventAckReceiver(this);mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);run("SensorService", PRIORITY_URGENT_DISPLAY);

2.1初始化

流程图如下,

SensorDevice继承于Singleton,所以整个android系统中,仅有一个SensorDevice对象,

class SensorDevice : public Singleton<SensorDevice> {friend class Singleton<SensorDevice>;    sensors_poll_device_1_t* mSensorDevice;    struct sensors_module_t* mSensorModule;

SensorDevice的构造方法主要逻辑如下,

1,加载sensor模块so库

status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,            (hw_module_t const**)&mSensorModule);

并且mSensorModule变量就指向sensor模块so库。通过该变量可以调用sensor模块so库中的方法。

但是mSensorDevice又是什么呢?sensors_poll_device_1_t对象,

sensors_poll_device_1_tsensor.h中定义,只是一个有些方法的结构体。

 

2, 调用sensor.h的sensors_open_1方法打开设备

err = sensors_open_1(&mSensorModule->common, &mSensorDevice);

3,获取so库的Sensor列表

ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);            mActivationCount.setCapacity(count);

4,激活sensor

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);}

2.1.1 sensor模块打开

sensor.h中的sensors_open_1方法如下,

static inline int sensors_open_1(const struct hw_module_t* module,        sensors_poll_device_1_t** device) {    return module->methods->open(module,            SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);}

直接调用sensor模块的open方法,

sensors.cpp对应的open方法为open_sensors

static struct hw_module_methods_t sensors_module_methods = {open: open_sensors};

在open_sensors方法中主要进行一些初始化的操作。

1,构造NativeSensorManager对象,

NativeSensorManager& sm(NativeSensorManager::getInstance());

2,构造sensors_poll_context_t,并且初始化,

sensors_poll_context_t *dev = new sensors_poll_context_t();•••dev->device.common.module   = const_cast<hw_module_t*>(module);dev->device.common.close= poll__close;dev->device.activate= poll__activate;dev->device.setDelay= poll__setDelay;dev->device.poll= poll__poll;dev->device.calibrate= poll_calibrate;

sensors_poll_context_t是sensors.cpp内部的一个结构体,类似于一个类,里面也有各种方法。

这样,sensorservice也可以通过mSensorDevice调用HAL中的方法。

 

在sensors_poll_context_t的构造方法中,对每个event创建从driver中读取数据的节点。

for (i = 0; i < number; i++) {context = sm.getInfoByHandle(slist[i].handle);mPollFds[i].fd = (context == NULL) ? -1 : context->data_fd;mPollFds[i].events = POLLIN;mPollFds[i].revents = 0;}ALOGI("The avaliable sensor handle number is %d",i);int wakeFds[2];int result = pipe(wakeFds);ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);mWritePipeFd = wakeFds[1];mPollFds[number].fd = wakeFds[0];mPollFds[number].events = POLLIN;mPollFds[number].revents = 0;

2.1.2 模块的Sensor列表

上层调用模块的get_sensors_list方法其实就是调用module__get_sensors_list方法,

get_sensors_list: sensors__get_sensors_list,

该方法直接调用NativeSensorManager的getSensorList方法,

static int sensors__get_sensors_list(struct sensors_module_t*, struct sensor_t const** list){NativeSensorManager& sm(NativeSensorManager::getInstance());return sm.getSensorList(list);}

NativeSensorManager的getSensorList方法如下,

int NativeSensorManager::getSensorList(const sensor_t **list) {*list = mSensorCount ? sensor_list:NULL;return mSensorCount;}

直接返回NativeSensorManager的mSensorCount变量。

mSensorCount变量的值是在NativeSensorManager的构造方法中调用getDataInfo方法赋值的。

sensor_list 变量保存各种sensor。

getDataInfo方法会为每个sensor保存对应的SensorContext结构体,

NativeSensorManager.h的SensorContext结构体定义如下,

struct SensorContext {char   name[SYSFS_MAXLEN]; // name of the sensorchar   vendor[SYSFS_MAXLEN]; // vendor of the sensorchar   enable_path[PATH_MAX]; // the control path of this sensorchar   data_path[PATH_MAX]; // the data path to get sensor eventsstruct sensor_t *sensor; // point to the sensor_t structure in the sensor listSensorBase     *driver; // point to the sensor driver instanceint data_fd; // the file descriptor of the data device nodeint enable; // indicate if the sensor is enabledbool is_virtual; // indicate if this is a virtual sensorint64_t delay_ns; // the poll delay setting of this sensorint64_t latency_ns; // the max report latency of this sensorstruct listnode dep_list; // the background sensor type needed for this sensorstruct listnode listener; // the head of listeners of this sensor};

SensorContext保存着对应sensor驱动的各种信息,读取sensor的值时会使用该结构体的data_fd变量。

2.1.3 激活Sensor

HAL 中的activate流程图如下,


poll__activate直接调用sensors_poll_context_t的activate方法,

static int poll__activate(struct sensors_poll_device_t *dev,int handle, int enabled) {sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;return ctx->activate(handle, enabled);}

sensors_poll_context_t的activate方法首先调用NativeSensorManager.c的activate方法打开对应的驱动设备文件,

然后往里面写入值1.

int sensors_poll_context_t::activate(int handle, int enabled) {int err = -1;NativeSensorManager& sm(NativeSensorManager::getInstance());Mutex::Autolock _l(mLock);err = sm.activate(handle, enabled);if (enabled && !err) {const char wakeMessage(WAKE_MESSAGE);int result = write(mWritePipeFd, &wakeMessage, 1);ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));}return err;}

SensorBase.cpp的enable方法是一个虚方法,由不同的独立的sensor去实现。

例如, Accelerometer.cpp的enable方法实现如下,

strlcpy(&input_sysfs_path[input_sysfs_path_len], SYSFS_ENABLE, SYSFS_MAXLEN);fd = open(input_sysfs_path, O_RDWR);if (fd >= 0) {char buf[2];int err;buf[1] = 0;if (flags) {buf[0] = '1';mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME;sysclk_sync_offset = getClkOffset();} else {buf[0] = '0';}err = write(fd, buf, sizeof(buf));close(fd);mEnabled = flags;return 0;}

实际上就是获取对应加速度sensor的驱动节点路径,然后打开该路径,往里面写入2个字符。

这样,从HAL到驱动这条路就打通了。

2.2 获取sensor列表

SensorService.cpp的onFirstRef中获取sensor列表的代码如下,

sensor_t const* list;ssize_t count = dev.getSensorList(&list);

将获取的sensor保存在list中。

SensorDevice.cpp的getSensorList方法如下,

ssize_t SensorDevice::getSensorList(sensor_t const** list) {    if (!mSensorModule) return NO_INIT;    ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);    return count;}

上节中已经说明了,调用模块的get_sensors_list方法将获取的sensor保存在list中。

2.3 sensor注册

registerSensor方法如下,

Sensor SensorService::registerSensor(SensorInterface* s){    sensors_event_t event;    memset(&event, 0, sizeof(event));    const Sensor sensor(s->getSensor());    // add to the sensor list (returned to clients)    mSensorList.add(sensor);    // add to our handle->SensorInterface mapping    mSensorMap.add(sensor.getHandle(), s);    // create an entry in the mLastEventSeen array    mLastEventSeen.add(sensor.getHandle(), NULL);    return sensor;}

实际上就是将从sensor模块获取的sensor 对象以及相关信息分别放在mSensorList, mSensorMap等数据结构中。

registerVirtualSensor也是调用registerSensor方法完成的。

Sensor SensorService::registerVirtualSensor(SensorInterface* s){    Sensor sensor = registerSensor(s);    mVirtualSensorList.add( s );    return sensor;}

2.4 启动服务

启动服务的代码如下,

mAckReceiver = new SensorEventAckReceiver(this);mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);run("SensorService", PRIORITY_URGENT_DISPLAY);

直接调用threadLoop方法,

do {    ssize_t count = device.poll(mSensorEventBuffer, numEventMax);

调用SensorDevice的poll方法读取sensor数据并且保存在mSensorEventBuffer中。具体的获取数据的过程下面再详细论述。

小结:

1,sensor服务端首先打通HAL和driver之间的通信。

2,激活各种sensor。

3,开启子线程读取sensor数据。

原创粉丝点击