android sensor 框架分析---服务端
2017-07-06 22:04
246 查看
前言:
相对于其他模块, 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
主要包括2个进程,服务端和客户端。
Sensor的整体逻辑非常清晰,一个控制流,一个数据流。
并且运行于systemserver进程中,就像systemserver中的各种服务一样,只是通过C/C++实现而已。
启动流程图如下,
SystemServer对应的为com_android_server_SystemServer.cpp,其实, SystemServer中只有一个native方法,
就是startSensorService,说了这么多, com_android_server_SystemServer.cpp就是为了启动sensor服务才有的。
sensorInit方法如下,
SensorService的onFirstRef方法中,主要逻辑如下,
1,获取SensorDevice对象,
2, 获取Sensor列表
3,sensor注册
首先为每一个sensor注册一个对应的HardwareSensor。
然后对有些sensor,注册特殊的sensor,例如,
4,启动服务
SensorDevice继承于Singleton,所以整个android系统中,仅有一个SensorDevice对象,
SensorDevice的构造方法主要逻辑如下,
1,加载sensor模块so库
并且mSensorModule变量就指向sensor模块so库。通过该变量可以调用sensor模块so库中的方法。
但是mSensorDevice又是什么呢?是sensors_poll_device_1_t对象,
sensors_poll_device_1_t在sensor.h中定义,只是一个有些方法的结构体。
2, 调用sensor.h的sensors_open_1方法打开设备
3,获取so库的Sensor列表
4,激活sensor
直接调用sensor模块的open方法,
sensors.cpp对应的open方法为open_sensors
在open_sensors方法中主要进行一些初始化的操作。
1,构造NativeSensorManager对象,
2,构造sensors_poll_context_t,并且初始化,
sensors_poll_context_t是sensors.cpp内部的一个结构体,类似于一个类,里面也有各种方法。
这样,sensorservice也可以通过mSensorDevice调用HAL中的方法。
在sensors_poll_context_t的构造方法中,对每个event创建从driver中读取数据的节点。
该方法直接调用NativeSensorManager的getSensorList方法,
NativeSensorManager的getSensorList方法如下,
直接返回NativeSensorManager的mSensorCount变量。
mSensorCount变量的值是在NativeSensorManager的构造方法中调用getDataInfo方法赋值的。
sensor_list 变量保存各种sensor。
getDataInfo方法会为每个sensor保存对应的SensorContext结构体,
NativeSensorManager.h的SensorContext结构体定义如下,
SensorContext保存着对应sensor驱动的各种信息,读取sensor的值时会使用该结构体的data_fd变量。
poll__activate直接调用sensors_poll_context_t的activate方法,
sensors_poll_context_t的activate方法首先调用NativeSensorManager.c的activate方法打开对应的驱动设备文件,
然后往里面写入值1.
SensorBase.cpp的enable方法是一个虚方法,由不同的独立的sensor去实现。
例如, Accelerometer.cpp的enable方法实现如下,
实际上就是获取对应加速度sensor的驱动节点路径,然后打开该路径,往里面写入2个字符。
这样,从HAL到驱动这条路就打通了。
将获取的sensor保存在list中。
SensorDevice.cpp的getSensorList方法如下,
上节中已经说明了,调用模块的get_sensors_list方法将获取的sensor保存在list中。
实际上就是将从sensor模块获取的sensor 对象以及相关信息分别放在mSensorList, mSensorMap等数据结构中。
registerVirtualSensor也是调用registerSensor方法完成的。
直接调用threadLoop方法,
调用SensorDevice的poll方法读取sensor数据并且保存在mSensorEventBuffer中。具体的获取数据的过程下面再详细论述。
小结:
1,sensor服务端首先打通HAL和driver之间的通信。
2,激活各种sensor。
3,开启子线程读取sensor数据。
相对于其他模块, 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_t在sensor.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 sensor char vendor[SYSFS_MAXLEN]; // vendor of the sensor char enable_path[PATH_MAX]; // the control path of this sensor char data_path[PATH_MAX]; // the data path to get sensor events struct sensor_t *sensor; // point to the sensor_t structure in the sensor list SensorBase *driver; // point to the sensor driver instance int data_fd; // the file descriptor of the data device node int enable; // indicate if the sensor is enabled bool is_virtual; // indicate if this is a virtual sensor int64_t delay_ns; // the poll delay setting of this sensor int64_t latency_ns; // the max report latency of this sensor struct listnode dep_list; // the background sensor type needed for this sensor struct 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数据。
相关文章推荐
- android sensor 框架分析---客户端和服务端的连接
- 深入浅出 - Android系统移植与平台开发(十三) - Sensor HAL框架分析之三
- 深入浅出 - Android系统移植与平台开发(十四) - Sensor HAL框架分析之四
- 深入浅出 - Android系统移植与平台开发(十二) - Sensor HAL框架分析之二
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
- 深入浅出 - Android系统移植与平台开发(十二) - Sensor HAL框架分析之二
- 深入浅出 - Android系统移植与平台开发(十四) - Sensor HAL框架分析之四
- 深入浅出 - Android系统移植与平台开发(十二) - Sensor HAL框架分析之二
- 深入浅出 - Android系统移植与平台开发(十四) - Sensor HAL框架分析之四
- 深入浅出 - Android系统移植与平台开发(十三) - Sensor HAL框架分析之三
- 深入浅出 - Android系统移植与平台开发(十四) - Sensor HAL框架分析之四
- 深入浅出 - Android系统移植与平台开发(十二) - Sensor HAL框架分析之二
- 深入浅出 - Android系统移植与平台开发(十二) - Sensor HAL框架分析之二
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
- 深入浅出 - Android系统移植与平台开发(十二) - Sensor HAL框架分析之二
- 深入浅出 - Android系统移植与平台开发(十三) - Sensor HAL框架分析之三
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
- 深入浅出 - Android系统移植与平台开发(十四) - Sensor HAL框架分析之四
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一