input之我见04——InputMangerService(Android7.0)

input之我见04——InputMangerService(Android7.0)

先抛出一个问题:
interceptKeyBeforQueueing 与 interceptKeyBeforDispatch的执行顺序。
很早以前…..
InputManager.cpp实例化的时候,会创建两个线程
  1. InputManager::InputManager(
  2. const sp<EventHubInterface>& eventHub,
  3. const sp<InputReaderPolicyInterface>& readerPolicy,
  4. const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
  5. mDispatcher = new InputDispatcher(dispatcherPolicy);
  6. mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
  7. initialize();
  8. }
  9. ...
  10. void InputManager::initialize() {
  11. mReaderThread = new InputReaderThread(mReader);
  12. mDispatcherThread = new InputDispatcherThread(mDispatcher);
  13. }
紧接着就start()
  1. status_t InputManager::start() {
  2. status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
  3. ...
  4. result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
  5. }
从此这两个线程就各自生活,貌似分道扬镳,其实却有着联系。
=>

InputReader

1,先看InputReader的构造函数,构造是在InputManager完成,
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
mDispatcher是InputDispacher的实例,而InputDispacher是继承了InputListenerInterface接口(继承爷爷接口),在此作为参数传递给InputReader,构造成mQueueListener变量,这就是InputReader与InputDispacher通信的桥梁。
=》
  1. InputReader::InputReader(const sp<EventHubInterface>& eventHub,
  2. const sp<InputReaderPolicyInterface>& policy,
  3. const sp<InputListenerInterface>& listener) :
  4. mContext(this), mEventHub(eventHub), mPolicy(policy),
  5. mGlobalMetaState(0), mGeneration(1),
  6. mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
  7. mConfigurationChangesToRefresh(0) {
  8. mQueuedListener = new QueuedInputListener(listener);
  9. { // acquire lock
  10. AutoMutex _l(mLock);
  11. refreshConfigurationLocked(0);
  12. updateGlobalMetaStateLocked();
  13. } // release lock
  14. }
来看InputReaderThread()的loopOnce(),是在InputReaderThread进行调用。
  1. bool InputReaderThread::threadLoop() {
  2. mReader->loopOnce();
  3. return true;
  4. }
InputReader.cpp里面
  1. void InputReader::loopOnce() {
  2. ...
  3. size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
  4. ...
  5. if (count) {
  6. processEventsLocked(mEventBuffer, count);
  7. }
  8. ...
  9. mQueuedListener->flush();
  10. }
去掉一些不重要的代码,loopOnce做了3件事
  • 通过EventHub->getEvents读取底层Input设备,是否有数据产生;
  • 如果有数据,就通过processEventLocked处理元数据,转化为input数据;
  • 处理完成之后,通过mQueueListener->flush()通知InputDispatcher去接收数据。
重点来看ProcessEventsLocked()
=>
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
=>
device->process(rawEvents, count);
=>
InputMapper* mapper = mMappers[i];
mapper->process(rawEvent);
通过不同的mapper来调用相应的process函数,我们这里关注KeyBoard
=>
void KeyboardInputMapper::process(const RawEvent* rawEvent)
=>
processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
=>
把rawEvent封装成NotifyKeyArgs的指针,
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
然后再传给某个Listener的nofifyKey,这个Listener就是InputListenerInterface,notifyKey调用就是InputDispacher的notifyKey。
getListener()->notifyKey(&args);
=>
进入InputDisaptcher.cpp
=>
  1. void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
  2. ...
  3. mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
  4. ...
  5. }
找到,interceptKeyBeforeQueueing终于又回到问题的出发点了。接下来看另外一处世界

InputDispacher

同理,先看InputDispacher的构造函数
  1. InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
  2. mPolicy(policy),
  3. mPendingEvent(NULL), mLastDropReason(DROP_REASON_NOT_DROPPED),
  4. mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
  5. mNextUnblockedEvent(NULL),
  6. mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
  7. mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
  8. mLooper = new Looper(false);
  9. mKeyRepeatState.lastKeyEntry = NULL;
  10. policy->getDispatcherConfiguration(&mConfig);
  11. }
没啥要特别讲的,那么进入线程的loop函数
  1. bool InputDispatcherThread::threadLoop() {
  2. mDispatcher->dispatchOnce();
  3. return true;
  4. }
=>
  1. if (!haveCommandsLocked()) {
  2. dispatchOnceInnerLocked(&nextWakeupTime);
  3. }
如果有数据就进入dispachOnceInnerLocked,进一步处理。
=>
同理,我们只关注Key的处理事件
  1. void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
  2. ...
  3. case EventEntry::TYPE_KEY: {
  4. KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
  5. if (isAppSwitchDue) {
  6. if (isAppSwitchKeyEventLocked(typedEntry)) {
  7. resetPendingAppSwitchLocked(true);
  8. isAppSwitchDue = false;
  9. } else if (dropReason == DROP_REASON_NOT_DROPPED) {
  10. dropReason = DROP_REASON_APP_SWITCH;
  11. }
  12. }
  13. if (dropReason == DROP_REASON_NOT_DROPPED
  14. && isStaleEventLocked(currentTime, typedEntry)) {
  15. dropReason = DROP_REASON_STALE;
  16. }
  17. if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
  18. dropReason = DROP_REASON_BLOCKED;
  19. }
  20. done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
  21. break;
  22. }
  23. ...
  24. }
=>
dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime)
=>
  1. CommandEntry* commandEntry = postCommandLocked(
  2. & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
=>
 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
            &event, entry->policyFlags);
又回到了问题的起点,interceptKeyBeforDispatching。我想到了我几年前画的一草图,其实当时并未完全理解,现在再看,只是信息更丰富了。
InputReader通过EventHub轮询读取底层数据,处理后,会通过Queue给到InputDispacher,InputDispacher再做进一步策略处理,发送给View做显示。
有了以上的信息,我们可以回答,一个Key键值的上报是先通过interceptKeyBeforQueueing 再执行interceptKeyBeforDispatch。
Comments are closed.
TOP