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

Commit dbe3411a authored by Yunfan Chen's avatar Yunfan Chen
Browse files

Use actual navigation bar insets info to determine position

The navigation bar position is currently only used to extend the ime
size when needed and determine whether IME can draw the color of the
navigation bar area. The only usage is to check whether it is at bottom
and the simulated display frame will not need the information.

This change make use of the actual insets size to determine whether the
navigation bar is at bottom and only update the information when the
navigation bar is layout. As the new way won't use the layout params
directly, the mismatch between the layout result and the method will no
longer happen.

Test: 3-button nav on landscape and launch IME. The bar should has
      content.
Test: DisplayPolicyTests
Test: TestDisplayContent
Flag: EXEMPT bugfix
Bug: 372835756
Change-Id: Ie763f164c7072c4a6fdbfbdbce6bdc8df9571b8e
parent 9f054ccb
Loading
Loading
Loading
Loading
+18 −36
Original line number Diff line number Diff line
@@ -65,10 +65,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED;
import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;

import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ANIM;
@@ -109,7 +105,6 @@ import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.InsetsFlags;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource;
@@ -142,7 +137,6 @@ import com.android.internal.view.AppearanceRegion;
import com.android.internal.widget.PointerLocationView;
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.policy.WindowManagerPolicy.NavigationBarPosition;
import com.android.server.policy.WindowManagerPolicy.ScreenOnListener;
import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -263,8 +257,7 @@ public class DisplayPolicy {
    private WindowState mStatusBar = null;
    private volatile WindowState mNotificationShade;
    private WindowState mNavigationBar = null;
    @NavigationBarPosition
    private int mNavigationBarPosition = NAV_BAR_BOTTOM;
    private boolean mHasBottomNavigationBar = true;

    private final ArraySet<WindowState> mInsetsSourceWindowsExceptIme = new ArraySet<>();

@@ -1255,8 +1248,7 @@ public class DisplayPolicy {
                throw new IllegalArgumentException("IME insets must be provided by a window.");
            }

            if (!ENABLE_HIDE_IME_CAPTION_BAR && mNavigationBar != null
                    && navigationBarPosition(displayFrames.mRotation) == NAV_BAR_BOTTOM) {
            if (!ENABLE_HIDE_IME_CAPTION_BAR && mNavigationBar != null && mHasBottomNavigationBar) {
                // In gesture navigation, nav bar frame is larger than frame to calculate insets.
                // IME should not provide frame which is smaller than the nav bar frame. Otherwise,
                // nav bar might be overlapped with the content of the client when IME is shown.
@@ -1469,10 +1461,9 @@ public class DisplayPolicy {
    public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
            WindowState attached, WindowState imeTarget) {
        if (attrs.type == TYPE_NAVIGATION_BAR) {
            // Keep mNavigationBarPosition updated to make sure the transient detection and bar
            // color control is working correctly.
            final DisplayFrames displayFrames = mDisplayContent.mDisplayFrames;
            mNavigationBarPosition = navigationBarPosition(displayFrames.mRotation);
            // Keep mHasBottomNavigationBar updated to make sure the bar color control is working
            // correctly.
            mHasBottomNavigationBar = hasBottomNavigationBar();
        }
        final boolean affectsSystemUi = win.canAffectSystemUiFlags();
        if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi);
@@ -2230,20 +2221,11 @@ public class DisplayPolicy {
        mDisplayContent.mDisplayUpdater.onDisplaySwitching(true);
    }

    @NavigationBarPosition
    int navigationBarPosition(int displayRotation) {
        if (mNavigationBar != null) {
            final int gravity = mNavigationBar.mAttrs.forRotation(displayRotation).gravity;
            switch (gravity) {
                case Gravity.LEFT:
                    return NAV_BAR_LEFT;
                case Gravity.RIGHT:
                    return NAV_BAR_RIGHT;
                default:
                    return NAV_BAR_BOTTOM;
            }
        }
        return NAV_BAR_INVALID;
    boolean hasBottomNavigationBar() {
        Insets navBarInsets = mDisplayContent.getInsetsStateController().getRawInsetsState()
                .calculateInsets(mDisplayContent.mDisplayFrames.mUnrestricted,
                        Type.navigationBars(), true /* ignoreVisibilities */);
        return navBarInsets.bottom > 0;
    }

    /**
@@ -2405,7 +2387,7 @@ public class DisplayPolicy {
            return;
        }
        final WindowState navColorWin = chooseNavigationColorWindowLw(mNavBarColorWindowCandidate,
                mDisplayContent.mInputMethodWindow, mNavigationBarPosition);
                mDisplayContent.mInputMethodWindow, mHasBottomNavigationBar);
        final boolean isNavbarColorManagedByIme =
                navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow;
        final int appearance = updateLightNavigationBarLw(win.mAttrs.insetsFlags.appearance,
@@ -2467,12 +2449,12 @@ public class DisplayPolicy {
    @VisibleForTesting
    @Nullable
    static WindowState chooseNavigationColorWindowLw(WindowState candidate, WindowState imeWindow,
            @NavigationBarPosition int navBarPosition) {
            boolean hasBottomNavigationBar) {
        // If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME
        // window can be navigation color window.
        final boolean imeWindowCanNavColorWindow = imeWindow != null
                && imeWindow.isVisible()
                && navBarPosition == NAV_BAR_BOTTOM
                && hasBottomNavigationBar
                && (imeWindow.mAttrs.flags
                        & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
        if (!imeWindowCanNavColorWindow) {
@@ -2689,7 +2671,7 @@ public class DisplayPolicy {
        final WindowState navBackgroundWin = chooseNavigationBackgroundWindow(
                mNavBarBackgroundWindowCandidate,
                mDisplayContent.mInputMethodWindow,
                mNavigationBarPosition);
                mHasBottomNavigationBar);
        final boolean drawBackground = navBackgroundWin != null
                // There is no app window showing underneath nav bar. (e.g., The screen is locked.)
                // Let system windows (ex: notification shade) draw nav bar background.
@@ -2727,8 +2709,8 @@ public class DisplayPolicy {
    @VisibleForTesting
    @Nullable
    static WindowState chooseNavigationBackgroundWindow(WindowState candidate,
            WindowState imeWindow, @NavigationBarPosition int navBarPosition) {
        if (imeWindow != null && imeWindow.isVisible() && navBarPosition == NAV_BAR_BOTTOM
            WindowState imeWindow, boolean hasBottomNavigationBar) {
        if (imeWindow != null && imeWindow.isVisible() && hasBottomNavigationBar
                && drawsBarBackground(imeWindow)) {
            return imeWindow;
        }
@@ -2906,8 +2888,8 @@ public class DisplayPolicy {
            pw.print(prefix); pw.print("mNavigationBar="); pw.println(mNavigationBar);
            pw.print(prefix); pw.print("mNavBarOpacityMode="); pw.println(mNavBarOpacityMode);
            pw.print(prefix); pw.print("mNavigationBarCanMove="); pw.println(mNavigationBarCanMove);
            pw.print(prefix); pw.print("mNavigationBarPosition=");
            pw.println(mNavigationBarPosition);
            pw.print(prefix); pw.print("mHasBottomNavigationBar=");
            pw.println(mHasBottomNavigationBar);
        }
        if (mLeftGestureHost != null) {
            pw.print(prefix); pw.print("mLeftGestureHost="); pw.println(mLeftGestureHost);
+28 −29
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -141,49 +140,49 @@ public class DisplayPolicyTests extends WindowTestsBase {

        // If everything is null, return null.
        assertNull(null, DisplayPolicy.chooseNavigationColorWindowLw(
                null, null, NAV_BAR_BOTTOM));
                null, null, true));

        // If no IME windows, return candidate window.
        assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
                candidate, null, NAV_BAR_BOTTOM));
                candidate, null, true));
        assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingImTarget, null, NAV_BAR_BOTTOM));
                dimmingImTarget, null, true));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingNonImTarget, null, NAV_BAR_BOTTOM));
                dimmingNonImTarget, null, true));

        // If IME is not visible, return candidate window.
        assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw(
                null, invisibleIme, NAV_BAR_BOTTOM));
                null, invisibleIme, true));
        assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
                candidate, invisibleIme, NAV_BAR_BOTTOM));
                candidate, invisibleIme, true));
        assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingImTarget, invisibleIme, NAV_BAR_BOTTOM));
                dimmingImTarget, invisibleIme, true));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingNonImTarget, invisibleIme, NAV_BAR_BOTTOM));
                dimmingNonImTarget, invisibleIme, true));

        // If IME is visible, return candidate when the candidate window is not dimming.
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
                null, visibleIme, NAV_BAR_BOTTOM));
                null, visibleIme, true));
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
                candidate, visibleIme, NAV_BAR_BOTTOM));
                candidate, visibleIme, true));

        // If IME is visible and the candidate window is dimming, checks whether the dimming window
        // can be IME tartget or not.
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingImTarget, visibleIme, NAV_BAR_BOTTOM));
                dimmingImTarget, visibleIme, true));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));
                dimmingNonImTarget, visibleIme, true));

        // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color
        // window.
        assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw(
                null, imeNonDrawNavBar, NAV_BAR_BOTTOM));
                null, imeNonDrawNavBar, true));
        assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
                candidate, imeNonDrawNavBar, NAV_BAR_BOTTOM));
                candidate, imeNonDrawNavBar, true));
        assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
                dimmingImTarget, imeNonDrawNavBar, true));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
                dimmingNonImTarget, imeNonDrawNavBar, true));
    }

    @Test
@@ -196,32 +195,32 @@ public class DisplayPolicyTests extends WindowTestsBase {
        final WindowState nonDrawBarIme = createInputMethodWindow(true, false, false);

        assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
                drawBarWin, null, NAV_BAR_BOTTOM));
                drawBarWin, null, true));
        assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
                null, null, NAV_BAR_BOTTOM));
                null, null, true));
        assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
                nonDrawBarWin, null, NAV_BAR_BOTTOM));
                nonDrawBarWin, null, true));

        assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
                drawBarWin, visibleIme, NAV_BAR_BOTTOM));
                drawBarWin, visibleIme, true));
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
                null, visibleIme, NAV_BAR_BOTTOM));
                null, visibleIme, true));
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
                nonDrawBarWin, visibleIme, NAV_BAR_BOTTOM));
                nonDrawBarWin, visibleIme, true));

        assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
                drawBarWin, invisibleIme, NAV_BAR_BOTTOM));
                drawBarWin, invisibleIme, true));
        assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
                null, invisibleIme, NAV_BAR_BOTTOM));
                null, invisibleIme, true));
        assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
                nonDrawBarWin, invisibleIme, NAV_BAR_BOTTOM));
                nonDrawBarWin, invisibleIme, true));

        assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
                drawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM));
                drawBarWin, nonDrawBarIme, true));
        assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
                null, nonDrawBarIme, NAV_BAR_BOTTOM));
                null, nonDrawBarIme, true));
        assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
                nonDrawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM));
                nonDrawBarWin, nonDrawBarIme, true));
    }

    @SetupWindows(addWindows = W_NAVIGATION_BAR)
+1 −3
Original line number Diff line number Diff line
@@ -19,11 +19,9 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
import static android.view.Surface.ROTATION_0;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -208,7 +206,7 @@ class TestDisplayContent extends DisplayContent {
            if (mSystemDecorations) {
                doReturn(true).when(newDisplay).supportsSystemDecorations();
                doReturn(true).when(displayPolicy).hasNavigationBar();
                doReturn(NAV_BAR_BOTTOM).when(displayPolicy).navigationBarPosition(anyInt());
                doReturn(true).when(displayPolicy).hasBottomNavigationBar();
            } else {
                doReturn(false).when(displayPolicy).hasNavigationBar();
                doReturn(false).when(displayPolicy).hasStatusBar();