WM: Prevent secondary display focus while keyguard is up
Fixes an issue where input intended for the keyguard could end up going
to a different display.
To prevent this, make sure that only the default display can get focused
when the keyguard is showing.
Change-Id: I6463c44aedca06930d2c9bda7c45ffd93141308c
Merged-In: I6463c44aedca06930d2c9bda7c45ffd93141308c
Fixes: 71786287
Test: atest DisplayContentTests
(cherry picked from commit 3cd5e3d9bbb3255e874b8fa27d7ed506164905dd)
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index c4ffb4c..235e61a 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -611,6 +611,11 @@
void notifyKeyguardTrustedChanged();
/**
+ * The keyguard showing state has changed
+ */
+ void onKeyguardShowingAndNotOccludedChanged();
+
+ /**
* Notifies the window manager that screen is being turned off.
*
* @param listener callback to call when display can be turned off
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index da14c36..d3469c2 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2150,6 +2150,11 @@
public void onTrustedChanged() {
mWindowManagerFuncs.notifyKeyguardTrustedChanged();
}
+
+ @Override
+ public void onShowingChanged() {
+ mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
+ }
});
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 941cd44..fd34c51 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -86,6 +86,8 @@
@Override // Binder interface
public void onShowingStateChanged(boolean showing) {
mIsShowing = showing;
+
+ mCallback.onShowingChanged();
}
@Override // Binder interface
@@ -119,6 +121,7 @@
public interface StateCallback {
void onTrustedChanged();
+ void onShowingChanged();
}
public void dump(String prefix, PrintWriter pw) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a9e56f3..5a75262 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -165,10 +165,18 @@
}
WindowState computeFocusedWindow() {
+ // While the keyguard is showing, we must focus anything besides the main display.
+ // Otherwise we risk input not going to the keyguard when the user expects it to.
+ final boolean forceDefaultDisplay = mService.mPolicy.isKeyguardShowingAndNotOccluded();
+
for (int i = mChildren.size() - 1; i >= 0; i--) {
final DisplayContent dc = mChildren.get(i);
final WindowState win = dc.findFocusedWindow();
if (win != null) {
+ if (forceDefaultDisplay && !dc.isDefaultDisplay) {
+ EventLog.writeEvent(0x534e4554, "71786287", win.mOwnerUid, "");
+ continue;
+ }
return win;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f5cc43b..d378fa3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2929,6 +2929,11 @@
}
@Override
+ public void onKeyguardShowingAndNotOccludedChanged() {
+ mH.sendEmptyMessage(H.RECOMPUTE_FOCUS);
+ }
+
+ @Override
public void screenTurningOff(ScreenOffListener listener) {
mTaskSnapshotController.screenTurningOff(listener);
}
@@ -4897,6 +4902,7 @@
public static final int NOTIFY_KEYGUARD_FLAGS_CHANGED = 56;
public static final int NOTIFY_KEYGUARD_TRUSTED_CHANGED = 57;
public static final int SET_HAS_OVERLAY_UI = 58;
+ public static final int RECOMPUTE_FOCUS = 61;
/**
* Used to denote that an integer field in a message will not be used.
@@ -5363,6 +5369,13 @@
mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1);
}
break;
+ case RECOMPUTE_FOCUS: {
+ synchronized (mWindowMap) {
+ updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
+ true /* updateInputWindows */);
+ }
+ }
+ break;
}
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG_WM, "handleMessage: exit");
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 10d2413..a6cada7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -313,6 +313,25 @@
assertEquals(window1, sWm.mRoot.computeFocusedWindow());
}
+ @Test
+ public void testKeyguard_preventsSecondaryDisplayFocus() throws Exception {
+ final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR,
+ sWm.getDefaultDisplayContentLocked(), "keyguard");
+ assertEquals(keyguard, sWm.mRoot.computeFocusedWindow());
+
+ // Add a window to a second display, and it should be focused
+ final DisplayContent dc = createNewDisplay();
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
+ assertEquals(win, sWm.mRoot.computeFocusedWindow());
+
+ ((TestWindowManagerPolicy)sWm.mPolicy).keyguardShowingAndNotOccluded = true;
+ try {
+ assertEquals(keyguard, sWm.mRoot.computeFocusedWindow());
+ } finally {
+ ((TestWindowManagerPolicy)sWm.mPolicy).keyguardShowingAndNotOccluded = false;
+ }
+ }
+
/**
* This tests setting the maximum ui width on a display.
*/
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index eca27ee..27ea325 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -63,6 +63,7 @@
private static WindowManagerService sWm = null;
int rotationToReport = 0;
+ boolean keyguardShowingAndNotOccluded = false;
private Runnable mRunnableWhenAddingSplashScreen;
@@ -420,7 +421,7 @@
@Override
public boolean isKeyguardLocked() {
- return false;
+ return keyguardShowingAndNotOccluded;
}
@Override
@@ -440,7 +441,7 @@
@Override
public boolean isKeyguardShowingAndNotOccluded() {
- return false;
+ return keyguardShowingAndNotOccluded;
}
@Override