Commit 196e5cf2 authored by Adrian Roos's avatar Adrian Roos Committed by android-build-team Robot

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 3cd5e3d9)
parent b4c5afe8
......@@ -610,6 +610,11 @@ public interface WindowManagerPolicy {
*/
void notifyKeyguardTrustedChanged();
/**
* The keyguard showing state has changed
*/
void onKeyguardShowingAndNotOccludedChanged();
/**
* Notifies the window manager that screen is being turned off.
*
......
......@@ -2150,6 +2150,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void onTrustedChanged() {
mWindowManagerFuncs.notifyKeyguardTrustedChanged();
}
@Override
public void onShowingChanged() {
mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
}
});
}
......
......@@ -86,6 +86,8 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
@Override // Binder interface
public void onShowingStateChanged(boolean showing) {
mIsShowing = showing;
mCallback.onShowingChanged();
}
@Override // Binder interface
......@@ -119,6 +121,7 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
public interface StateCallback {
void onTrustedChanged();
void onShowingChanged();
}
public void dump(String prefix, PrintWriter pw) {
......
......@@ -165,10 +165,18 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
}
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;
}
}
......
......@@ -2928,6 +2928,11 @@ public class WindowManagerService extends IWindowManager.Stub
mH.sendEmptyMessage(H.NOTIFY_KEYGUARD_TRUSTED_CHANGED);
}
@Override
public void onKeyguardShowingAndNotOccludedChanged() {
mH.sendEmptyMessage(H.RECOMPUTE_FOCUS);
}
@Override
public void screenTurningOff(ScreenOffListener listener) {
mTaskSnapshotController.screenTurningOff(listener);
......@@ -4897,6 +4902,7 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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");
......
......@@ -313,6 +313,25 @@ public class DisplayContentTests extends WindowTestsBase {
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.
*/
......
......@@ -63,6 +63,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
private static WindowManagerService sWm = null;
int rotationToReport = 0;
boolean keyguardShowingAndNotOccluded = false;
private Runnable mRunnableWhenAddingSplashScreen;
......@@ -420,7 +421,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public boolean isKeyguardLocked() {
return false;
return keyguardShowingAndNotOccluded;
}
@Override
......@@ -440,7 +441,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public boolean isKeyguardShowingAndNotOccluded() {
return false;
return keyguardShowingAndNotOccluded;
}
@Override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment