InputReader
input输入系统中,我们使用InputReader来读取底层节点中的数据,并对数据进行处理加工
首先InputReader是运行在线程InputReader上的,我们从他的start方法开始
native/services/inputflinger/reader/InputReader.cpp
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}
开启一个名为InputReader的线程,主要执行loopOnce这个方法,继续看loopOnce方法,首先通过mEventHub->getEvents获取底层节点数据,再通过processEventsLocked方法解析这些数据。
根据之前介绍的EventHub的逻辑,第一次调用getEvents其实是获取不到输入事件的,这次只是将底层节点加入到epoll的监听上了,当epoll监听到节点可读,将会触发mEventHub->wake,这样就会再次执行这个loopOnce方法第二次调用getEvents来读取相应数据
void InputReader::loopOnce() {
//通过EventHub读取底层节点数据
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
//processEventsLocked处理数据
if (count) {
processEventsLocked(mEventBuffer, count);
}
//刷新QueuedListener
mQueuedListener->flush();
}
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
int32_t deviceId = rawEvent->deviceId;
//processEventsForDeviceLocked处理一般输入事件
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;
}
}
}
}
//调用createDeviceLocked生成一个新的InputDevice,加入mDevices中,eventHubId为key
void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
mDevices.emplace(eventHubId, device);
}
enum {
// Sent when a device is added.
DEVICE_ADDED = 0x10000000,
// Sent when a device is removed.
DEVICE_REMOVED = 0x20000000,
// Sent when all added/removed devices from the most recent scan have been reported.
// This event is always sent at least once.
FINISHED_DEVICE_SCAN = 0x30000000,
FIRST_SYNTHETIC_EVENT = DEVICE_ADDED,
};
}
loopOnce从底层读取到数据,这些数据包含多种事件类型,processEventsLocked方法根据事件类型进行处理
- DEVICE_ADDED 新增输入设备,根据读取到的属性生成InputDevice加入到mDevices中
- DEVICE_REMOVED 移除输入设备,根据deviceId,移除mDevices中的对应InputDevice
- FINISHED_DEVICE_SCAN 标志扫描事件结束
- type < FIRST_SYNTHETIC_EVENT 由输入设备产生的事件,我们一般意义上指代的输入事件
InputDevice对象是和底层的节点相对应的,用于描述底层输入设备的相关信息,每个Device对象在生成时,内部都会保存一些InputMapper对象用于处理各自设备节点的输入事件,不同的InputMapper都有各自处理事件的逻辑,比如处理键盘事件的KeyboardInputMapper,处理触摸事件的MultiTouchInputMapper
std::shared_ptr<InputDevice> InputReader::createDeviceLocked({
std::shared_ptr<InputDevice> device;
device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(), identifier);}
device->addEventHubDevice(eventHubId);
return device;
}
void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
std::vector<std::unique_ptr<InputMapper>> mappers;
// 根据InputDevice的不同属性添加相应的InputMapper到mappers中,这里就加了一个KeyboardInputMapper和MultiTouchInputMapper
if (keyboardSource != 0) {
mappers.push_back(
std::make_unique<KeyboardInputMapper>(*contextPtr, keyboardSource, keyboardType));
}
if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
} else if (classes & INPUT_DEVICE_CLASS_TOUCH) { mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
}
对于一般输入事件,调用processEventsForDeviceLocked方法处理,就是调用这些InputDevice去处理原始事件数据的
void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
size_t count) {
//通过key查找到对应的InputDevice
auto deviceIt = mDevices.find(eventHubId);
std::shared_ptr<InputDevice>& device = deviceIt->second;
//调用InputDevice的process方法处理原始事件数据
device->process(rawEvents, count);
}
void InputDevice::process(const RawEvent* rawEvents,, size_t count) {
...
//遍历rawEvents,通过mappers中的InputMapper处理
for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
...
for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
mapper.process(rawEvent);
});
}
}
}
void KeyboardInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_KEY: {
int32_t scanCode = rawEvent->code;
//判断是否是键盘事件
if (isKeyboardOrGamepadKey(scanCode)) {
processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
}
break;
}
}
}
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode, int32_t usageCode) {
...
//封装NotifyKeyArgs对象,传递出去
NotifyKeyArgs args(getContext()->getNextId(), when, getDeviceId(), mSource, getDisplayId(),
policyFlags, down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
getListener()->notifyKey(&args);
}
NotifyKeyArgs继承自NotifyArgs。
processEventsForDeviceLocked处理Key事件逻辑
- 通过eventHubId从mDevices中查找到对应的InputDevice
- InputDevice.process->KeyboardInputMapper.process->KeyboardInputMapper.processKey->getListener()->notifyKey
- mQueuedListener->flush()将事件传递出去
void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
//将封装好的NotifyKeyArgs放入到mArgsQueue
mArgsQueue.push_back(new NotifyKeyArgs(*args));
}
void QueuedInputListener::flush() {
//取出所有NotifyArgs对象,执行notify方法
size_t count = mArgsQueue.size();
for (size_t i = 0; i < count; i++) {
NotifyArgs* args = mArgsQueue[i];
args->notify(mInnerListener);
delete args;
}
mArgsQueue.clear();
}
执行了mArgsQueue.push操作将NotifyKeyArgs放进队列中。在flush时取出来执行NotifyArgs的notify方法,notify代码如下
void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
listener->notifyKey(this);
}
这里调用传递进来的listener执行notifyKey方法,而InputDispatcher继承了InputListenerInterface,这里最终调用了的其实就是InputDispatcher中的notifyKey函数。
此时事件已经成功从InputReader传递到InputDispatcher了
由上面我们分析可知,只有被InputMapper识别的事件才能传输到InputDispatcher中,即一般事件的流程图如下:
Touch触摸事件逻辑类似,调用MultiTouchInputMapper,封装NotifyMotionArgs对象进行处理的,所有的事件最终通过QueuedInputListener.flush触发发送到InputDispatcher的notifyMotion函数