input key and Touch
Android 输入事件的一般流程
EventHub
- EventHub 事件枢纽,可以多路复用监听/dev/input/目录 文件的变化;
- getEvents步骤:
(1) . 开始循环执行,直至已经收集了任何事件,或者我们被显式地唤醒,立即返回。
a. Reopen input devices if needed.
b. Report any devices that had last been added/removed.
c. scan devices if Needed, add devices / remove devices.
d. product adding devices event if needed.
e. product finishing scan devices event if needed.
f. start grab the next input event really. //多路复用监听fd,
g. readNotify()将修改设备列表,因此必须在处理所有其他事件之后完成,以确保在关闭设备之前读取所有剩余事件。
h. 若上一个动作执行,Report added or removed devices immediately.
i. 如果我们已经收集了任何事件,或者我们被显式地唤醒,立即返回。
多路复用监听事件补充:
/*
man help:
EPOLLIN 连接到达;有数据来临;
The associated file is available for read(2) operations.
EPOLLOUT 有数据要写
The associated file is available for write(2) operations.
EPOLLRDHUP 表示读关闭。
如果有EPOLLRDHUP,检测它就可以直到是对方关闭;否则就用上面方法。
EPOLLHUP 表示读写都关闭。
*/
if (eventItem.events & EPOLLIN) {
...
} else if (eventItem.events & EPOLLHUP) {
ALOGI("Removing device %s due to epoll hang-up event.",
device->identifier.name.string());
deviceChanged = true;
closeDeviceLocked(device);
} else {
ALOGW("Received unexpected epoll event 0x%08x for device %s.",
eventItem.events, device->identifier.name.string());
}
事件枢纽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 (;;) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
// 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.
while (mClosingDevices) {
Device* device = mClosingDevices;
ALOGV("Reporting device closed: id=%d, name=%s\n",
device->id, device->path.string());
mClosingDevices = device->next;
event->when = now;
event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;
event->type = DEVICE_REMOVED;
event += 1;
delete device;
mNeedToSendFinishedDeviceScan = true;
if (--capacity == 0) {
break;
}
}
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
scanDevicesLocked();
mNeedToSendFinishedDeviceScan = true;
}
while (mOpeningDevices != NULL) {
Device* device = mOpeningDevices;
ALOGV("Reporting device opened: id=%d, name=%s\n",
device->id, device->path.string());
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;
}