文章参考:http://gityuan.com/2016/12/11/input-reader/

概述

介绍IMS服务的启动过程会创建两个native线程,分别是InputReader,InputDispatcher. 接下来从InputReader线程的执行过程从threadLoop为起点开始分析。

InputManager::start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
status_t InputManager::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);

mDispatcher->stop();
return result;
}

return OK;
}

InputDispatcher::start

1
2
3
4
5
6
7
8
9
status_t InputDispatcher::start() {
if (mThread) {
return ALREADY_EXISTS;
}
// 启动一个InputDispatcher线程
mThread = std::make_unique<InputThread>(
"InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
return OK;
}

InputReader::start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 代码位于:framework/native/services/inputflinger/reader/InputReader.cpp
**/
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
// 启动一个InputReader线程
// 循环调用loopOnce()。整个过程是不断循环的地调用InputReader的loopOnce()方法
// make_unique的智能指针需要学习
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}

InputManager的start方法的主要功能是启动两个线程:

  • 启动线程“InputReader”
  • 启动线程”InputDispatcher“

那么,下面我们看一下InputReader的线程的业务逻辑。InputReader的线程中,回会调用到loopOnce()方法。

InputReader::loopOnce()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* 代码位于:framework/native/services/inputflinger/reader/InputReader.cpp
**/
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
// 启动一个InputReader线程
// 循环调用loopOnce()。整个过程是不断循环的地调用InputReader的loopOnce()方法
// make_unique的智能指针需要学习
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}

status_t InputReader::stop() {
if (mThread && mThread->isCallingThread()) {
ALOGE("InputReader cannot be stopped from its own thread!");
return INVALID_OPERATION;
}
mThread.reset();
return OK;
}
/**
* 代码位于:framework/native/services/inputflinger/reader/InputReader.cpp
**/
void InputReader::loopOnce() {
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
std::vector<InputDeviceInfo> inputDevices;
{ // acquire lock
AutoMutex _l(mLock);

oldGeneration = mGeneration;
timeoutMillis = -1;

uint32_t changes = mConfigurationChangesToRefresh;
if (changes) {
mConfigurationChangesToRefresh = 0;
timeoutMillis = 0;
refreshConfigurationLocked(changes);
} else if (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
}
} // release lock
// 从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 (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (now >= mNextTimeout) {
#if DEBUG_RAW_EVENTS
ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
#endif
mNextTimeout = LLONG_MAX;
timeoutExpiredLocked(now);
}
}

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);
}

// 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();
}

我们可以看到。InputReader会通过会不断地循环调用loopOnce()。源源不断的从EventHub中获取输入事件。下面,我们就来看一下比较重要的EventHub是怎么获取输入事件的。

EventHub->getEvents

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/**
* frameworks/native/services/inputflinger/reader/EventHub.cpp
**/
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
// 确认缓存数据区空间大于1
ALOG_ASSERT(bufferSize >= 1);
// 加锁处理
std::scoped_lock _l(mLock);

struct input_event readBuffer[bufferSize];
// 定义原始事件
RawEvent* event = buffer;
// 传入的缓冲区的大小,一般为256
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.
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;
}
}

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;
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;
}

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());
}
} else if (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);
} else if (readSize < 0) {
if (errno != EAGAIN && errno != EINTR) {
ALOGW("could not get event (errno=%d)", errno);
}
} else if ((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的数据
struct input_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;
}
}
} else if (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;
}

EventHub采用INotify + epoll机制实现监听目录/dev/input下的设备节点,经过EventHub将input_event结构体 + deviceId 转换成RawEvent结构体

所以这里我们可以看到EventHub进行消息的监听也是使用INotify + epoll机制。有点类似于Handler机制。

RawEvent

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
* A raw event as retrieved from the EventHub.
*
*/
struct RawEvent {
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
**/
void EventHub::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();
}
}

EventHub::scanDirLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
status_t EventHub::scanDirLocked(const std::string& dirname) {
for (const auto& entry : std::filesystem::directory_iterator(dirname)) {
openDeviceLocked(entry.path());
}
return 0;
}

status_t EventHub::scanDirLocked(const char* dirname) {
char devname[PATH_MAX];
char* filename;
DIR* dir;
struct dirent* de;
dir = opendir(dirname);
if (dir == nullptr) return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
// 读取/dev/input/目录下所有的设备节点
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);
//打开相应的设备节点
openDeviceLocked(devname);
}
closedir(dir);
return 0;
}

EventHub::openDirLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
status_t EventHub::openDeviceLocked(const char *devicePath) {
char buffer[80];
//打开设备文件
int fd = open(devicePath, O_RDWR | O_CLOEXEC);
InputDeviceIdentifier identifier;
//获取设备名
if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1){
} else {
buffer[sizeof(buffer) - 1] = '\0';
identifier.name.setTo(buffer);
}

identifier.bus = inputId.bustype;
identifier.product = inputId.product;
identifier.vendor = inputId.vendor;
identifier.version = inputId.version;

//获取设备物理地址
if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
} else {
buffer[sizeof(buffer) - 1] = '\0';
identifier.location.setTo(buffer);
}

//获取设备唯一ID
if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
} else {
buffer[sizeof(buffer) - 1] = '\0';
identifier.uniqueId.setTo(buffer);
}
//将identifier信息填充到fd
assignDescriptorLocked(identifier);
//设置fd为非阻塞方式
fcntl(fd, F_SETFL, O_NONBLOCK);

//获取设备ID,分配设备对象内存
int32_t deviceId = mNextDeviceId++;
Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
...

//注册epoll
struct epoll_event eventItem;
memset(&eventItem, 0, sizeof(eventItem));
eventItem.events = EPOLLIN;
if (mUsingEpollWakeup) {
eventItem.events |= EPOLLWAKEUP;
}
eventItem.data.u32 = deviceId;
if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
delete device; //添加失败则删除该设备
return -1;
}
...
//【见小节2.2.4】
addDeviceLocked(device);
}

EventHub::addDeviceLocked

1
2
3
4
5
6
7
8
/**
* 代码位于:frameworks/native/services/inputflinger/reader/EventHub.cpp
**/
void EventHub::addDeviceLocked(std::unique_ptr<Device> device) {
// 添加到mDevices队列
reportDeviceAddedForStatisticsLocked(device->identifier, device->classes);
mOpeningDevices.push_back(std::move(device));
}

介绍了EventHub从设备节点获取事件的流程,当收到事件后接下里便开始处理事件。

InputReader::processEventsLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* 代码位于:frameworks/native/services/inputflinger/reader/InputReader.cpp
**/
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
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;
}
// 同一设备的事件打包处理
batchSize += 1;
}
if (DEBUG_RAW_EVENTS) {
ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
}
// 数据事件的处理
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;
}
}

事件处理总共有下几类类型:

  • DEVICE_ADDED(设备增加), [见小节3.2]
  • DEVICE_REMOVED(设备移除)
  • FINISHED_DEVICE_SCAN(设备扫描完成)
  • 数据事件[见小节3.4]

先来说说DEVICE_ADDED设备增加的过程。

InputReader::addDeviceLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* 代码位于:frameworks/native/services/inputflinger/reader/InputReader.cpp
*/
void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
// 已添加的相同设备则不再添加
if (mDevices.find(eventHubId) != mDevices.end()) {
ALOGW("Ignoring spurious device added event for eventHubId %d.", eventHubId);
return;
}

InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
// 进行设备的创建
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
device->configure(when, &mConfig, 0);
device->reset(when);
//
if (device->isIgnored()) {
ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
"(ignored non-input device)",
device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str());
} else {
ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s',sources=%s",
device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str(),
inputEventSourceToString(device->getSources()).c_str());
}
// 添加设备到mDevices
mDevices.emplace(eventHubId, device);
// Add device to device to EventHub ids map.
const auto mapIt = mDeviceToEventHubIdsMap.find(device);
if (mapIt == mDeviceToEventHubIdsMap.end()) {
std::vector<int32_t> ids = {eventHubId};
mDeviceToEventHubIdsMap.emplace(device, ids);
} else {
mapIt->second.push_back(eventHubId);
}
bumpGenerationLocked();

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);
}
}

InputReader::addDeviceLocked

归纳总结

Android 系统是由事件驱动的,而 input 是最常见的事件之一,用户的点击、滑动、长按等操作,都属于 input 事件驱动,其中的核心就是 InputReaderInputDispatcherInputReaderInputDispatcher 是跑在 SystemServer进程中的两个 native 循环线程,负责读取和分发 Input 事件。整个处理过程大致流程如下:

InputReader整个过程涉及多次事件封装转换,其主要工作核心是以下三大步骤:

  • 首先,system_server进程中的native线程的InputReader利用linux的epolle机制监听并且从屏幕驱动读取上报的事件。通过EventHub(监听目录/dev/input)读取事件放入mEventBuffer,而mEventBuffer是一个大小为256的数组, 再将事件input_event转换为RawEvent;
  • processEventsLocked: 对事件进行加工, 转换RawEvent -> NotifyKeyArgs(NotifyArgs)
  • QueuedListener->flush:将事件发送到InputDispatcher线程, 转换NotifyKeyArgs -> KeyEntry(EventEntry)

InputReader线程不断循环地执行InputReader.loopOnce(), 每次处理完生成的是EventEntry(比如KeyEntry, MotionEntry), 接下来的工作就交给InputDispatcher线程。

InputReader线程不断循环地执行InputReader.loopOnce(), 每次处理完生成的是EventEntry(比如KeyEntry, MotionEntry), 接下来的工作就交给InputDispatcher线程。