am 4b255a23: am 03aa28fb: Merge "Improve the input policy handling a bit." into gingerbread

Merge commit '4b255a23041225103a6870e77a236f78c2816eda'

* commit '4b255a23041225103a6870e77a236f78c2816eda':
  Improve the input policy handling a bit.
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 3b9ef6d..84c3db8 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -432,10 +432,9 @@
     switch (dropReason) {
     case DROP_REASON_POLICY:
 #if DEBUG_INBOUND_EVENT_DETAILS
-        LOGD("Dropped event because policy requested that it not be delivered to the application.");
+        LOGD("Dropped event because policy consumed it.");
 #endif
-        reason = "inbound event was dropped because the policy requested that it not be "
-                "delivered to the application";
+        reason = "inbound event was dropped because the policy consumed it";
         break;
     case DROP_REASON_DISABLED:
         LOGI("Dropped event because input dispatch is disabled.");
@@ -625,15 +624,13 @@
         if (*dropReason == DROP_REASON_NOT_DROPPED) {
             *dropReason = DROP_REASON_POLICY;
         }
-        resetTargetsLocked();
-        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
-        return true;
     }
 
     // Clean up if dropping the event.
     if (*dropReason != DROP_REASON_NOT_DROPPED) {
         resetTargetsLocked();
-        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
+                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
         return true;
     }
 
@@ -713,7 +710,8 @@
     // Clean up if dropping the event.
     if (*dropReason != DROP_REASON_NOT_DROPPED) {
         resetTargetsLocked();
-        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
+                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
         return true;
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ec5b098..c6898d4 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1124,10 +1124,6 @@
     @Override
     public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
             int keyCode, int metaState, int repeatCount, int policyFlags) {
-        if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
-            return false;
-        }
-
         final boolean keyguardOn = keyguardOn();
         final boolean down = (action == KeyEvent.ACTION_DOWN);
         final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
@@ -1860,9 +1856,6 @@
     public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
             int policyFlags, boolean isScreenOn) {
         int result = ACTION_PASS_TO_USER;
-        if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
-            return result;
-        }
 
         if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
             performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
@@ -1870,7 +1863,14 @@
 
         final boolean isWakeKey = (policyFlags
                 & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
-        
+
+        // If the key is injected, pretend that the screen is on and don't let the
+        // device go to sleep.  This feature is mainly used for testing purposes.
+        final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
+        if (isInjected) {
+            isScreenOn = true;
+        }
+
         // If screen is off then we treat the case where the keyguard is open but hidden
         // the same as if it were open and in front.
         // This will prevent any keys other than the power button from waking the screen
@@ -1969,7 +1969,7 @@
                         || (handled && hungUp && keyCode == KeyEvent.KEYCODE_POWER)) {
                     mShouldTurnOffOnKeyUp = false;
                 } else {
-                    // only try to turn off the screen if we didn't already hang up
+                    // Only try to turn off the screen if we didn't already hang up.
                     mShouldTurnOffOnKeyUp = true;
                     mHandler.postDelayed(mPowerLongPress,
                             ViewConfiguration.getGlobalActionKeyTimeout());
@@ -1992,12 +1992,14 @@
                     if (keyguardActive
                             || (sleeps && !gohome)
                             || (gohome && !goHome() && sleeps)) {
-                        // they must already be on the keyguad or home screen,
-                        // go to sleep instead
-                        Log.d(TAG, "I'm tired mEndcallBehavior=0x"
-                                + Integer.toHexString(mEndcallBehavior));
-                        result &= ~ACTION_POKE_USER_ACTIVITY;
-                        result |= ACTION_GO_TO_SLEEP;
+                        // They must already be on the keyguard or home screen,
+                        // go to sleep instead unless the event was injected.
+                        if (!isInjected) {
+                            Log.d(TAG, "I'm tired mEndcallBehavior=0x"
+                                    + Integer.toHexString(mEndcallBehavior));
+                            result &= ~ACTION_POKE_USER_ACTIVITY;
+                            result |= ACTION_GO_TO_SLEEP;
+                        }
                     }
                     result &= ~ACTION_PASS_TO_USER;
                 }
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index e15e8d8..599163b 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -842,31 +842,35 @@
         flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
     }
 
-    const int32_t WM_ACTION_PASS_TO_USER = 1;
-    const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
-    const int32_t WM_ACTION_GO_TO_SLEEP = 4;
+    // Policy:
+    // - Ignore untrusted events and pass them along.
+    // - Ask the window manager what to do with normal events and trusted injected events.
+    // - For normal events wake and brighten the screen if currently off or dim.
+    if ((policyFlags & POLICY_FLAG_TRUSTED)) {
+        const int32_t WM_ACTION_PASS_TO_USER = 1;
+        const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
+        const int32_t WM_ACTION_GO_TO_SLEEP = 4;
 
-    bool isScreenOn = this->isScreenOn();
-    bool isScreenBright = this->isScreenBright();
+        bool isScreenOn = this->isScreenOn();
+        bool isScreenBright = this->isScreenBright();
 
-    JNIEnv* env = jniEnv();
-    jint wmActions = env->CallIntMethod(mCallbacksObj,
-            gCallbacksClassInfo.interceptKeyBeforeQueueing,
-            when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
-    if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
-        wmActions = 0;
-    }
-
-    if (policyFlags & POLICY_FLAG_TRUSTED) {
-        if (! isScreenOn) {
-            // Key presses and releases wake the device.
-            policyFlags |= POLICY_FLAG_WOKE_HERE;
-            flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+        JNIEnv* env = jniEnv();
+        jint wmActions = env->CallIntMethod(mCallbacksObj,
+                gCallbacksClassInfo.interceptKeyBeforeQueueing,
+                when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
+        if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
+            wmActions = 0;
         }
 
-        if (! isScreenBright) {
-            // Key presses and releases brighten the screen if dimmed.
-            policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+        if (!(flags & POLICY_FLAG_INJECTED)) {
+            if (!isScreenOn) {
+                policyFlags |= POLICY_FLAG_WOKE_HERE;
+                flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+            }
+
+            if (!isScreenBright) {
+                policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+            }
         }
 
         if (wmActions & WM_ACTION_GO_TO_SLEEP) {
@@ -876,9 +880,11 @@
         if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
             android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
         }
-    }
 
-    if (wmActions & WM_ACTION_PASS_TO_USER) {
+        if (wmActions & WM_ACTION_PASS_TO_USER) {
+            policyFlags |= POLICY_FLAG_PASS_TO_USER;
+        }
+    } else {
         policyFlags |= POLICY_FLAG_PASS_TO_USER;
     }
 }
@@ -888,33 +894,47 @@
     LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
 #endif
 
-    if (isScreenOn()) {
-        // Only dispatch events when the device is awake.
-        // Do not wake the device.
-        policyFlags |= POLICY_FLAG_PASS_TO_USER;
+    // Policy:
+    // - Ignore untrusted events and pass them along.
+    // - No special filtering for injected events required at this time.
+    // - Filter normal events based on screen state.
+    // - For normal events brighten (but do not wake) the screen if currently dim.
+    if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
+        if (isScreenOn()) {
+            policyFlags |= POLICY_FLAG_PASS_TO_USER;
 
-        if ((policyFlags & POLICY_FLAG_TRUSTED) && !isScreenBright()) {
-            // Brighten the screen if dimmed.
-            policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+            if (!isScreenBright()) {
+                policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+            }
         }
+    } else {
+        policyFlags |= POLICY_FLAG_PASS_TO_USER;
     }
 }
 
 bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
         const KeyEvent* keyEvent, uint32_t policyFlags) {
-    JNIEnv* env = jniEnv();
+    // Policy:
+    // - Ignore untrusted events and pass them along.
+    // - Filter normal events and trusted injected events through the window manager policy to
+    //   handle the HOME key and the like.
+    if (policyFlags & POLICY_FLAG_TRUSTED) {
+        JNIEnv* env = jniEnv();
 
-    // Note: inputChannel may be null.
-    jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
-    jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
-            gCallbacksClassInfo.interceptKeyBeforeDispatching,
-            inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
-            keyEvent->getKeyCode(), keyEvent->getMetaState(),
-            keyEvent->getRepeatCount(), policyFlags);
-    bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
+        // Note: inputChannel may be null.
+        jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
+        jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
+                gCallbacksClassInfo.interceptKeyBeforeDispatching,
+                inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
+                keyEvent->getKeyCode(), keyEvent->getMetaState(),
+                keyEvent->getRepeatCount(), policyFlags);
+        bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
 
-    env->DeleteLocalRef(inputChannelObj);
-    return consumed && ! error;
+        env->DeleteLocalRef(inputChannelObj);
+        return consumed && ! error;
+    } else {
+        return false;
+    }
 }
 
 void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {