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",