From 22d3ec2bbc526616eaac0bd5733f0de68c7ad3ea Mon Sep 17 00:00:00 2001 From: HEO SEUNG Date: Thu, 30 May 2019 20:28:53 +0900 Subject: [PATCH] [wm]: Make the navigation bar in translucent mode when overlapping with freeform If you move a freeform window to the navigation bar, there was no response. So If the freeform window overlaps with the navigation bar area to show that it overlaps, set the navigation bar display in translucent mode. Test: Manual - Move a freeform window to the navigation bar Test: atest WmTests:DisplayPolicyTests Bug: 129522556 Change-Id: I74df3bb499f9c946593c2aad4bbcf33587413bc9 (cherry picked from commit df95599de4792dd5381f8d4a663eb6060fb237bc) --- .../com/android/server/wm/DisplayPolicy.java | 26 +++++++++++++- .../android/server/wm/DisplayPolicyTests.java | 36 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index cf87203893cf3..61ba69fdf4047 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -284,6 +284,8 @@ public class DisplayPolicy { /** See {@link #getNavigationBarFrameHeight} */ private int[] mNavigationBarFrameHeightForRotationDefault = new int[4]; + private boolean mIsFreeformWindowOverlappingWithNavBar; + /** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */ @Px private int mWindowOutsetBottom; @@ -2379,6 +2381,7 @@ public class DisplayPolicy { mAllowLockscreenWhenOn = false; mShowingDream = false; mWindowSleepTokenNeeded = false; + mIsFreeformWindowOverlappingWithNavBar = false; } /** @@ -2478,6 +2481,13 @@ public class DisplayPolicy { } } + // Check if the freeform window overlaps with the navigation bar area. + final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null; + if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode() + && isOverlappingWithNavBar(win, navBarWin)) { + mIsFreeformWindowOverlappingWithNavBar = true; + } + // Also keep track of any windows that are dimming but not necessarily fullscreen in the // docked stack. if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming() @@ -3458,7 +3468,11 @@ public class DisplayPolicy { } } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { - visibility = setNavBarOpaqueFlag(visibility); + if (mIsFreeformWindowOverlappingWithNavBar) { + visibility = setNavBarTranslucentFlag(visibility); + } else { + visibility = setNavBarOpaqueFlag(visibility); + } } else if (fullscreenDrawsBackground) { visibility = setNavBarTransparentFlag(visibility); } @@ -3747,4 +3761,14 @@ public class DisplayPolicy { wm.removeView(mPointerLocationView); mPointerLocationView = null; } + + @VisibleForTesting + static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) { + if (navBarWindow == null || !navBarWindow.isVisibleLw() + || targetWindow.mAppToken == null || !targetWindow.isVisibleLw()) { + return false; + } + + return Rect.intersects(targetWindow.getFrameLw(), navBarWindow.getFrameLw()); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index 1684f97d28e33..6a3c81ab73bce 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -32,6 +32,7 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLES import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; +import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -49,10 +50,12 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.graphics.PixelFormat; +import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.Surface; import android.view.WindowManager; +import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.Test; @@ -273,4 +276,37 @@ public class DisplayPolicyTests extends WindowTestsBase { win.mHasSurface = true; return win; } + + @Test + @FlakyTest(bugId = 131005232) + public void testOverlappingWithNavBar() { + final WindowState targetWin = createApplicationWindow(); + final WindowFrames winFrame = targetWin.getWindowFrames(); + winFrame.mFrame.set(new Rect(100, 100, 200, 200)); + + final WindowState navigationBar = createNavigationBarWindow(); + + navigationBar.getFrameLw().set(new Rect(100, 200, 200, 300)); + + assertFalse("Freeform is overlapping with navigation bar", + DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); + + winFrame.mFrame.set(new Rect(100, 101, 200, 201)); + assertTrue("Freeform should be overlapping with navigation bar (bottom)", + DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); + + winFrame.mFrame.set(new Rect(99, 200, 199, 300)); + assertTrue("Freeform should be overlapping with navigation bar (right)", + DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); + + winFrame.mFrame.set(new Rect(199, 200, 299, 300)); + assertTrue("Freeform should be overlapping with navigation bar (left)", + DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); + } + + private WindowState createNavigationBarWindow() { + final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar"); + win.mHasSurface = true; + return win; + } }