Android SensorService启动流程(二)
来源:互联网 发布:网络变压器内部线路图 编辑:程序博客网 时间:2024/05/20 16:42
上一篇我们讲完了SensorService::onFirstRef()的第一步,实例化一个SensorDevice(),本篇我们继续往下分析~~~
4.2)获取芯片商在Hal层初始化好的SensorList,并返回sensor的数目。
ssize_t count = dev.getSensorList(&list);
4.3)registerSensor( new HardwareSensor(list[i]))
for (ssize_t i=0 ; i<count ; i++) { registerSensor( new HardwareSensor(list[i]) ); switch (list[i].type) { case SENSOR_TYPE_ORIENTATION: orientationIndex = i; break; case SENSOR_TYPE_GYROSCOPE: case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: hasGyro = true; break; case SENSOR_TYPE_GRAVITY: case SENSOR_TYPE_LINEAR_ACCELERATION: case SENSOR_TYPE_ROTATION_VECTOR: virtualSensorsNeeds &= ~(1<<list[i].type); break; } }
在for循环中注册这些sensor。根据硬件sensor_t创建HardwareSensor,然后加入mSensorList(Sensor) 和mSensorMap(HardwareSensor)中。
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(), event); return sensor;}4.4)mUserSensorList = mSensorList;将mSensorList传感器列表赋值给mUserSensorList,mSensorList是由registerSensor初始化的,mUserSensorList是要提交给Java框架层的传感器列表。
4.5)Gyro通常包含其他几种Sensor的数据,诸如下述代码所说,如果hal层没有这几种sensor,那么上层可以通过Gyro数据去虚拟出来这几类sensor。
if (hasGyro) { Sensor aSensor; // Add Android virtual sensors if they're not already // available in the HAL aSensor = registerVirtualSensor( new RotationVectorSensor() ); if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { mUserSensorList.add(aSensor); } aSensor = registerVirtualSensor( new GravitySensor(list, count) ); if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) { mUserSensorList.add(aSensor); } aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) ); if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) { mUserSensorList.add(aSensor); } aSensor = registerVirtualSensor( new OrientationSensor() ); if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { // if we are doing our own rotation-vector, also add // the orientation sensor and remove the HAL provided one. mUserSensorList.replaceAt(aSensor, orientationIndex); } // virtual debugging sensors are not added to mUserSensorList registerVirtualSensor( new CorrectedGyroSensor(list, count) ); registerVirtualSensor( new GyroDriftSensor() ); }4.6)启动sensorService线程,sensorService父类有一个Thread线程,调用run方法会创建线程并调用threadLoop方法。
run("SensorService", PRIORITY_URGENT_DISPLAY);sensorService的threadLoop方法:
bool SensorService::threadLoop(){ ALOGD("nuSensorService thread starting..."); // each virtual sensor could generate an event per "real" event, that's why we need // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. // in practice, this is too aggressive, but guaranteed to be enough. const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size()); SensorDevice& device(SensorDevice::getInstance()); const size_t vcount = mVirtualSensorList.size(); const int halVersion = device.getHalDeviceVersion(); do { ssize_t count = device.poll(mSensorEventBuffer, numEventMax); if (count < 0) { ALOGE("sensor poll failed (%s)", strerror(-count)); break; } // Reset sensors_event_t.flags to zero for all events in the buffer. for (int i = 0; i < count; i++) { mSensorEventBuffer[i].flags = 0; } // Make a copy of the connection vector as some connections may be removed during the // course of this loop (especially when one-shot sensor events are present in the // sensor_event buffer). Promote all connections to StrongPointers before the lock is // acquired. If the destructor of the sp gets called when the lock is acquired, it may // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for // cleanup. So copy all the strongPointers to a vector before the lock is acquired. SortedVector< sp<SensorEventConnection> > activeConnections; populateActiveConnections(&activeConnections); Mutex::Autolock _l(mLock); // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and // releasing the wakelock. bool bufferHasWakeUpEvent = false; for (int i = 0; i < count; i++) { if (isWakeUpSensorEvent(mSensorEventBuffer[i])) { bufferHasWakeUpEvent = true; break; } } if (bufferHasWakeUpEvent && !mWakeLockAcquired) { setWakeLockAcquiredLocked(true); } recordLastValueLocked(mSensorEventBuffer, count); // handle virtual sensors if (count && vcount) { sensors_event_t const * const event = mSensorEventBuffer; const size_t activeVirtualSensorCount = mActiveVirtualSensors.size(); if (activeVirtualSensorCount) { size_t k = 0; SensorFusion& fusion(SensorFusion::getInstance()); if (fusion.isEnabled()) { 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=%zd, k=%zu, size=%zu", count, k, minBufferSize); break; } sensors_event_t out; SensorInterface* si = mActiveVirtualSensors.valueAt(j); if (si->process(&out, event[i])) { mSensorEventBuffer[count + k] = out; k++; } } } if (k) { // record the last synthesized values recordLastValueLocked(&mSensorEventBuffer[count], k); count += k; // sort the buffer by time-stamps sortEventBuffer(mSensorEventBuffer, count); } } } // handle backward compatibility for RotationVector sensor if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { for (int i = 0; i < count; i++) { if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { // All the 4 components of the quaternion should be available // No heading accuracy. Set it to -1 mSensorEventBuffer[i].data[4] = -1; } } } // Map flush_complete_events in the buffer to SensorEventConnections which called // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the // SensorEventConnection mapped to the corresponding flush_complete_event in // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise). for (int i = 0; i < count; ++i) { mMapFlushEventsToConnections[i] = NULL; if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) { const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor; SensorRecord* rec = mActiveSensors.valueFor(sensor_handle); if (rec != NULL) { mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection(); rec->removeFirstPendingFlushConnection(); } } } // Send our events to clients. Check the state of wake lock for each client and release the // lock if none of the clients need it. bool needsWakeLock = false; size_t numConnections = activeConnections.size(); for (size_t i=0 ; i < numConnections; ++i) { if (activeConnections[i] != 0) { activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, mMapFlushEventsToConnections); needsWakeLock |= activeConnections[i]->needsWakeLock(); // If the connection has one-shot sensors, it may be cleaned up after first trigger. // Early check for one-shot sensors. if (activeConnections[i]->hasOneShotSensors()) { cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, count); } } } if (mWakeLockAcquired && !needsWakeLock) { setWakeLockAcquiredLocked(false); } } while (!Thread::exitPending()); ALOGW("Exiting SensorService::threadLoop => aborting..."); abort(); return false;}4.6.1)该方法一开始是先调用 ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
dev->device.poll = poll__poll;
实则是调用到了hal层的poll__poll方法:
static int poll__poll(struct sensors_poll_device_t *dev, sensors_event_t* data, int count) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->pollEvents(data, count);}
继续pollEvents方法:
int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count){ int nbEvents = 0; int n = 0; //ALOGE("pollEvents count =%d",count ); do { // see if we have some leftover from the last poll() for (int i=0 ; count && i<numSensorDrivers ; i++) { SensorBase* const sensor(mSensors[i]); if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) { int nb = sensor->readEvents(data, count); if (nb < count) { // no more data for this sensor mPollFds[i].revents = 0; } //if(nb < 0||nb > count) // ALOGE("pollEvents count error nb:%d, count:%d, nbEvents:%d", nb, count, nbEvents);//for sensor NE debug count -= nb; nbEvents += nb; data += nb; //if(nb < 0||nb > count) // ALOGE("pollEvents count error nb:%d, count:%d, nbEvents:%d", nb, count, nbEvents);//for sensor NE debug } } if (count) { // we still have some room, so try to see if we can get // some events immediately or just wait if we don't have // anything to return n = poll(mPollFds, numFds, nbEvents ? 0 : -1); if (n<0) { ALOGE("poll() failed (%s)", strerror(errno)); return -errno; } if (mPollFds[wake].revents & POLLIN) { char msg; int result = read(mPollFds[wake].fd, &msg, 1); ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); mPollFds[wake].revents = 0; } } // if we have events and space, go read them } while (n && count); return nbEvents;}首先调用sensor->readEvents(data,count)方法,此方法为各个sensor读取event事件的方法,以AccelerationSensor为例做分析:
int AccelerationSensor::readEvents(sensors_event_t* data, int count){ //ALOGE("fwq read Event 1\r\n"); if (count < 1) return -EINVAL; ssize_t n = mInputReader.fill(mdata_fd); if (n < 0) return n; int numEventReceived = 0; input_event const* event; while (count && mInputReader.readEvent(&event)) { int type = event->type; //ALOGE("fwq1....\r\n"); if (type == EV_ABS) { processEvent(event->code, event->value); //ALOGE("fwq2....\r\n"); } else if (type == EV_SYN) { //ALOGE("fwq3....\r\n"); int64_t time = timevalToNano(event->time); mPendingEvent.timestamp = time; if (mEnabled) { //ALOGE("fwq4....\r\n"); if (mPendingEvent.timestamp >= mEnabledTime) { //ALOGE("fwq5....\r\n"); *data++ = mPendingEvent; numEventReceived++; } count--; } } else if (type != EV_ABS) { ALOGE("AccelerationSensor: unknown event (type=%d, code=%d)", type, event->code); } mInputReader.next(); } //ALOGE("fwq read Event 2\r\n"); return numEventReceived;}首先调用fill方法,把相应节点的input事件读入缓冲的buffer,然后在while循环中mInputReader.readEvent(&event)读取当前指针所指向的事件,mInputReader.next();将指针指向环形队列下一条事件来读取下一条事件。
fill方法:
ssize_t InputEventCircularReader::fill(int fd) { size_t numEventsRead = 0; if (mFreeSpace) { const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); if (nread<0 || nread % sizeof(input_event)) { // we got a partial event!! return nread<0 ? -errno : -EINVAL; } numEventsRead = nread / sizeof(input_event); if (numEventsRead) { mHead += numEventsRead; mFreeSpace -= numEventsRead; if (mHead > mBufferEnd) { size_t s = mHead - mBufferEnd; memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); mHead = mBuffer + s; } } } return numEventsRead;}从传入的文件节点中读取事件,存入mBuffer。
ssize_t InputEventCircularReader::readEvent(input_event const** events){ *events = mCurr; ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; return available ? 1 : 0;}void InputEventCircularReader::next(){ mCurr++; mFreeSpace++; if (mCurr >= mBufferEnd) { mCurr = mBuffer; }}
每new一个特殊类型的Sensor,都会调用类似SensorBase(NULL, "m_acc_input"),这是Acc传感器中的相关调用,而SensorBase方法会调用openInput:
SensorBase::SensorBase( const char* dev_name, const char* data_name) : dev_name(dev_name), data_name(data_name), dev_fd(-1), data_fd(-1){ data_fd = openInput(data_name);}我们再来看openInput的实现:
int SensorBase::openInput(const char* inputName) { int fd = -1; const char *dirname = "/dev/input"; char devname[PATH_MAX]; char *filename; DIR *dir; struct dirent *de; dir = opendir(dirname); if(dir == NULL) return -1; strcpy(devname, dirname); filename = devname + strlen(devname); *filename++ = '/'; while((de = readdir(dir))) { if(de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) continue; strcpy(filename, de->d_name); fd = open(devname, O_RDONLY); if (fd>=0) { char name[80]; if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { name[0] = '\0'; } if (!strcmp(name, inputName)) { break; } else { close(fd); fd = -1; } } } closedir(dir); ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName); return fd;}openInput()实际上是打开各个sensor对应于/dev/input/event*文件节点最后返回的是sensor对应文件节点的fd,也就是上面fill函数的参数data_fd,在adb shell,然后getevent命令也是获取位于/dev/input/下所有的event事件。之后回到SensorService的threadLoop中,在获取完数据之后就要通过 activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,mMapFlushEventsToConnections);调用write函数将数据放到一个管道里面,sensor APP将数据取走。
ssize_t size = SensorEventQueue::write(mChannel, reinterpret_cast<ASensorEvent const*>(scratch), count);
所有的故~~~事~~~~,总要有一个结果,此致,结尾。。。。
0 0
- Android SensorService启动流程(二)
- Android SensorService启动流程(一)
- android-5.0 sensor工作原理—sensorservice的启动(二)
- Android SensorService源码分析(二)
- (OK) android-5.0 sensor工作原理—sensorservice的启动(二)
- Android sensorservice
- Android启动流程二
- Android之init启动流程(二)
- android应用程序的启动流程(二)
- android启动流程分析(二)
- Android sensor架构(二)SystemSensorManager以及JNI、sensorService(and5.1)
- Android sensor架构(二)SystemSensorManager以及JNI、sensorService(and5.1)
- Android sensor架构(二)SystemSensorManager以及JNI、sensorService(and5.1)
- SensorService流程分析
- Android启动流程(二):android服务启动
- android-5.0 sensor工作原理—sensorservice的启动(一)
- SensorService启动分析
- android SensorService lightSensor
- 线性回归(linear-regression)预测算法基本概念&C++实现
- python几个内建函数
- hibernate5.2.2入门实践
- 第4周项目3-单链表应用(3)
- nexus-3.0.0-03-win64搭建Maven nexus私服
- Android SensorService启动流程(二)
- 如何将mysql安装到U盘
- 二叉树排序在Java代码的简单实现
- iOS开发 适配iOS10以及Xcode8
- HTML DOM树
- 十款值得推荐的php开发工具
- 单例模式(Singletion)
- 大数据学习笔记-------------------(5)
- 第四周项目3-单链表的应用(3)