前言
上一篇文章我们具体分析了InputManagerService的构造方法和start方法,知道IMS的start方法经过层层调用,最终会触发Navite层InputDispatcher的start方法和InputReader的start方法。InputDispatcher的start方法会启动一个名为InputDispatcher的线程,该线程会循环调用自己的dispatchOnce方法;InputReader的start方法会启动一个名为InputReader的线程,该线程会循环调用自己的loopOnce方法;并绘制了一个简单的IMS架构图。
本篇文章我们将在此基础上,继续结合Navite层的InputDispatcher和InputReader的源码,来分析Android系统是如何对输入事件进行加工和分发的。
一、输入事件的加工
1.1 InputReader的start方法
>frameworks/>native/services/inputflinger/reader/InputReader.cpp
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
//开启InputThread线程,并循环调用loopOnce方法。
mThread = std::make_unique<InputThread>(
"InputReader", [this]() {
loopOnce(); }, [this]() {
mEventHub->wake(); });
return OK;
}
void InputReader::loopOnce() {
...代码省略...
//从事件缓冲区中获取设备节点的事件信息并将其存放到mEventBuffer中
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
...代码省略...
if (count) {
//如果有事件,则调用processEventsLocked方法处理这些事件。
processEventsLocked(mEventBuffer, count);
}
...代码省略...
}
InputReader的start方法会开启一个名为InputThread的线程,该线程会循环调用loopOnce方法,该方法先是从事件缓冲区中获取设备节点的事件信息并将其存放到mEventBuffer中,如果有事件,则调用processEventsLocked方法处理这些事件。
1.2 InputReader的processEventsLocked方法
>frameworks/>native/services/inputflinger/reader/InputReader.cpp
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
//注释1,遍历所有事件
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
//注释2,事件类型分为原始输入事件和设备事件,这个条件语句对原始输入事件进行处理
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;
}
//处理deviceId所对应设备的原始输入事件
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
//注释3,对设备事件进行处理
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;
}
在注释1处会对传递进来的所有事件进行遍历。在注释2处会判断事件是输入事件还是设备事件,如果是输入事件,会调用processEventsForDeviceLocked方法。在注释3处判断如果是事件是设备事件,则会进一步判断设备事件的具体类型,针对不同的事件类型进行不同的操作,如果是设备新增,则调用addDeviceLocked方法,如果是设备移除,则调用removeDeviceLocked,如果配置变化,则调用handleConfigurationChangedLocked方法。
1.2.1 InputReader的processEventsForDeviceLocked方法
>frameworks/>native/services/inputflinger/reader/InputReader.cpp
//处理同一个设备的输入事件
void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
size_t count) {
//注释1,通过设备id获取设备对象
auto deviceIt = mDevices.find(eventHubId);
if (deviceIt == mDevices.end()) {
ALOGW("Discarding event for unknown eventHubId %d.", eventHubId);
return;
}
std::shared_ptr<InputDevice>& device = deviceIt->second;//获取输入设备对象
if (device->isIgnored()) {
// ALOGD("Discarding event for ignored deviceId %d.", deviceId);
return;
}
//注释,2,调用InputDevices的process方法
device->process(rawEvents, count);
}
>frameworks/native/services/inputflinger/reader/InputDevice.cpp
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
//遍历输入事件
for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
...代码省略...
//C++ Lambda 表达式,遍历与输入事件对应的设备ID关联的所有映射器,并调用每个映射器的process方法处理事件。
for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
//调用InputMapper的process方法
mapper.process(rawEvent);
});
...代码省略...
--count;
}
}
>frameworks/native/services/inputflinger/reader/include/InputDevice.h
inline void for_each_mapper_in_subdevice(int32_t eventHubDevice,
std::function<void(InputMapper&)> f) {
auto deviceIt = mDevices.find(eventHubDevice);//获取设备对象
if (deviceIt != mDevices.end()) {
auto& devicePair = deviceIt->second;
auto& mappers = devicePair.second;
for (auto& mapperPtr : mappers) {
//获取设备对象的InputMapper集合,循环执行其方法,其实就是process方法
f(*mapperPtr);
}
}
}
}
在注释1处通过deviceId获取输入设备在mDevices中实例对象,然后调用InputDevice实例对象的process方法,process方法会遍历所有输入事件,获取每个输入事件对应的设备ID关联的所有InputMapper映射器,并调用这些映射器的process方法处理事件。那么这些映射器是在什么地方被初始化的呢?
1.2.2 InputReader的addDeviceLocked方法
重新回到前面InputReader的processEventsLocked方法中,当一个输入事件类型为设备事件类型,且该设备事件类型为设备新增类型的时候,会调用addDeviceLocked方法来处理。
>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);
//注释1,调用createDeviceLocked方法创建InputDevice对象
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
...代码省略...
//注释2,将新创建的device对象添加到事件节点设备对象集合中
mDevices.emplace(eventHubId, device);
...代码省略...
}
std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
int32_t eventHubId, const InputDeviceIdentifier& identifier) {
auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) {
const InputDeviceIdentifier identifier2 =
devicePair.second->getDeviceInfo().getIdentifier();
return isSubDevice(identifier, identifier2);
});
std::shared_ptr<InputDevice> device;
if (deviceIt != mDevices.end()) {
device = deviceIt->second;
} else {
int32_t deviceId = (eventHubId < END_RESERVED_ID) ? eventHubId : nextInputDeviceIdLocked();
//创建输入设备对象
device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
identifier);
}
//注释3,调用InputDevice的addEventHubDevice方法,将输入事件添加到输入设备对象中
device->addEventHubDevice(eventHubId);
return device;
}
在注释1处调用createDeviceLocked方法创建InputDevice对象。在注释2处将新创建的device对象添加到事件节点设备对象集合中。在注释3处,也就是createDeviceLocked方法中,调用InputDevice的addEventHubDevice方法,将输入事件添加到输入设备对象中。
1.3 InputDevice的addEventHubDevice方法
>frameworks/native/services/inputflinger/reader/include/InputDevice.h
class InputDevice {
private:
using MapperVector = std::vector<std::unique_ptr<InputMapper>>;
using DevicePair = std::pair<std::unique_ptr<InputDeviceContext>, MapperVector>;
哈希映射表,里面存放了和eventHubId 关联的设备上下文和映射器列表
std::unordered_map<int32_t, DevicePair> mDevices;
}
>frameworks/native/services/inputflinger/reader/InputDevice.cpp
void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
//注释1,检查是否已存在指定的设备
if (mDevices.find(eventHubId) != mDevices.end()) {
return;
}
//创建新的设备上下文
std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
//获取设备类别
Flags<InputDeviceClass> cla