赞
踩
首先看下sensor的一个整体大概架构图:
4.0中sensor是以一个service 的方式启动的
在base\cmds\sensorservice\main_sensorservice.cpp
- #include <binder/BinderService.h>
- #include <SensorService.h>
-
- using namespace android;
-
- int main(int argc, char** argv) {
- SensorService::publishAndJoinThreadPool();
- return 0;
- }
-
- static void publishAndJoinThreadPool(bool allowIsolated = false) {
- sp<IServiceManager> sm(defaultServiceManager());
- sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
- }

主要是new了一个service并添加到ServiceManager,然后启动线程池
在add service的过程中会调用SensorService的onFirstRef
- void SensorService::onFirstRef()
- {
- ALOGD("nuSensorService starting...");
-
- SensorDevice& dev(SensorDevice::getInstance());//获取sensorSevice实例
-
- if (dev.initCheck() == NO_ERROR) {
- sensor_t const* list;
- ssize_t count = dev.getSensorList(&list);//获取sensorSevice列表
-
- if (count > 0) {
- ssize_t orientationIndex = -1;
- bool hasGyro = false;
- uint32_t virtualSensorsNeeds =
- (1<<SENSOR_TYPE_GRAVITY) |
- (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
- (1<<SENSOR_TYPE_ROTATION_VECTOR);
-
- mLastEventSeen.setCapacity(count);
- for (ssize_t i=0 ; i<count ; i++) {
- registerSensor( new HardwareSensor(list[i]) );//注册各个sensor
- switch (list[i].type) {
- case SENSOR_TYPE_ORIENTATION:
- orientationIndex = i;
- break;
- case SENSOR_TYPE_GYROSCOPE:
- hasGyro = true;
- break;
- case SENSOR_TYPE_GRAVITY:
- case SENSOR_TYPE_LINEAR_ACCELERATION:
- case SENSOR_TYPE_ROTATION_VECTOR:
- virtualSensorsNeeds &= ~(1<<list[i].type);
- break;
- }
- }
-
- // it's safe to instantiate the SensorFusion object here
- // (it wants to be instantiated after h/w sensors have been
- // registered)
- const SensorFusion& fusion(SensorFusion::getInstance());
-
- if (hasGyro) {//如果有陀螺仪传感器,则虚拟的旋转矢量、重力、线性加速度、方向传感器
- // Always instantiate Android's virtual sensors. Since they are
- // instantiated behind sensors from the HAL, they won't
- // interfere with applications, unless they looks specifically
- // for them (by name).
-
- registerVirtualSensor( new RotationVectorSensor() );
- registerVirtualSensor( new GravitySensor(list, count) );
- registerVirtualSensor( new LinearAccelerationSensor(list, count) );
-
- // these are optional
- registerVirtualSensor( new OrientationSensor() );
- registerVirtualSensor( new CorrectedGyroSensor(list, count) );
-
- // virtual debugging sensors...
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.sensors", value, "0");
- if (atoi(value)) {
- registerVirtualSensor( new GyroDriftSensor() );
- }
- }
-
- // build the sensor list returned to users
- mUserSensorList = mSensorList;
- if (hasGyro &&
- (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {
- // if we have the fancy sensor fusion, and it's not provided by the
- // HAL, use our own (fused) orientation sensor by removing the
- // HAL supplied one form the user list.
- /*if (orientationIndex >= 0) {
- mUserSensorList.removeItemsAt(orientationIndex);
- }*/
- }
-
- run("SensorService", PRIORITY_URGENT_DISPLAY);//启动线程
- mInitCheck = NO_ERROR;
- }
- }
- }

onFirstRef主要做了下面三件事:
1构造SensorDevice
- SensorDevice::SensorDevice()
- : mSensorDevice(0),
- mSensorModule(0)
- {
- status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
- (hw_module_t const**)&mSensorModule);//获取sensor模块
-
- ALOGE_IF(err, "couldn't load %s module (%s)",
- SENSORS_HARDWARE_MODULE_ID, strerror(-err));
-
- if (mSensorModule) {
- err = sensors_open(&mSensorModule->common, &mSensorDevice);//打开sensor设备
-
- ALOGE_IF(err, "couldn't open device for module %s (%s)",
- SENSORS_HARDWARE_MODULE_ID, strerror(-err));
-
- if (mSensorDevice) {
- sensor_t const* list;
- ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);//获取sensor列表
- mActivationCount.setCapacity(count);
- Info model;
- for (size_t i=0 ; i<size_t(count) ; i++) {
- mActivationCount.add(list[i].handle, model);
- mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
- }
- }
- }
- }

2、获取到sensor之后 ,就是注册sensor,开始注册的都是HardwareSensor类型的sensor
- void 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(), event);
- }
注册sensor比较简单,主要是添加到几个list和map中。
还有一个registerVirtualSensor,注册虚拟的sensor
- void SensorService::registerVirtualSensor(SensorInterface* s)
- {
- registerSensor(s);
- mVirtualSensorList.add( s );
- }
调用registerSensor并添加到mVirtualSensorList链表。
3、run启动threadLoop线程
- bool SensorService::threadLoop()
- {
- ALOGD("nuSensorService thread starting...");
-
- const size_t numEventMax = 16;
- const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
- sensors_event_t buffer[minBufferSize];
- sensors_event_t scratch[minBufferSize];
- SensorDevice& device(SensorDevice::getInstance());
- const size_t vcount = mVirtualSensorList.size();
-
- ssize_t count;
- do {
- count = device.poll(buffer, numEventMax);//查看sensor上是否有数据到来
- if (count<0) {
- ALOGE("sensor poll failed (%s)", strerror(-count));
- break;
- }
-
- recordLastValue(buffer, count);//记录每个sensor的最后一次事件
-
- // handle virtual sensors
- if (count && vcount) {
- sensors_event_t const * const event = buffer;
- const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
- getActiveVirtualSensors());//获取虚拟的sensor
- const size_t activeVirtualSensorCount = virtualSensors.size();
- if (activeVirtualSensorCount) {
- size_t k = 0;
- SensorFusion& fusion(SensorFusion::getInstance());
- if (fusion.isEnabled()) {//融合传感器使能,则调用它的process对根据event数据对SensorFusion里面的一些变量进行设置,
- //后面调用其相应的sensor process的时候会用到
- for (size_t i=0 ; i<size_t(count) ; i++) {
- fusion.process(event[i]);
- }
- }
- for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
- for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
- if (count + k >= minBufferSize) {
- ALOGE("buffer too small to hold all events: "
- "count=%u, k=%u, size=%u",
- count, k, minBufferSize);
- break;
- }
- sensors_event_t out;
- SensorInterface* si = virtualSensors.valueAt(j);
- if (si->process(&out, event[i])) {//调用模拟sensor的process处理,输出一个event,添加到buffer
- buffer[count + k] = out;
- k++;
- }
- }
- }
- if (k) {
- // record the last synthesized values
- recordLastValue(&buffer[count], k);//重新记录每个sensor的最后一次事件
- count += k;
- // sort the buffer by time-stamps
- sortEventBuffer(buffer, count);
- }
- }
- }
-
- // send our events to clients...
- const SortedVector< wp<SensorEventConnection> > activeConnections(
- getActiveConnections());
- size_t numConnections = activeConnections.size();
- for (size_t i=0 ; i<numConnections ; i++) {
- sp<SensorEventConnection> connection(
- activeConnections[i].promote());
- if (connection != 0) {
- connection->sendEvents(buffer, count, scratch);//把收到的数据传上去
- }
- }
- } while (count >= 0 || Thread::exitPending());
-
- ALOGW("Exiting SensorService::threadLoop => aborting...");
- abort();
- return false;
- }

代码中大概注释了各个比较关键地方的函数意义,主要是收到数据后,查看下如果有虚拟的sensor:
1、 如果使能了SensorFusion,调用它的process对数据进行处理(这里应该是每种类型sensor一次poll最多只会上报一次),处理过程中会设置相应的一些成员变量值
2、 两个for循环,对所有的event,针对所有的已使能的virtual sensor调用它的process,这里面会用到一些前面第一步设置的一些值,根据输入的event输出一个event并添加到buffer.
数据处理完成后,获取所有活动的连接,并把数据发给它。看一下sendEvents
- status_t SensorService::SensorEventConnection::sendEvents(
- sensors_event_t const* buffer, size_t numEvents,
- sensors_event_t* scratch)
- {
- // filter out events not for this connection
- size_t count = 0;
- if (scratch) {
- Mutex::Autolock _l(mConnectionLock);
- size_t i=0;
- while (i<numEvents) {
- const int32_t curr = buffer[i].sensor;
- if (mSensorInfo.indexOf(curr) >= 0) {//检查在该连接里面是否存在这个sensor,存在则添加到scratch里面
- do {
- scratch[count++] = buffer[i++];
- } while ((i<numEvents) && (buffer[i].sensor == curr));
- } else {
- i++;
- }
- }
- } else {
- scratch = const_cast<sensors_event_t *>(buffer);
- count = numEvents;
- }
-
- // NOTE: ASensorEvent and sensors_event_t are the same type
- ssize_t size = SensorEventQueue::write(mChannel,//将数据写到一个通道
- reinterpret_cast<ASensorEvent const*>(scratch), count);
- if (size == -EAGAIN) {
- // the destination doesn't accept events anymore, it's probably
- // full. For now, we just drop the events on the floor.
- //ALOGW("dropping %d events on the floor", count);
- return size;
- }
-
- return size < 0 ? status_t(size) : status_t(NO_ERROR);
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。