一、InputDispatcher的notifyKey函数

接上一篇我们我们分析到InputDispatcher的notifyKey函数:

1. void InputDispatcher::notifyKey(const
2. if
3. return;  
4.     }  
5.   
6.     uint32_t policyFlags = args->policyFlags;  
7.     int32_t flags = args->flags;  
8.     int32_t metaState = args->metaState;  
9. if
10.         policyFlags |= POLICY_FLAG_VIRTUAL;  
11.         flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;  
12.     }  
13. if
14.         metaState |= AMETA_FUNCTION_ON;  
15.     }  
16.   
17.     policyFlags |= POLICY_FLAG_TRUSTED;  
18.   
19.     int32_t keyCode = args->keyCode;  
20. if
21.         int32_t newKeyCode = AKEYCODE_UNKNOWN;  
22. if
23.             newKeyCode = AKEYCODE_BACK;  
24. else if
25.             newKeyCode = AKEYCODE_HOME;  
26.         }  
27. if
28.             AutoMutex _l(mLock);  
29. struct
30.             mReplacedKeys.add(replacement, newKeyCode);  
31.             keyCode = newKeyCode;  
32.             metaState &= ~AMETA_META_ON;  
33.         }  
34. else if
35. // In order to maintain a consistent stream of up and down events, check to see if the key
36. // going up is one we've replaced in a down event and haven't yet replaced in an up event,
37. // even if the modifier was released between the down and the up events.
38.         AutoMutex _l(mLock);  
39. struct
40.         ssize_t index = mReplacedKeys.indexOfKey(replacement);  
41. if
42.             keyCode = mReplacedKeys.valueAt(index);  
43.             mReplacedKeys.removeItemsAt(index);  
44.             metaState &= ~AMETA_META_ON;  
45.         }  
46.     }  
47.   
48.     KeyEvent event;  
49.     event.initialize(args->deviceId, args->source, args->action,  
50.             flags, keyCode, args->scanCode, metaState, 0,  
51.             args->downTime, args->eventTime);  
52.   
53. /*byref*/ policyFlags);//这个函数是调用了java的PhoneWindowManager
54.   
55. bool
56. // acquire lock
57.         mLock.lock();  
58.   
59. if
60.             mLock.unlock();  
61.   
62.             policyFlags |= POLICY_FLAG_FILTERED;  
63. if
64. return; // event was consumed by the filter
65.             }  
66.   
67.             mLock.lock();  
68.         }  
69.   
70.         int32_t repeatCount = 0;  
71. new
72.                 args->deviceId, args->source, policyFlags,  
73.                 args->action, flags, keyCode, args->scanCode,  
74.                 metaState, repeatCount, args->downTime);  
75.   
76. //将KeyEntry放入到队列中
77.         mLock.unlock();  
78. // release lock
79.   
80. if
81. //唤醒进程
82.     }  
83. }

我们先来看看mPolicy是构造函数中传进来的,那么我们就要去看InputManager中

    1. InputDispatcher::InputDispatcher(const
    2.     mPolicy(policy),


    InputManager的构造函数,还是在InputManager中传入的,那么我们就要跟到NativeInputManager了。

      1. InputManager::InputManager(  
      2. const
      3. const
      4. const
      5. new
      6. new

      NativeInputManager是把自己传进来了,

      1. NativeInputManager::NativeInputManager(jobject contextObj,  
      2. const
      3. true) {  
      4.     JNIEnv* env = jniEnv();  
      5.   
      6.     mContextObj = env->NewGlobalRef(contextObj);  
      7.     mServiceObj = env->NewGlobalRef(serviceObj);  
      8.   
      9.     {  
      10.         AutoMutex _l(mLock);  
      11.         mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;  
      12.         mLocked.pointerSpeed = 0;  
      13. true;  
      14. false;  
      15.     }  
      16. true;  
      17.   
      18. new
      19. new InputManager(eventHub, this, this);


      因此在InputDispatcher中调用interceptKeyBeforeQueueing,是调用了NativeInputManager的interceptKeyBeforeQueueing函数

      1. void NativeInputManager::interceptKeyBeforeQueueing(const
      2.         uint32_t& policyFlags) {  
      3. // Policy:
      4. // - Ignore untrusted events and pass them along.
      5. // - Ask the window manager what to do with normal events and trusted injected events.
      6. // - For normal events wake and brighten the screen if currently off or dim.
      7. bool
      8. if
      9.         policyFlags |= POLICY_FLAG_INTERACTIVE;  
      10.     }  
      11. if
      12.         nsecs_t when = keyEvent->getEventTime();  
      13.         JNIEnv* env = jniEnv();  
      14.         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);  
      15.         jint wmActions;  
      16. if
      17. //反调用PhoneWindowManager
      18.                     gServiceClassInfo.interceptKeyBeforeQueueing,  
      19.                     keyEventObj, policyFlags);  
      20. if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {  
      21.                 wmActions = 0;  
      22.             }  
      23.             android_view_KeyEvent_recycle(env, keyEventObj);  
      24.             env->DeleteLocalRef(keyEventObj);  
      25. else
      26. "Failed to obtain key event object for interceptKeyBeforeQueueing.");  
      27.             wmActions = 0;  
      28.         }  
      29.   
      30. /*byref*/
      31. else
      32. if
      33.             policyFlags |= POLICY_FLAG_PASS_TO_USER;  
      34.         }  
      35.     }  
      36. }


      在这个函数中会反调到PhoneWindowManager中的interceptKeyBeforeQueueing函数,在上层的result返回result &= ~ACTION_PASS_TO_USER就不会发送到应用进程了。

      返回结果保存在wmActions中,然后调用了handleInterceptActions函数:

      1. void
      2.         uint32_t& policyFlags) {  
      3. if
      4.         policyFlags |= POLICY_FLAG_PASS_TO_USER;  
      5. else
      6.     }  
      7. }

      如果PhoneWindowManager返回的是result &= ~ACTION_PASS_TO_USER,policyFlags |= POLICY_FLAG_PASS_TO_USER就没有了。



      继续分析InputDispatcher::notifyKey函数,调用完interceptKeyBeforeQueueing,然后 新建了一个KeyEntry对象后,调用enqueueInboundEventLocked函数。

      1. bool
      2. bool
      3. //放入队列尾
      4.     traceInboundQueueLengthLocked();  
      5.   
      6. switch
      7. case EventEntry::TYPE_KEY: {//各个不同类型
      8. // Optimize app switch latency.
      9. // If the application takes too long to catch up then we drop all events preceding
      10. // the app switch key.
      11. static_cast<KeyEntry*>(entry);  
      12. if
      13. if
      14. true;  
      15. else if
      16. if
      17. #if DEBUG_APP_SWITCH
      18. "App switch is pending!");  
      19. #endif
      20.                     mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;  
      21. false;  
      22. true;  
      23.                 }  
      24.             }  
      25.         }  
      26. break;  
      27.     }

      继续分析InputDispatcher::notifyKey函数,最后会调用mLooper的wake函数唤醒线程,这个我们就不详细分析了。之前分析过。



      二、InputDispatcher分发

      notifyKey我们分析完了,接下来我们分析之前的InputDispatcherThread,线程不断的循环调用了InputDispatcher的dispatchOnce函数,下面我们来看下:

      1. void
      2.     nsecs_t nextWakeupTime = LONG_LONG_MAX;  
      3. // acquire lock
      4.         AutoMutex _l(mLock);  
      5.         mDispatcherIsAliveCondition.broadcast();  
      6.   
      7. // Run a dispatch loop if there are no pending commands.
      8. // The dispatch loop might enqueue commands to run afterwards.
      9. if
      10. //分发消息
      11.         }  
      12.   
      13. // Run all pending commands if there are any.
      14. // If any commands were run then force the next poll to wake up immediately.
      15. if
      16.             nextWakeupTime = LONG_LONG_MIN;  
      17.         }  
      18. // release lock
      19.   
      20. // Wait for callback or timeout or wake.  (make sure we round up, not down)
      21.     nsecs_t currentTime = now();  
      22. int
      23. //进入epoll
      24. }


      继续分析dispatchOnceInnerLocked函数

      1. void
      2.     ........  
      3.   
      4. switch (mPendingEvent->type) {//根据类型不同
      5. case
      6.         ConfigurationChangedEntry* typedEntry =  
      7. static_cast<ConfigurationChangedEntry*>(mPendingEvent);  
      8.         done = dispatchConfigurationChangedLocked(currentTime, typedEntry);  
      9. // configuration changes are never dropped
      10. break;  
      11.     }  
      12.   
      13. case
      14.         DeviceResetEntry* typedEntry =  
      15. static_cast<DeviceResetEntry*>(mPendingEvent);  
      16.         done = dispatchDeviceResetLocked(currentTime, typedEntry);  
      17. // device resets are never dropped
      18. break;  
      19.     }  
      20.   
      21. case
      22. static_cast<KeyEntry*>(mPendingEvent);  
      23. if
      24. if
      25. true);  
      26. false;  
      27. else if
      28.                 dropReason = DROP_REASON_APP_SWITCH;  
      29.             }  
      30.         }  
      31. if
      32.                 && isStaleEventLocked(currentTime, typedEntry)) {  
      33.             dropReason = DROP_REASON_STALE;  
      34.         }  
      35. if
      36.             dropReason = DROP_REASON_BLOCKED;  
      37.         }  
      38.         done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);  
      39. break;  
      40.     }  
      41.   
      42. case
      43. static_cast<MotionEntry*>(mPendingEvent);  
      44. if
      45.             dropReason = DROP_REASON_APP_SWITCH;  
      46.         }  
      47. if
      48.                 && isStaleEventLocked(currentTime, typedEntry)) {  
      49.             dropReason = DROP_REASON_STALE;  
      50.         }  
      51. if
      52.             dropReason = DROP_REASON_BLOCKED;  
      53.         }  
      54.         done = dispatchMotionLocked(currentTime, typedEntry,  
      55.                 &dropReason, nextWakeupTime);  
      56. break;  
      57.     }  
      58.   
      59. default:  
      60. false);  
      61. break;  
      62.     }  
      63.   
      64. if
      65. if
      66.             dropInboundEventLocked(mPendingEvent, dropReason);  
      67.         }  
      68.         mLastDropReason = dropReason;  
      69.   
      70.         releasePendingEventLocked();  
      71. // force next poll to wake up immediately
      72.     }  
      73. }

      这个函数中,最后会根据类型不同调用不同的方法,我们是TYPE_KEY,调用了dispatchKeyLocked方法,一路跟下去有很多函数,我们就直接到最后的函数startDispatchCycleLocked函数:

      1. void
      2. const
      3.   
      4. while
      5.             && !connection->outboundQueue.isEmpty()) {  
      6.         DispatchEntry* dispatchEntry = connection->outboundQueue.head;  
      7.         dispatchEntry->deliveryTime = currentTime;  
      8.   
      9. // Publish the event.
      10.         status_t status;  
      11.         EventEntry* eventEntry = dispatchEntry->eventEntry;  
      12. switch
      13. case
      14. static_cast<KeyEntry*>(eventEntry);  
      15.   
      16. // Publish the key event.
      17.             status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,  
      18.                     keyEntry->deviceId, keyEntry->source,  
      19.                     dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,  
      20.                     keyEntry->keyCode, keyEntry->scanCode,  
      21.                     keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,  
      22.                     keyEntry->eventTime);  
      23. break;  
      24.         }


      这个函数会根据Event类型来分别处理,最后调用了connection对象的inputPublisher的publishKeyEvent函数。

      下篇博客我们来继续分析下connection这个对象从何而来?