Loading services/core/java/com/android/server/wm/DisplayPolicy.java +25 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2379,6 +2381,7 @@ public class DisplayPolicy { mAllowLockscreenWhenOn = false; mShowingDream = false; mWindowSleepTokenNeeded = false; mIsFreeformWindowOverlappingWithNavBar = false; } /** Loading Loading @@ -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() Loading Loading @@ -3458,7 +3468,11 @@ public class DisplayPolicy { } } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { if (mIsFreeformWindowOverlappingWithNavBar) { visibility = setNavBarTranslucentFlag(visibility); } else { visibility = setNavBarOpaqueFlag(visibility); } } else if (fullscreenDrawsBackground) { visibility = setNavBarTransparentFlag(visibility); } Loading Loading @@ -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()); } } services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +36 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } } Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +25 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2379,6 +2381,7 @@ public class DisplayPolicy { mAllowLockscreenWhenOn = false; mShowingDream = false; mWindowSleepTokenNeeded = false; mIsFreeformWindowOverlappingWithNavBar = false; } /** Loading Loading @@ -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() Loading Loading @@ -3458,7 +3468,11 @@ public class DisplayPolicy { } } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { if (mIsFreeformWindowOverlappingWithNavBar) { visibility = setNavBarTranslucentFlag(visibility); } else { visibility = setNavBarOpaqueFlag(visibility); } } else if (fullscreenDrawsBackground) { visibility = setNavBarTransparentFlag(visibility); } Loading Loading @@ -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()); } }
services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +36 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } }