Loading services/core/java/com/android/server/wm/DisplayPolicy.java +30 −13 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ import android.os.Message; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArraySet; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -1908,7 +1909,7 @@ public class DisplayPolicy { applyKeyguardPolicy(win, imeTarget); // Check if the freeform window overlaps with the navigation bar area. final boolean isOverlappingWithNavBar = isOverlappingWithNavBar(win, mNavigationBar); final boolean isOverlappingWithNavBar = isOverlappingWithNavBar(win); if (isOverlappingWithNavBar && !mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()) { mIsFreeformWindowOverlappingWithNavBar = true; Loading Loading @@ -2770,7 +2771,7 @@ public class DisplayPolicy { private int getStatusBarAppearance(WindowState opaque, WindowState opaqueOrDimming) { final boolean onKeyguard = isKeyguardShowing() && !isKeyguardOccluded(); final WindowState colorWin = onKeyguard ? mNotificationShade : opaqueOrDimming; return isLightBarAllowed(colorWin, ITYPE_STATUS_BAR) && (colorWin == opaque || onKeyguard) return isLightBarAllowed(colorWin, Type.statusBars()) && (colorWin == opaque || onKeyguard) ? (colorWin.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_STATUS_BARS) : 0; } Loading Loading @@ -2818,7 +2819,7 @@ public class DisplayPolicy { @VisibleForTesting int updateLightNavigationBarLw(int appearance, WindowState navColorWin) { if (navColorWin == null || navColorWin.isDimming() || !isLightBarAllowed(navColorWin, ITYPE_NAVIGATION_BAR)) { || !isLightBarAllowed(navColorWin, Type.navigationBars())) { // Clear the light flag while not allowed. appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; return appearance; Loading Loading @@ -2883,12 +2884,11 @@ public class DisplayPolicy { return appearance; } private boolean isLightBarAllowed(WindowState win, @InternalInsetsType int type) { private static boolean isLightBarAllowed(WindowState win, @InsetsType int type) { if (win == null) { return false; } final InsetsSource source = win.getInsetsState().peekSource(type); return source != null && Rect.intersects(win.getFrame(), source.getFrame()); return intersectsAnyInsets(win.getFrame(), win.getInsetsState(), type); } private Rect getBarContentFrameForWindow(WindowState win, int windowType) { Loading Loading @@ -3268,17 +3268,34 @@ public class DisplayPolicy { } @VisibleForTesting static boolean isOverlappingWithNavBar(@NonNull WindowState targetWindow, WindowState navBarWindow) { if (navBarWindow == null || !navBarWindow.isVisible() || targetWindow.mActivityRecord == null || !targetWindow.isVisible()) { static boolean isOverlappingWithNavBar(@NonNull WindowState win) { if (win.mActivityRecord == null || !win.isVisible()) { return false; } // When the window is dimming means it's requesting dim layer to its host container, so // checking whether it's overlapping with navigation bar by its container's bounds. return Rect.intersects(targetWindow.isDimming() ? targetWindow.getBounds() : targetWindow.getFrame(), navBarWindow.getFrame()); // checking whether it's overlapping with a navigation bar by its container's bounds. return intersectsAnyInsets(win.isDimming() ? win.getBounds() : win.getFrame(), win.getInsetsState(), Type.navigationBars()); } /** * Returns whether the given {@param bounds} intersects with any insets of the * provided {@param insetsType}. */ private static boolean intersectsAnyInsets(Rect bounds, InsetsState insetsState, @InsetsType int insetsType) { final ArraySet<Integer> internalTypes = InsetsState.toInternalType(insetsType); for (int i = 0; i < internalTypes.size(); i++) { final InsetsSource source = insetsState.peekSource(internalTypes.valueAt(i)); if (source == null || !source.isVisible()) { continue; } if (Rect.intersects(bounds, source.getFrame())) { return true; } } return false; } /** Loading services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +19 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.RoundedCorners.NO_ROUNDED_CORNERS; Loading Loading @@ -251,28 +252,38 @@ public class DisplayPolicyTests extends WindowTestsBase { @Test public void testOverlappingWithNavBar() { final InsetsSource navSource = new InsetsSource(ITYPE_NAVIGATION_BAR); navSource.setFrame(new Rect(100, 200, 200, 300)); testOverlappingWithNavBarType(navSource); } @Test public void testOverlappingWithExtraNavBar() { final InsetsSource navSource = new InsetsSource(ITYPE_EXTRA_NAVIGATION_BAR); navSource.setFrame(new Rect(100, 200, 200, 300)); testOverlappingWithNavBarType(navSource); } private void testOverlappingWithNavBarType(InsetsSource navSource) { final WindowState targetWin = createApplicationWindow(); final WindowFrames winFrame = targetWin.getWindowFrames(); winFrame.mFrame.set(new Rect(100, 100, 200, 200)); final WindowState navigationBar = createNavigationBarWindow(); navigationBar.getFrame().set(new Rect(100, 200, 200, 300)); targetWin.mAboveInsetsState.addSource(navSource); assertFalse("Freeform is overlapping with navigation bar", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); winFrame.mFrame.set(new Rect(100, 101, 200, 201)); assertTrue("Freeform should be overlapping with navigation bar (bottom)", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); winFrame.mFrame.set(new Rect(99, 200, 199, 300)); assertTrue("Freeform should be overlapping with navigation bar (right)", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); winFrame.mFrame.set(new Rect(199, 200, 299, 300)); assertTrue("Freeform should be overlapping with navigation bar (left)", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); } private WindowState createNavigationBarWindow() { Loading Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +30 −13 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ import android.os.Message; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArraySet; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -1908,7 +1909,7 @@ public class DisplayPolicy { applyKeyguardPolicy(win, imeTarget); // Check if the freeform window overlaps with the navigation bar area. final boolean isOverlappingWithNavBar = isOverlappingWithNavBar(win, mNavigationBar); final boolean isOverlappingWithNavBar = isOverlappingWithNavBar(win); if (isOverlappingWithNavBar && !mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()) { mIsFreeformWindowOverlappingWithNavBar = true; Loading Loading @@ -2770,7 +2771,7 @@ public class DisplayPolicy { private int getStatusBarAppearance(WindowState opaque, WindowState opaqueOrDimming) { final boolean onKeyguard = isKeyguardShowing() && !isKeyguardOccluded(); final WindowState colorWin = onKeyguard ? mNotificationShade : opaqueOrDimming; return isLightBarAllowed(colorWin, ITYPE_STATUS_BAR) && (colorWin == opaque || onKeyguard) return isLightBarAllowed(colorWin, Type.statusBars()) && (colorWin == opaque || onKeyguard) ? (colorWin.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_STATUS_BARS) : 0; } Loading Loading @@ -2818,7 +2819,7 @@ public class DisplayPolicy { @VisibleForTesting int updateLightNavigationBarLw(int appearance, WindowState navColorWin) { if (navColorWin == null || navColorWin.isDimming() || !isLightBarAllowed(navColorWin, ITYPE_NAVIGATION_BAR)) { || !isLightBarAllowed(navColorWin, Type.navigationBars())) { // Clear the light flag while not allowed. appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; return appearance; Loading Loading @@ -2883,12 +2884,11 @@ public class DisplayPolicy { return appearance; } private boolean isLightBarAllowed(WindowState win, @InternalInsetsType int type) { private static boolean isLightBarAllowed(WindowState win, @InsetsType int type) { if (win == null) { return false; } final InsetsSource source = win.getInsetsState().peekSource(type); return source != null && Rect.intersects(win.getFrame(), source.getFrame()); return intersectsAnyInsets(win.getFrame(), win.getInsetsState(), type); } private Rect getBarContentFrameForWindow(WindowState win, int windowType) { Loading Loading @@ -3268,17 +3268,34 @@ public class DisplayPolicy { } @VisibleForTesting static boolean isOverlappingWithNavBar(@NonNull WindowState targetWindow, WindowState navBarWindow) { if (navBarWindow == null || !navBarWindow.isVisible() || targetWindow.mActivityRecord == null || !targetWindow.isVisible()) { static boolean isOverlappingWithNavBar(@NonNull WindowState win) { if (win.mActivityRecord == null || !win.isVisible()) { return false; } // When the window is dimming means it's requesting dim layer to its host container, so // checking whether it's overlapping with navigation bar by its container's bounds. return Rect.intersects(targetWindow.isDimming() ? targetWindow.getBounds() : targetWindow.getFrame(), navBarWindow.getFrame()); // checking whether it's overlapping with a navigation bar by its container's bounds. return intersectsAnyInsets(win.isDimming() ? win.getBounds() : win.getFrame(), win.getInsetsState(), Type.navigationBars()); } /** * Returns whether the given {@param bounds} intersects with any insets of the * provided {@param insetsType}. */ private static boolean intersectsAnyInsets(Rect bounds, InsetsState insetsState, @InsetsType int insetsType) { final ArraySet<Integer> internalTypes = InsetsState.toInternalType(insetsType); for (int i = 0; i < internalTypes.size(); i++) { final InsetsSource source = insetsState.peekSource(internalTypes.valueAt(i)); if (source == null || !source.isVisible()) { continue; } if (Rect.intersects(bounds, source.getFrame())) { return true; } } return false; } /** Loading
services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +19 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.RoundedCorners.NO_ROUNDED_CORNERS; Loading Loading @@ -251,28 +252,38 @@ public class DisplayPolicyTests extends WindowTestsBase { @Test public void testOverlappingWithNavBar() { final InsetsSource navSource = new InsetsSource(ITYPE_NAVIGATION_BAR); navSource.setFrame(new Rect(100, 200, 200, 300)); testOverlappingWithNavBarType(navSource); } @Test public void testOverlappingWithExtraNavBar() { final InsetsSource navSource = new InsetsSource(ITYPE_EXTRA_NAVIGATION_BAR); navSource.setFrame(new Rect(100, 200, 200, 300)); testOverlappingWithNavBarType(navSource); } private void testOverlappingWithNavBarType(InsetsSource navSource) { final WindowState targetWin = createApplicationWindow(); final WindowFrames winFrame = targetWin.getWindowFrames(); winFrame.mFrame.set(new Rect(100, 100, 200, 200)); final WindowState navigationBar = createNavigationBarWindow(); navigationBar.getFrame().set(new Rect(100, 200, 200, 300)); targetWin.mAboveInsetsState.addSource(navSource); assertFalse("Freeform is overlapping with navigation bar", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); winFrame.mFrame.set(new Rect(100, 101, 200, 201)); assertTrue("Freeform should be overlapping with navigation bar (bottom)", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); winFrame.mFrame.set(new Rect(99, 200, 199, 300)); assertTrue("Freeform should be overlapping with navigation bar (right)", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); winFrame.mFrame.set(new Rect(199, 200, 299, 300)); assertTrue("Freeform should be overlapping with navigation bar (left)", DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar)); DisplayPolicy.isOverlappingWithNavBar(targetWin)); } private WindowState createNavigationBarWindow() { Loading