From 28635b9391f527685b2ccff62afd7b4fa59a45e3 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Fri, 30 Oct 2020 16:19:04 +0800 Subject: [PATCH] Don't let fullscreen app window hide status bar... ... when notification shade can receive keys. If notification shade is the focused window, we won't let the top fullscreen app to hide status bar. If there is a focused window on top of the focusable notification shade, we should keep preventing the top fullscreen app from controlling status bar. Fix: 171223838 Test: atest InsetsPolicyTest Change-Id: I6d61e3936cb273a8f4dd8546334f751f3a86f4b8 --- .../com/android/server/wm/InsetsPolicy.java | 8 +++-- .../android/server/wm/InsetsPolicyTest.java | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index a2b9cf9c5b3c3..73641f4d76ac8 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -287,7 +287,8 @@ class InsetsPolicy { if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) { return mDummyControlTarget; } - if (focusedWin == mPolicy.getNotificationShade()) { + final WindowState notificationShade = mPolicy.getNotificationShade(); + if (focusedWin == notificationShade) { // Notification shade has control anyways, no reason to force anything. return focusedWin; } @@ -308,9 +309,10 @@ class InsetsPolicy { // fake control to the client, so that it can re-show the bar during this scenario. return mDummyControlTarget; } - if (!canBeTopFullscreenOpaqueWindow(focusedWin) && mPolicy.topAppHidesStatusBar()) { + if (!canBeTopFullscreenOpaqueWindow(focusedWin) && mPolicy.topAppHidesStatusBar() + && (notificationShade == null || !notificationShade.canReceiveKeys())) { // Non-fullscreen focused window should not break the state that the top-fullscreen-app - // window hides status bar. + // window hides status bar, unless the notification shade can receive keys. return mPolicy.getTopFullscreenOpaqueWindow(); } return focusedWin; diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index a1606d3502adb..6b10a336628c6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -29,6 +29,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -226,6 +227,40 @@ public class InsetsPolicyTest extends WindowTestsBase { // mTopFullscreenOpaqueWindowState is still fullscreenApp. verify(sbmi).setWindowState(mDisplayContent.mDisplayId, StatusBarManager.WINDOW_STATUS_BAR, StatusBarManager.WINDOW_STATE_SHOWING); + + // Add a system window: panel. + final WindowState panel = addWindow(TYPE_STATUS_BAR_SUB_PANEL, "panel"); + mDisplayContent.getInsetsPolicy().updateBarControlTarget(panel); + + // panel is the focused window, but it can only control navigation bar. + // Because fullscreenApp is hiding status bar. + InsetsSourceControl[] panelControls = + mDisplayContent.getInsetsStateController().getControlsForDispatch(panel); + assertNotNull(panelControls); + assertEquals(1, panelControls.length); + assertEquals(ITYPE_NAVIGATION_BAR, panelControls[0].getType()); + + // Add notificationShade and make it can receive keys. + final WindowState shade = addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade"); + shade.setHasSurface(true); + assertTrue(shade.canReceiveKeys()); + mDisplayContent.getInsetsPolicy().updateBarControlTarget(panel); + + // panel can control both system bars now. + panelControls = mDisplayContent.getInsetsStateController().getControlsForDispatch(panel); + assertNotNull(panelControls); + assertEquals(2, panelControls.length); + + // Make notificationShade cannot receive keys. + shade.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + assertFalse(shade.canReceiveKeys()); + mDisplayContent.getInsetsPolicy().updateBarControlTarget(panel); + + // panel can only control navigation bar now. + panelControls = mDisplayContent.getInsetsStateController().getControlsForDispatch(panel); + assertNotNull(panelControls); + assertEquals(1, panelControls.length); + assertEquals(ITYPE_NAVIGATION_BAR, panelControls[0].getType()); } @UseTestDisplay(addWindows = W_ACTIVITY)