目录
前言
前面其实也有提到EventHub的构造函数,里面就是创建epoll实例,然后把一些事件触发的文件描述符加入到epoll里面统一管理。
- 监控/dev/input/目录的iNotify文件mINotifyFd
- 接收Kernel驱动事件(/dev/input/eventX)的文件描述符
- 用来唤醒InputReader线程的管道读文件
EventHub是服务于InputReader线程的,前面在InputRead的构造函数里面有创建EventHub的实例。
InputReader线程
InputReader线程主要就是查看threadLoop接口中代码的实现,threadLoop返回值是true代表的是会不断的循环,返回false的话就不会继续在调用threadLoop函数。
bool InputReaderThread::threadLoop() {
mReader->loopOnce();
return true;
}
不停的调用InputReader的loopOnce函数
loopOnce函数
InputReader.cpp
void InputReader::loopOnce() {
...
{
AutoMutex _l(mLock);
uint32_t changes = mConfigurationChangesToRefresh;
if (changes) {
timeoutMillis = 0;
...
} else if (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
}
}
//从EventHub读取事件,其中EVENT_BUFFER_SIZE = 256
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
if (inputDevicesChanged) { //输入设备发生改变
mPolicy->notifyInputDevicesChanged(inputDevices);
}
//发送事件到nputDispatcher
mQueuedListener->flush();
}
两个关键的地方,从注释可以很明确的看出来,首先是获取到底层的input事件,处理事件,然后发送到InputDispatcher线程
- mEventHub->getEvents
- processEventsLocked(mEventBuffer, count)
- mQueuedListener->flush
EventHub->getEvents
EventHub.cpp
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
AutoMutex _l(mLock); //加锁
struct input_event readBuffer[bufferSize];
RawEvent* event = buffer; //原始事件
size_t capacity = bufferSize; //容量大小为256
bool awoken = false;
for (;;) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
...
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
scanDevicesLocked(); //扫描设备
mNeedToSendFinishedDeviceScan = true;
}
while (mOpeningDevices != NULL) {
Device* device = mOpeningDevices;
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;
}
}
...
bool deviceChanged = false;
while (mPendingEventIndex < mPendingEventCount) {
//从mPendingEventItems读