Android系統輸入事件產生的底層主要是輸入子系統,Android 中的輸入設備有很多,例如屏幕,鼠標,鍵盤等都是輸入設備,對于應用開發者,接觸最多的也就是屏幕了。
1. 當輸入設備可用時,Linux會在 /dev/input 中創建對應的設備節點。
2. 用戶操作輸入設備就會產生各種事件,這些事件的原始信息就會被 Linux內核中的輸入子系統采集,原始信息由 Kernel space 的驅動層一直傳遞到設備結點。
3. InputReader讀取設備節點數據并對輸入事件信息進行加工處理,加工處理后的事件會交給 InputDispatcher 來處理。
以下是InputReader創建InputDevice設備、讀取事件和交給InputDispatcher事件的調用流程
@frameworks/native/services/inputflinger/reader/InputReader.cpp
InputReader::startloopOnce()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=0x00002002mDevices.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.cppfor_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::processmCursorButtonAccumulator.process(rawEvent);mCursorMotionAccumulator.process(rawEvent);mCursorScrollAccumulator.process(rawEvent);sync(rawEvent->when, rawEvent->readTime);getListener()->notifyMotion(&args);InputDispatcher::notifyMotionmPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);needWake = enqueueInboundEventLocked(std::move(newEntry));mInboundQueue.push_back(std::move(newEntry)); //放入mInboundQueue隊列