From d0097871828bb7d5d6eec06cadd92c2e3358849b Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 30 Jun 2010 14:41:59 -0700 Subject: [PATCH] Fix injection of specially intercepted keys like HOME. This change mainly unwinds a premature optimization in the dispatch pipeline. To test HOME injection, run 'adb shell input keyevent 3'. Change-Id: I1c4b7377c205da7c898014b8b07fc6dc1d46e4dd --- include/ui/Input.h | 3 - include/ui/InputReader.h | 4 -- libs/ui/InputReader.cpp | 4 -- .../jni/com_android_server_InputManager.cpp | 61 ++++++++++--------- 4 files changed, 31 insertions(+), 41 deletions(-) diff --git a/include/ui/Input.h b/include/ui/Input.h index 214f587c78359..a2e0ba06a2c24 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -87,9 +87,6 @@ enum { // Indicates that the screen was dim when the event was received and the event // should brighten the device. POLICY_FLAG_BRIGHT_HERE = 0x20000000, - - // Indicates that the dispatcher should call back into the policy before dispatching. */ - POLICY_FLAG_INTERCEPT_DISPATCH = 0x40000000, }; /* diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h index 8f6777d10666b..781da356a07fa 100644 --- a/include/ui/InputReader.h +++ b/include/ui/InputReader.h @@ -371,10 +371,6 @@ public: // The input dispatcher should add POLICY_FLAG_BRIGHT_HERE to the policy flags it // passes through the dispatch pipeline. ACTION_BRIGHT_HERE = 0x00000008, - - // The input dispatcher should add POLICY_FLAG_INTERCEPT_DISPATCH to the policy flags - // it passed through the dispatch pipeline. - ACTION_INTERCEPT_DISPATCH = 0x00000010 }; /* Describes a virtual key. */ diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index 217c5970359d3..899027c9b9208 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -1639,10 +1639,6 @@ bool InputReader::applyStandardInputDispatchPolicyActions(nsecs_t when, *policyFlags |= POLICY_FLAG_BRIGHT_HERE; } - if (policyActions & InputReaderPolicyInterface::ACTION_INTERCEPT_DISPATCH) { - *policyFlags |= POLICY_FLAG_INTERCEPT_DISPATCH; - } - return policyActions & InputReaderPolicyInterface::ACTION_DISPATCH; } diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp index 7f245f363faf8..d0f856b84f5ae 100644 --- a/services/jni/com_android_server_InputManager.cpp +++ b/services/jni/com_android_server_InputManager.cpp @@ -374,6 +374,9 @@ private: int32_t identifyTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector& outTargets); + bool interceptKeyBeforeDispatching(const InputTarget& target, + const KeyEvent* keyEvent, uint32_t policyFlags); + void pokeUserActivityIfNeeded(int32_t windowType, int32_t eventType); void pokeUserActivity(nsecs_t eventTime, int32_t eventType); bool checkInjectionPermission(const InputWindow* window, @@ -633,8 +636,6 @@ int32_t NativeInputManager::interceptKey(nsecs_t when, } } - // TODO Be smarter about which keys cause us to request interception during dispatch. - actions |= InputReaderPolicyInterface::ACTION_INTERCEPT_DISPATCH; return actions; } @@ -1530,34 +1531,11 @@ int32_t NativeInputManager::waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t windowType = focusedWindow->layoutParamsType; } // release lock - if (policyFlags & POLICY_FLAG_INTERCEPT_DISPATCH) { - const InputTarget& target = outTargets.top(); - - JNIEnv* env = jniEnv(); - - jobject inputChannelObj = getInputChannelObjLocal(env, target.inputChannel); - if (inputChannelObj) { - jboolean consumed = env->CallBooleanMethod(mCallbacksObj, - gCallbacksClassInfo.interceptKeyBeforeDispatching, - inputChannelObj, keyEvent->getKeyCode(), keyEvent->getMetaState(), - keyEvent->getAction() == KEY_EVENT_ACTION_DOWN, - keyEvent->getRepeatCount(), policyFlags); - bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatch"); - - env->DeleteLocalRef(inputChannelObj); - - if (error) { - return INPUT_EVENT_INJECTION_FAILED; - } - - if (consumed) { - outTargets.clear(); - return INPUT_EVENT_INJECTION_SUCCEEDED; - } - } else { - LOGW("Could not apply key dispatch policy because input channel '%s' is " - "no longer valid.", target.inputChannel->getName().string()); - } + const InputTarget& target = outTargets.top(); + bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags); + if (consumed) { + outTargets.clear(); + return INPUT_EVENT_INJECTION_SUCCEEDED; } pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT); @@ -1656,6 +1634,29 @@ int32_t NativeInputManager::identifyTouchEventTargets(MotionEvent* motionEvent, return INPUT_EVENT_INJECTION_SUCCEEDED; } +bool NativeInputManager::interceptKeyBeforeDispatching(const InputTarget& target, + const KeyEvent* keyEvent, uint32_t policyFlags) { + JNIEnv* env = jniEnv(); + + jobject inputChannelObj = getInputChannelObjLocal(env, target.inputChannel); + if (inputChannelObj) { + jboolean consumed = env->CallBooleanMethod(mCallbacksObj, + gCallbacksClassInfo.interceptKeyBeforeDispatching, + inputChannelObj, keyEvent->getKeyCode(), keyEvent->getMetaState(), + keyEvent->getAction() == KEY_EVENT_ACTION_DOWN, + keyEvent->getRepeatCount(), policyFlags); + bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching"); + + env->DeleteLocalRef(inputChannelObj); + + return consumed && ! error; + } else { + LOGW("Could not apply key dispatch policy because input channel '%s' is " + "no longer valid.", target.inputChannel->getName().string()); + return false; + } +} + void NativeInputManager::pokeUserActivityIfNeeded(int32_t windowType, int32_t eventType) { if (windowType != TYPE_KEYGUARD) { nsecs_t eventTime = now();