前面的博客有提到过android事件上报流程,InputReaderThread 从EventHub读到按键事件后,交给InputDispatcher 往上上报,我们从这里跟踪一下长按power键关键流程,
frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
…
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
…
}
这里的mPolicy是NativeInputManager对象.
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
…
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
886 jint wmActions;
887 if (keyEventObj) {
888 wmActions = env->CallIntMethod(mServiceObj,
889 gServiceClassInfo.interceptKeyBeforeQueueing,
890 keyEventObj, policyFlags);
891 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
892 wmActions = 0;
893 }
894 android_view_KeyEvent_recycle(env, keyEventObj);
895 env->DeleteLocalRef(keyEventObj);
896 } else {
897 ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
898 wmActions = 0;
899 }
…
}
这里会call到java层,call 到InputManagerService里面。
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
// Native callback.
1871 private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
1872 return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags);
}
这个mWindowManagerCallbacks 是通过下面的接口设置的。
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
继续追查下去,就是一个InputMonitor 实例。
frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
}
这里的mService就是WindowManagerService。
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.javafinal WindowManagerPolicy mPolicy = new PhoneWindowManager();
所以这个mPolicy就是PhoneWindowManager对象。
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
case KeyEvent.KEYCODE_POWER: {
5815 result &= ~ACTION_PASS_TO_USER;
5816 isWakeKey = false; // wake-up will be handled separately
5817 if (down) {
5818 interceptPowerKeyDown(event, interactive);
5819 } else {
5820 interceptPowerKeyUp(event, interactive, canceled);
5821 }
5822 break;
5823 }
}
继续走到interceptPowerKeyDown()函数里面。
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {