status_tInputManager::start(){ // 启动InputDispatcher的事件分发 status_t result = mDispatcher->start(); if (result) { ALOGE("Could not start InputDispatcher thread due to error %d.", result); return result; } // 启动InputReader result = mReader->start(); if (result) { ALOGE("Could not start InputReader due to error %d.", result);
// Send out a message that the describes the changed input devices. // 如果输入设备发生改变。则发送通知告知输入设备发生改变 if (inputDevicesChanged) { mPolicy->notifyInputDevicesChanged(inputDevices); }
// Flush queued events out to the listener. // This must happen outside of the lock because the listener could potentially call // back into the InputReader's methods, such as getScanCodeState, or become blocked // on another thread similarly waiting to acquire the InputReader lock thereby // resulting in a deadlock. This situation is actually quite plausible because the // listener is actually the input dispatcher, which calls into the window manager, // which occasionally calls into the input reader. // 通过监听回调。发送事件到InputDispatcher mQueuedListener->flush(); }
// Reopen input devices if needed. if (mNeedToReopenDevices) { mNeedToReopenDevices = false;
ALOGI("Reopening all input devices due to a configuration change.");
closeAllDevicesLocked(); mNeedToScanDevices = true; break; // return to the caller before we actually rescan }
// Report any devices that had last been added/removed. for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) { std::unique_ptr<Device> device = std::move(*it); ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.c_str()); event->when = now; event->deviceId = (device->id == mBuiltInKeyboardId) ? ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID : device->id; event->type = DEVICE_REMOVED; event += 1; it = mClosingDevices.erase(it); mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } } // 进行输入事件的设备扫描 if (mNeedToScanDevices) { mNeedToScanDevices = false; // TODO 具体扫描设备的逻辑,我们后来再看 scanDevicesLocked(); mNeedToSendFinishedDeviceScan = true; } // 进行设备的添加 while (!mOpeningDevices.empty()) { /// 从mPendingEventItems读取事件项 std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin()); mOpeningDevices.pop_back(); ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str()); event->when = now; event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; event->type = DEVICE_ADDED; event += 1;
// Try to find a matching video device by comparing device names for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end(); it++) { std::unique_ptr<TouchVideoDevice>& videoDevice = *it; if (tryAddVideoDeviceLocked(*device, videoDevice)) { // videoDevice was transferred to 'device' it = mUnattachedVideoDevices.erase(it); break; } }
auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device)); if (!inserted) { ALOGW("Device id %d exists, replaced.", device->id); } mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } }
// Grab the next input event. bool deviceChanged = false; while (mPendingEventIndex < mPendingEventCount) { conststructepoll_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; }
if (eventItem.data.fd == mWakeReadPipeFd) { if (eventItem.events & EPOLLIN) { ALOGV("awoken after wake()"); awoken = true; char wakeReadBuffer[16]; ssize_t nRead; do { nRead = read(mWakeReadPipeFd, wakeReadBuffer, sizeof(wakeReadBuffer)); } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(wakeReadBuffer)); } else { ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.", eventItem.events); } continue; } /// 根据eventItem.data.fd。获取设备ID所对应的devices Device* device = getDeviceByFdLocked(eventItem.data.fd); if (device == nullptr) { ALOGE("Received unexpected epoll event 0x%08x for unknown fd %d.", eventItem.events, eventItem.data.fd); ALOG_ASSERT(!DEBUG); continue; } if (device->videoDevice && eventItem.data.fd == device->videoDevice->getFd()) { if (eventItem.events & EPOLLIN) { size_t numFrames = device->videoDevice->readAndQueueFrames(); if (numFrames == 0) { ALOGE("Received epoll event for video device %s, but could not read frame", device->videoDevice->getName().c_str()); } } elseif (eventItem.events & EPOLLHUP) { // TODO(b/121395353) - consider adding EPOLLRDHUP ALOGI("Removing video device %s due to epoll hang-up event.", device->videoDevice->getName().c_str()); unregisterVideoDeviceFromEpollLocked(*device->videoDevice); device->videoDevice = nullptr; } else { ALOGW("Received unexpected epoll event 0x%08x for device %s.", eventItem.events, device->videoDevice->getName().c_str()); ALOG_ASSERT(!DEBUG); } continue; } // This must be an input event if (eventItem.events & EPOLLIN) { /// 开始从设备中不断的读取事件,放到readerBuffer中。 int32_t readSize = read(device->fd, readBuffer, sizeof(struct input_event) * capacity); if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { // Device was removed before INotify noticed. ALOGW("could not get event, removed? (fd: %d size: %" PRId32 " bufferSize: %zu capacity: %zu errno: %d)\n", device->fd, readSize, bufferSize, capacity, errno); deviceChanged = true; //设备已被移除则执行关闭操作 closeDeviceLocked(*device); } elseif (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { ALOGW("could not get event (errno=%d)", errno); } } elseif ((readSize % sizeof(struct input_event)) != 0) { ALOGE("could not get event (wrong size: %d)", readSize); } else { int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
size_t count = size_t(readSize) / sizeof(struct input_event); for (size_t i = 0; i < count; i++) { // 获取readBuffer的数据 structinput_event& iev = readBuffer[i]; // 将input_event信息, 封装成RawEvent event->when = processEventTimestamp(iev); event->readTime = systemTime(SYSTEM_TIME_MONOTONIC); event->deviceId = deviceId; event->type = iev.type; event->code = iev.code; event->value = iev.value; event += 1; capacity -= 1; } if (capacity == 0) { // The result buffer is full. Reset the pending event index // so we will try to read the device again on the next iteration. mPendingEventIndex -= 1; break; } } } elseif (eventItem.events & EPOLLHUP) { ALOGI("Removing device %s due to epoll hang-up event.", device->identifier.name.c_str()); deviceChanged = true; closeDeviceLocked(*device); } else { ALOGW("Received unexpected epoll event 0x%08x for device %s.", eventItem.events, device->identifier.name.c_str()); } }
// readNotify() will modify the list of devices so this must be done after // processing all other events to ensure that we read all remaining events // before closing the devices. if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) { mPendingINotify = false; readNotifyLocked(); deviceChanged = true; }
// Report added or removed devices immediately. if (deviceChanged) { continue; }
// Return now if we have collected any events or if we were explicitly awoken. if (event != buffer || awoken) { break; }
// Poll for events. // When a device driver has pending (unread) events, it acquires // a kernel wake lock. Once the last pending event has been read, the device // driver will release the kernel wake lock, but the epoll will hold the wakelock, // since we are using EPOLLWAKEUP. The wakelock is released by the epoll when epoll_wait // is called again for the same fd that produced the event. // Thus the system can only sleep if there are no events pending or // currently being processed. // // The timeout is advisory only. If the device is asleep, it will not wake just to // service the timeout. mPendingEventIndex = 0; // poll之前先释放锁 mLock.unlock(); // release lock before poll // 等待input事件的到来 int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis); // poll之后再次请求锁 mLock.lock(); // reacquire lock after poll
if (pollResult == 0) { // Timed out. mPendingEventCount = 0; break; } //出现错误 if (pollResult < 0) { // An error occurred. // 系统发生错误则休眠1s mPendingEventCount = 0;
// Sleep after errors to avoid locking up the system. // Hopefully the error is transient. if (errno != EINTR) { ALOGW("poll failed (errno=%d)\n", errno); usleep(100000); } } else { // Some events occurred. mPendingEventCount = size_t(pollResult); } }
// All done, return the number of events we read. // 返回所读取的事件个数 return event - buffer; }
/* * A raw event as retrieved from the EventHub. * */ structRawEvent { nsecs_t when; //时间发生的时间点 int32_t deviceId; // 产生事件的设备ID int32_t type; // 事件的类型:DEVICE_ADDED(添加)、DEVICE_REMOVED(删除)、 // FINISHED_DEVICE_SCAN(扫描完成)、type<FIRST_SYNTHETIC_EVENT(其他事件) int32_t code; int32_t value; };
此处事件类型:
DEVICE_ADDED(添加)
DEVICE_REMOVED(删除)
FINISHED_DEVICE_SCAN(扫描完成)
type<FIRST_SYNTHETIC_EVENT(其他事件)
getEvents()已完成转换事件转换工作, 接下来,顺便看看设备扫描过程.
EventHub::scanDevicesLocked
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** * frameworks/native/services/inputflinger/reader/EventHub.cpp **/ voidEventHub::scanDevicesLocked(){ // 此处DEVICE_PATH="/dev/input" status_t result = scanDirLocked(DEVICE_PATH); if (result < 0) { ALOGE("scan dir failed for %s", DEVICE_PATH); } if (isV4lScanningEnabled()) { result = scanVideoDirLocked(VIDEO_DEVICE_PATH); if (result != OK) { ALOGE("scan video dir failed for %s", VIDEO_DEVICE_PATH); } } if (mDevices.indexOfKey(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) < 0) { createVirtualKeyboardLocked(); } }
if (device->getClasses().test(InputDeviceClass::EXTERNAL_STYLUS)) { notifyExternalStylusPresenceChangedLocked(); }
// Sensor input device is noisy, to save power disable it by default. // Input device is classified as SENSOR when any sub device is a SENSOR device, check Eventhub // device class to disable SENSOR sub device only. if (mEventHub->getDeviceClasses(eventHubId).test(InputDeviceClass::SENSOR)) { mEventHub->disableDevice(eventHubId); } }