android-5.0 sensor工作原理—sensorservice的启动(二)
来源:互联网 发布:淘宝客高佣 编辑:程序博客网 时间:2024/05/21 13:57
3.2 dev.getSensorList(&list);获取厂商在HAL层初始化的sensor_t类型结构体的sSensorList,并返回sensor device的数目。
3.3 registerSensor( new HardwareSensor(list[i]) );在for循环中注册这些sensor。根据硬件sensor_t创建HardwareSensor,然后加入mSensorList(Sensor) 和mSensorMap(HardwareSensor)中,后面的switch是判断是否存在电子罗盘,GYRO以及GYRO对应所需要的对应的一些所对应的一些虚拟sensor
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; }
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;}
3.4 mUserSensorList = mSensorList;将mSensorList传感器列表赋值给mUserSensorList,mSensorList是由registerSensor初始化的,mUserSensorList是要提交给Java框架层的传感器列表。
3.5 如果有GYRO就注册这样一些上面提到的三种虚拟sensor来实现GYRO的功能,此处我是这么理解的。
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() ); }
3.6 run("SensorService", PRIORITY_URGENT_DISPLAY);启动sensorService线程,sensorService父类有一个Thread线程,调用run方法会创建线程并调用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(); SensorEventAckReceiver sender(this); sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); 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; { Mutex::Autolock _l(mLock); for (size_t i=0 ; i < mActiveConnections.size(); ++i) { sp<SensorEventConnection> connection(mActiveConnections[i].promote()); if (connection != 0) { activeConnections.add(connection); } } } 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) { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); mWakeLockAcquired = 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) { release_wake_lock(WAKE_LOCK_NAME); mWakeLockAcquired = false; } } while (!Thread::exitPending()); ALOGW("Exiting SensorService::threadLoop => aborting..."); abort(); return false;}
3.6.1 首先是调用device.poll(mSensorEventBuffer, numEventMax);来获取sensor数据。这里调用的是前面open_sensors函数初始化的 dev->device.poll = 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;int polltime = -1;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 sensormPollFds[i].revents = 0;}#ifndef ORI_NULLif ((0 != nb) && (acc == i)) {((OriSensor *) (mSensors[ori]))-> setAccel(&data[nb - 1]);}#endifcount -= nb;nbEvents += nb;data += nb;}}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 returndo {n = poll(mPollFds, numFds, nbEvents ? 0 : polltime);} while (n < 0 && errno == EINTR);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对应的读取sensor event的方法。readEvents()函数先调用fill函数将所要读的sensor的input_event事件读取到一个环形缓冲区,然后在while循环中mInputReader.readEvent(&event)读取当前指针所指向的事件,mInputReader.next();将指针指向环形队列下一条事件来读取下一条事件。
int STKLightSensor::readEvents(sensors_event_t* data, int count){ if (count < 1) return -EINVAL; if (mHasPendingEvent) { mHasPendingEvent = false; mPendingEvent.timestamp = getTimestamp(); *data = mPendingEvent; return mEnabled ? 1 : 0; } ssize_t n = mInputReader.fill(data_fd); if (n < 0) return n; int numEventReceived = 0; input_event const* event; while (count && mInputReader.readEvent(&event)) { int type = event->type; if (type == EV_ABS) { if (event->code == ABS_MISC) { mPendingEvent.light = (float)event->value; } } else if (type == EV_SYN) { mPendingEvent.timestamp = timevalToNano(event->time); if (mEnabled) { *data++ = mPendingEvent; count--; numEventReceived++; } } else { ALOGE("STKLightSensor: unknown event (type=%d, code=%d)", type, event->code); } mInputReader.next(); } return numEventReceived;}
fill函数的参数data_fd是在前面sensors_poll_context_t()函数中的new STKLightSensor();进行初始化的,其主要是SensorBase(NULL, "lightsensor-level"),这里主要是openInput动作来获得一个fd从而从这个fd的文件中获取sensor event。
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;}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;}}
SensorBase::SensorBase( const char* dev_name, const char* data_name) : dev_name(dev_name), data_name(data_name), dev_fd(-1), data_fd(-1){ if (data_name) { data_fd = openInput(data_name); }}
openInput()实际上是打开各个sensor对应于/dev/input/event*文件节点最后返回的是sensor对应文件节点的fd,也就是上面fill函数的参数data_fd,在adb shell,然后getevent命令也是获取位于/dev/input/下所有的event事件。
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)) { strcpy(input_name, filename); break; } else { close(fd); fd = -1; } } } closedir(dir); ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName); return fd;
在获取完数据之后就要通过 activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,mMapFlushEventsToConnections);调用write函数将数据放到一个管道里面,sensor APP将数据取走。
ssize_t size = SensorEventQueue::write(mChannel, reinterpret_cast<ASensorEvent const*>(scratch), count);
至此sensorservice的启动就讲完了,下一篇将从sensor APP端讲述sensor APP的工作流程。
- android-5.0 sensor工作原理—sensorservice的启动(二)
- android-5.0 sensor工作原理—sensorservice的启动(一)
- (OK) android-5.0 sensor工作原理—sensorservice的启动(二)
- (OK) android-5.0 sensor工作原理—sensorservice的启动(一)
- android-5.0 sensor工作原理—Sensor APP数据的获取
- Android SensorService启动流程(二)
- Android sensor架构(二)SystemSensorManager以及JNI、sensorService(and5.1)
- Android sensor架构(二)SystemSensorManager以及JNI、sensorService(and5.1)
- Android sensor架构(二)SystemSensorManager以及JNI、sensorService(and5.1)
- 图像sensor的工作原理
- Android SensorService源码分析(二)
- SensorService 初始化4(类图篇sensor注册监听原理)
- SensorService 初始化5(类图篇sensor注册监听原理)
- Android 浅谈Sensor工作流程(二)
- Android SensorService启动流程(一)
- Android sensorservice
- Android——View的工作原理(二)
- android Sensor相关工作
- 计算机网络之——虚拟专用网VPN和网络地址转换NAT
- java中urlrewrite使用文档(简单demo)
- oc中protocol、category和继承的区别
- java中的final关键字所起的作用
- Java面试题:如何对HashMap按键值排序
- android-5.0 sensor工作原理—sensorservice的启动(二)
- ID有多条记录导致用于副表 连接查询时会出现重复
- Windows下挂载Ubuntu网络文件系统NFS
- Android ImageView控件中的MaxWidth,MaxHeight不起作用
- nuget发布
- 触发器同步数据针对表,这样的主要是针对个别表同步技术使用
- Struct和Class的区别
- 欢迎使用CSDN-markdown编辑器
- EISCONN的故事