Android系统输入事件产生的底层主要是输入子系统,Android 中的输入设备有很多,例如屏幕,鼠标,键盘等都是输入设备,对于应用开发者,接触最多的也就是屏幕了。
1. 当输入设备可用时,Linux会在 /dev/input 中创建对应的设备节点。
2. 用户操作输入设备就会产生各种事件,这些事件的原始信息就会被 Linux内核中的输入子系统采集,原始信息由 Kernel space 的驱动层一直传递到设备结点。
3. InputReader读取设备节点数据并对输入事件信息进行加工处理,加工处理后的事件会交给 InputDispatcher 来处理。
以下是InputReader创建InputDevice设备、读取事件和交给InputDispatcher事件的调用流程
@frameworks/native/services/inputflinger/reader/InputReader.cpp
InputReader::start
loopOnce()
processEventsLocked(mEventBuffer, count);
case EventHubInterface::DEVICE_ADDED: addDeviceLocked(rawEvent->when, rawEvent->deviceId); //添加设备
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
if(identifier.vendor == 8183 && identifier.product == 4084) { return; } //根据keyboard设备类型判断,不添加设备,以免vd启动异常
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier)
@frameworks/native/services/inputflinger/reader/InputDevice.cpp
device->addEventHubDevice(eventHubId); //添加触摸光标设备
if (classes.test(InputDeviceClass::BATTERY) || classes.test(InputDeviceClass::LIGHT)) { mController = std::make_unique<PeripheralController>(*contextPtr); }
if (classes.test(InputDeviceClass::CURSOR)) { mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr)); }
//addDeviceLocked Device added: id=3, eventHubId=8, name='hyn_ts', descriptor='dd768709fe8e1221a31cd1cbe2fb6da013ae6c46',sources=0x00002002
mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
auto deviceIt = mDevices.find(eventHubId);
device->process(rawEvents, count);
@frameworks/native/services/inputflinger/reader/InputDevice.cpp
for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper)
auto deviceIt = mDevices.find(eventHubDevice); //eventHubDevice=8
@frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cpp
mapper.process(rawEvent); //CursorInputMapper::process
mCursorButtonAccumulator.process(rawEvent);
mCursorMotionAccumulator.process(rawEvent);
mCursorScrollAccumulator.process(rawEvent);
sync(rawEvent->when, rawEvent->readTime);
getListener()->notifyMotion(&args);
InputDispatcher::notifyMotion
mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
needWake = enqueueInboundEventLocked(std::move(newEntry));
mInboundQueue.push_back(std::move(newEntry)); //放入mInboundQueue队列