Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ffe736c2 authored by Winson Chung's avatar Winson Chung Committed by Automerger Merge Worker
Browse files

Merge "Account for extra nav bar when checking nav bar appearance" into sc-v2-dev am: cdb9e71c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16251878

Change-Id: I7a9eb5bf53d841c94b09a6bd254946675aab0bfd
parents b710176a cdb9e71c
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
    }
@@ -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;
@@ -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) {
@@ -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;
    }

    /**
+19 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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() {