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

Commit 4dbbd9c5 authored by Winson Chung's avatar Winson Chung
Browse files

Account for extra nav bar when checking nav bar appearance

Bug: 206170580
Test: Set light-bar flags in Launcher w/ Taskbar, ensure they are
      reflected in the data sent back to SysUI
Test: atest DisplayPolicyTests
Change-Id: I75618fca238c77a9e6ae0f2df37a9e017e8be69f
parent ddd87bf8
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() {