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
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 7f245f3..d0f856b 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -374,6 +374,9 @@
     int32_t identifyTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
             int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& 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 @@
         }
     }
 
-    // TODO Be smarter about which keys cause us to request interception during dispatch.
-    actions |= InputReaderPolicyInterface::ACTION_INTERCEPT_DISPATCH;
     return actions;
 }
 
@@ -1530,34 +1531,11 @@
         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 @@
     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();