Allow for event dispatching when in non-interactive states.

We need to allow for event dispatching in non-interactive states so
that we can enable a richer set of interactions when a device is
dozing (i.e. is in a low power state with an Always-on-Display).

Bug: 17167296
Change-Id: I8ae0f544a8106cb91ff38c2309b8b57cbe2f2c72
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 053fdd0..78d0421 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -761,7 +761,8 @@
     public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
 
     /**
-     * Called from the input reader thread before a motion is enqueued when the screen is off.
+     * Called from the input reader thread before a motion is enqueued when the device is in a
+     * non-interactive state.
      *
      * <p>There are some actions that need to be handled here because they
      * affect the power state of the device, for example, waking on motions.
@@ -771,7 +772,7 @@
      *
      * @return Actions flags: may be {@link #ACTION_PASS_TO_USER}.
      */
-    public int interceptWakeMotionBeforeQueueing(long whenNanos, int policyFlags);
+    public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags);
 
     /**
      * Called from the input dispatcher thread before a key is dispatched to a window.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e382a9f..22bdb17 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4203,8 +4203,12 @@
         int result;
         boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
                 || event.isWakeKey();
-        if (interactive || (isInjected && !isWakeKey)) {
-            // When the screen is on or if the key is injected pass the key to the application.
+        if (interactive
+                || (isInjected && !isWakeKey)
+                || (!interactive && shouldDispatchInputWhenNonInteractive())) {
+            // When the device is interactive, the key is injected, or we're currently dozing in a
+            // non-interactive state with the screen on and the keyguard showing,  pass the key to
+            // the application.
             result = ACTION_PASS_TO_USER;
             isWakeKey = false;
         } else {
@@ -4511,14 +4515,22 @@
 
     /** {@inheritDoc} */
     @Override
-    public int interceptWakeMotionBeforeQueueing(long whenNanos, int policyFlags) {
-        // We already know this is a wake motion so just wake up.
-        // Note that we would observe policyFlags containing
-        // FLAG_WAKE and FLAG_INTERACTIVE here.
-        mPowerManager.wakeUp(whenNanos / 1000000);
+    public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
+        if ((policyFlags & FLAG_WAKE) != 0) {
+            mPowerManager.wakeUp(whenNanos / 1000000);
+            return 0;
+        }
+        if (shouldDispatchInputWhenNonInteractive()) {
+            return ACTION_PASS_TO_USER;
+        }
         return 0;
     }
 
+    private boolean shouldDispatchInputWhenNonInteractive() {
+        return keyguardIsShowingTq() && mDisplay != null &&
+                mDisplay.getState() != Display.STATE_OFF;
+    }
+
     void dispatchMediaKeyWithWakeLock(KeyEvent event) {
         if (DEBUG_INPUT) {
             Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6310764..1eae5e3 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9883,7 +9883,7 @@
     }
 
     private void updateEventDispatchingLocked() {
-        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
+        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
     }
 
     public void setLockScreenShown(boolean shown) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 93dceff..78e999a 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1420,8 +1420,8 @@
     }
 
     // Native callback.
-    private int interceptWakeMotionBeforeQueueing(long whenNanos, int policyFlags) {
-        return mWindowManagerCallbacks.interceptWakeMotionBeforeQueueing(
+    private int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
+        return mWindowManagerCallbacks.interceptMotionBeforeQueueingNonInteractive(
                 whenNanos, policyFlags);
     }
 
@@ -1582,7 +1582,7 @@
 
         public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
 
-        public int interceptWakeMotionBeforeQueueing(long whenNanos, int policyFlags);
+        public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags);
 
         public long interceptKeyBeforeDispatching(InputWindowHandle focus,
                 KeyEvent event, int policyFlags);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index f02c0e6..2f04578 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -359,12 +359,13 @@
         return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
     }
 
-    /* Provides an opportunity for the window manager policy to intercept early
-     * motion event processing when the screen is off since these events are normally
+    /* Provides an opportunity for the window manager policy to intercept early motion event
+     * processing when the device is in a non-interactive state since these events are normally
      * dropped. */
     @Override
-    public int interceptWakeMotionBeforeQueueing(long whenNanos, int policyFlags) {
-        return mService.mPolicy.interceptWakeMotionBeforeQueueing(whenNanos, policyFlags);
+    public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
+        return mService.mPolicy.interceptMotionBeforeQueueingNonInteractive(
+                whenNanos, policyFlags);
     }
 
     /* Provides an opportunity for the window manager policy to process a key before
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 8ed74be..cddca92 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -71,7 +71,7 @@
     jmethodID notifyANR;
     jmethodID filterInputEvent;
     jmethodID interceptKeyBeforeQueueing;
-    jmethodID interceptWakeMotionBeforeQueueing;
+    jmethodID interceptMotionBeforeQueueingNonInteractive;
     jmethodID interceptKeyBeforeDispatching;
     jmethodID dispatchUnhandledKey;
     jmethodID checkInjectEventsPermission;
@@ -854,7 +854,9 @@
 
         handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
     } else {
-        policyFlags |= POLICY_FLAG_PASS_TO_USER;
+        if (mInteractive) {
+            policyFlags |= POLICY_FLAG_PASS_TO_USER;
+        }
     }
 }
 
@@ -870,20 +872,22 @@
     if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
         if (policyFlags & POLICY_FLAG_INTERACTIVE) {
             policyFlags |= POLICY_FLAG_PASS_TO_USER;
-        } else if (policyFlags & POLICY_FLAG_WAKE) {
+        } else {
             JNIEnv* env = jniEnv();
             jint wmActions = env->CallIntMethod(mServiceObj,
-                        gServiceClassInfo.interceptWakeMotionBeforeQueueing,
+                        gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
                         when, policyFlags);
             if (checkAndClearExceptionFromCallback(env,
-                    "interceptWakeMotionBeforeQueueing")) {
+                    "interceptMotionBeforeQueueingNonInteractive")) {
                 wmActions = 0;
             }
 
             handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
         }
     } else {
-        policyFlags |= POLICY_FLAG_PASS_TO_USER;
+        if (mInteractive) {
+            policyFlags |= POLICY_FLAG_PASS_TO_USER;
+        }
     }
 }
 
@@ -1441,8 +1445,8 @@
     GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
             "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");
 
-    GET_METHOD_ID(gServiceClassInfo.interceptWakeMotionBeforeQueueing, clazz,
-            "interceptWakeMotionBeforeQueueing", "(JI)I");
+    GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, clazz,
+            "interceptMotionBeforeQueueingNonInteractive", "(JI)I");
 
     GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
             "interceptKeyBeforeDispatching",