> 文档中心 > android Input专题- Q/R/S 10/11/12 InputReader源码分析1

android Input专题- Q/R/S 10/11/12 InputReader源码分析1

新课程优惠获取请加入千里马老师qq群:422901085
上节课已经讲到了InputReaderThread和InputDispatchThread已经启动了,调用了对应的run方法,这里会导致对应的threadLoop方法执行:

native/services/inputflinger/InputReaderBase.cpp

bool InputReaderThread::threadLoop() {    mReader->loopOnce();    return true;}

这里会调用到mReader的loopOnce方法,这个方法将是非常关键的方法:

void InputReader::loopOnce() {    int32_t oldGeneration;    int32_t timeoutMillis;    bool inputDevicesChanged = false;    std::vector<InputDeviceInfo> inputDevices; //省略部分    //mEventHub获取数据    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);    { // acquire lock AutoMutex _l(mLock); mReaderIsAliveCondition.broadcast(); if (count) {     processEventsLocked(mEventBuffer, count); }//省略部分 if (oldGeneration != mGeneration) {     inputDevicesChanged = true;     getInputDevicesLocked(inputDevices); }    } // release lock    // Send out a message that the describes the changed input devices.    if (inputDevicesChanged) { mPolicy->notifyInputDevicesChanged(inputDevices);    }//省略部分注释    mQueuedListener->flush();}

1. mEventHub中获取getEvents数据:

这里第一步就是调用了EventHub的getEvents方法:

size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {    ALOG_ASSERT(bufferSize >= 1);    AutoMutex _l(mLock);    struct input_event readBuffer[bufferSize];    RawEvent* event = buffer;    size_t capacity = bufferSize;    bool awoken = false;    for (;;) {//省略部分 if (mNeedToScanDevices) {     mNeedToScanDevices = false;     scanDevicesLocked();     mNeedToSendFinishedDeviceScan = true; }//第一次一般遍历mOpeningDevices这个列表进行各个device获取变成DEVICE_ADDED while (mOpeningDevices != nullptr) {     Device* device = mOpeningDevices;     ALOGV("Reporting device opened: id=%d, name=%s\n",   device->id, device->path.c_str());     mOpeningDevices = device->next;     event->when = now;     event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;     event->type = DEVICE_ADDED;     event += 1;     mNeedToSendFinishedDeviceScan = true;     if (--capacity == 0) {  break;     } }//第一次扫描完毕消息 if (mNeedToSendFinishedDeviceScan) {     mNeedToSendFinishedDeviceScan = false;     event->when = now;     event->type = FINISHED_DEVICE_SCAN;     event += 1;     if (--capacity == 0) {  break;     } } // Grab the next input event. bool deviceChanged = false; //第一次扫描时候没有消息,指导后面有触摸消息才会进入这里,这里是会由下面epoll监听消息触发 while (mPendingEventIndex < mPendingEventCount) {     const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];     if (eventItem.data.fd == mINotifyFd) {  if (eventItem.events & EPOLLIN) {      mPendingINotify = true;  } else {      ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);  }  continue;     }//省略部分     Device* device = getDeviceByFdLocked(eventItem.data.fd);    //省略部分     // This must be an input event     if (eventItem.events & EPOLLIN) {      //读取对应数据  int32_t readSize = read(device->fd, readBuffer,   sizeof(struct input_event) * capacity);  //省略部分  } else {      int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;//获取真实读取到的inputevent数据真实个数      size_t count = size_t(readSize) / sizeof(struct input_event);      //构造出对应的event      for (size_t i = 0; i < count; i++) {   struct input_event& iev = readBuffer[i];   event->when = processEventTimestamp(iev);   event->deviceId = deviceId;   event->type = iev.type;   event->code = iev.code;   event->value = iev.value;   event += 1;   capacity -= 1;      }   //省略部分  }     }     //省略部分 }//省略部分 if (event != buffer || awoken) {//第一次扫描就会进入这里进行返回     break; }//省略部分//这里epoll在等待消息产生,产生消息EventItem都会放到mPendingEventItems中 int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis); if (pollResult < 0) {   //省略部分 } else { //这里对mPendingEventCount进行赋值真正有多少个事件产生     // Some events occurred.     mPendingEventCount = size_t(pollResult); }    }    // All done, return the number of events we read.    return event - buffer;}

这个方法相对还是比较复杂的,主要关心做了两部分的业务:
1、获取设备device各个信息,及监听设备变化
2、监听各个设备产生数据,并转换变成元数据RawEvent
最后会把一个个的RawEvent放入到传递进来的event这个链表里面即InputReader的

 size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);

中的mEventBuffer,所以后面就是用这个mEventBuffer进行对应数据读取等,当mEventBuffer数据有了之后那应该到了InputReader loopOnce的下一步了。

2. 处理数据processEventsLocked

void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {    for (const RawEvent* rawEvent = rawEvents; count;) { int32_t type = rawEvent->type; size_t batchSize = 1; //首先判断type类型,如果已经开始触摸,那么这里type值肯定会小于FIRST_SYNTHETIC_EVENT if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {     int32_t deviceId = rawEvent->deviceId;     while (batchSize < count) {  //判断是否有其他消息,或者设备都换了,存在则退出这次数据的系列  if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT   || rawEvent[batchSize].deviceId != deviceId) {      break;  }  //一个触摸事件是由若干个RawEvent组成,比如触摸滑动,他有abs,syn等类型  batchSize += 1;     }     //把一个系列事件完成后进行processEvents进行处理     processEventsForDeviceLocked(deviceId, rawEvent, batchSize); } else { //以下几种都是对设备相关移除添加进行操作的     switch (rawEvent->type) {     case EventHubInterface::DEVICE_ADDED:  addDeviceLocked(rawEvent->when, rawEvent->deviceId);  break;     case EventHubInterface::DEVICE_REMOVED:  removeDeviceLocked(rawEvent->when, rawEvent->deviceId);  break;     case EventHubInterface::FINISHED_DEVICE_SCAN:  handleConfigurationChangedLocked(rawEvent->when);  break;     default:  ALOG_ASSERT(false); // can't happen  break;     } } count -= batchSize; rawEvent += batchSize;    }}

这里注释中对大部分已经进行讲解,最重要其实是processEventsForDeviceLocked