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