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

Commit c9889ea6 authored by chaviw's avatar chaviw
Browse files

Use WC bounds for insets calculation

When computing insets based on navigation bar and status bar, use the
window's bounds instead of display bounds to ensure it compenstates for
the display area. The system bars should use their bounds to ensure
they aren't creating insets outside the display area. The window bounds
are also used when calculating the size and placement of the system
bars.

Bug: 156676090
Test: DisplayPolicyLayoutTests
Test: DisplayPolicyInsetsTests
Test: InsetsPolicyTest
Test: InsetsSourceProviderTest
Test: InsetsStateControllerTest
Change-Id: I9a3481fcd0146463c10077967b49bf46190f7946
parent 85cac3bc
Loading
Loading
Loading
Loading
+24 −25
Original line number Diff line number Diff line
@@ -1037,8 +1037,8 @@ public class DisplayPolicy {
                mStatusBarController.setWindow(win);
                final TriConsumer<DisplayFrames, WindowState, Rect> frameProvider =
                        (displayFrames, windowState, rect) -> {
                            rect.top = 0;
                            rect.bottom = getStatusBarHeight(displayFrames);
                            rect.set(windowState.getFrameLw());
                            rect.bottom = rect.top + getStatusBarHeight(displayFrames);
                        };
                mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, win, frameProvider);
                mDisplayContent.setInsetProvider(ITYPE_TOP_GESTURES, win, frameProvider);
@@ -1058,8 +1058,7 @@ public class DisplayPolicy {
                                    displayFrames.mDisplayHeight,
                                    displayFrames.mRotation) == NAV_BAR_BOTTOM
                                    && !mNavButtonForcedVisible) {

                                sTmpRect.set(displayFrames.mUnrestricted);
                                sTmpRect.set(windowState.getFrameLw());
                                sTmpRect.intersectUnchecked(displayFrames.mDisplayCutoutSafe);
                                inOutFrame.top = sTmpRect.bottom
                                        - getNavigationBarHeight(displayFrames.mRotation,
@@ -1687,12 +1686,11 @@ public class DisplayPolicy {
            if (isSimulatedLayout) {
                w.setSimulatedWindowFrames(simulatedFrames);
            }
            Rect bounds = w.getBounds();
            final WindowFrames windowFrames = w.getLayoutingWindowFrames();
            windowFrames.setFrames(displayFrames.mUnrestricted /* parentFrame */,
                    displayFrames.mUnrestricted /* displayFrame */,
                    displayFrames.mUnrestricted /* contentFrame */,
                    displayFrames.mUnrestricted /* visibleFrame */, sTmpRect /* decorFrame */,
                    displayFrames.mUnrestricted /* stableFrame */);
            windowFrames.setFrames(bounds /* parentFrame */, bounds /* displayFrame */,
                    bounds /* contentFrame */, bounds /* visibleFrame */, sTmpRect /* decorFrame */,
                    bounds /* stableFrame */);
            try {
                w.computeFrame(displayFrames);
            } finally {
@@ -1749,14 +1747,13 @@ public class DisplayPolicy {
        if (mStatusBar == null) {
            return false;
        }
        // apply any navigation bar insets
        // apply any status bar insets
        Rect bounds = mStatusBar.getBounds();
        sTmpRect.setEmpty();
        final WindowFrames windowFrames = mStatusBar.getLayoutingWindowFrames();
        windowFrames.setFrames(displayFrames.mUnrestricted /* parentFrame */,
                displayFrames.mUnrestricted /* displayFrame */,
                displayFrames.mStable /* contentFrame */,
                displayFrames.mStable /* visibleFrame */, sTmpRect /* decorFrame */,
                displayFrames.mStable /* stableFrame */);
        windowFrames.setFrames(bounds /* parentFrame */, bounds /* displayFrame */,
                bounds /* contentFrame */, bounds /* visibleFrame */, sTmpRect /* decorFrame */,
                bounds /* stableFrame */);
        // Let the status bar determine its size.
        mStatusBar.computeFrame(displayFrames);

@@ -1827,18 +1824,20 @@ public class DisplayPolicy {
        final Rect dockFrame = displayFrames.mDock;
        final int navBarPosition = navigationBarPosition(displayWidth, displayHeight, rotation);

        navigationFrame.set(mNavigationBar.getBounds());

        final Rect cutoutSafeUnrestricted = sTmpRect;
        cutoutSafeUnrestricted.set(displayFrames.mUnrestricted);
        cutoutSafeUnrestricted.intersectUnchecked(displayFrames.mDisplayCutoutSafe);

        if (navBarPosition == NAV_BAR_BOTTOM) {
            // It's a system nav bar or a portrait screen; nav bar goes on bottom.
            final int topNavBar = cutoutSafeUnrestricted.bottom
            final int topNavBar = Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom)
                    - getNavigationBarFrameHeight(rotation, uiMode);
            final int top = mNavButtonForcedVisible
                    ? topNavBar
                    : cutoutSafeUnrestricted.bottom - getNavigationBarHeight(rotation, uiMode);
            navigationFrame.set(0, topNavBar, displayWidth, displayFrames.mUnrestricted.bottom);
            final int top = mNavButtonForcedVisible ? topNavBar :
                    Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom)
                            - getNavigationBarHeight(rotation, uiMode);
            navigationFrame.top = topNavBar;
            displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top;
            if (transientNavBarShowing) {
                mNavigationBarController.setBarShowingLw(true);
@@ -1858,9 +1857,9 @@ public class DisplayPolicy {
            }
        } else if (navBarPosition == NAV_BAR_RIGHT) {
            // Landscape screen; nav bar goes to the right.
            final int left = cutoutSafeUnrestricted.right
            final int left = Math.min(cutoutSafeUnrestricted.right, navigationFrame.right)
                    - getNavigationBarWidth(rotation, uiMode);
            navigationFrame.set(left, 0, displayFrames.mUnrestricted.right, displayHeight);
            navigationFrame.left = left;
            displayFrames.mStable.right = displayFrames.mStableFullscreen.right = left;
            if (transientNavBarShowing) {
                mNavigationBarController.setBarShowingLw(true);
@@ -1880,9 +1879,9 @@ public class DisplayPolicy {
            }
        } else if (navBarPosition == NAV_BAR_LEFT) {
            // Seascape screen; nav bar goes to the left.
            final int right = cutoutSafeUnrestricted.left
            final int right = Math.max(cutoutSafeUnrestricted.left, navigationFrame.left)
                    + getNavigationBarWidth(rotation, uiMode);
            navigationFrame.set(displayFrames.mUnrestricted.left, 0, right, displayHeight);
            navigationFrame.right = right;
            displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right;
            if (transientNavBarShowing) {
                mNavigationBarController.setBarShowingLw(true);
@@ -2065,7 +2064,7 @@ public class DisplayPolicy {
            final @InsetsType int typesToFit = attrs.getFitInsetsTypes();
            final @InsetsSide int sidesToFit = attrs.getFitInsetsSides();
            final ArraySet<Integer> types = InsetsState.toInternalType(typesToFit);
            final Rect dfu = displayFrames.mUnrestricted;
            final Rect dfu = win.getBounds();
            Insets insets = Insets.of(0, 0, 0, 0);
            for (int i = types.size() - 1; i >= 0; i--) {
                final InsetsSource source = mDisplayContent.getInsetsPolicy()
+4 −1
Original line number Diff line number Diff line
@@ -462,7 +462,10 @@ class InsetsSourceProvider {

            mCapturedLeash = animationLeash;
            final Rect frame = mWin.getWindowFrames().mFrame;
            t.setPosition(mCapturedLeash, frame.left, frame.top);
            Point position = new Point();
            mWin.transformFrameToSurfacePosition(frame.left, frame.top, position);

            t.setPosition(mCapturedLeash, position.x, position.y);
        }

        @Override
+1 −1
Original line number Diff line number Diff line
@@ -5387,7 +5387,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        }
    }

    private void transformFrameToSurfacePosition(int left, int top, Point outPoint) {
    void transformFrameToSurfacePosition(int left, int top, Point outPoint) {
        outPoint.set(left, top);

        // If changed, also adjust getTransformationMatrix
+26 −1
Original line number Diff line number Diff line
@@ -43,11 +43,15 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.testng.Assert.expectThrows;

@@ -61,6 +65,7 @@ import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.InsetsState;
import android.view.View;
import android.view.WindowInsets.Side;
import android.view.WindowInsets.Type;
import android.view.WindowManager;
@@ -95,6 +100,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
    private boolean mIsLongEdgeDisplayCutout;
    private static final int DECOR_WINDOW_INSET = 50;

    private final Rect mDisplayBounds = new Rect();

    @Before
    public void setUp() throws Exception {
        mWindow = spy(createWindow(null, TYPE_APPLICATION, "window"));
@@ -107,6 +114,15 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
        attrs.height = MATCH_PARENT;
        attrs.format = PixelFormat.TRANSLUCENT;

        spyOn(mStatusBarWindow);
        spyOn(mNavBarWindow);

        // Disabling this call for most tests since it can override the systemUiFlags when called.
        doReturn(0).when(mDisplayPolicy).updateSystemUiVisibilityLw();

        mDisplayPolicy.mLastSystemUiFlags |= View.STATUS_BAR_TRANSPARENT;
        mDisplayPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;

        updateDisplayFrames();
    }

@@ -128,7 +144,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {

    private void updateDisplayFrames() {
        mFrames = createDisplayFrames();
        mDisplayBounds.set(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight);
        mDisplayContent.mDisplayFrames = mFrames;

        doReturn(mDisplayBounds).when(mStatusBarWindow).getBounds();
        doReturn(mDisplayBounds).when(mNavBarWindow).getBounds();
        doReturn(mDisplayBounds).when(mWindow).getBounds();
    }

    private DisplayFrames createDisplayFrames() {
@@ -808,6 +829,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {

    @Test
    public void forceShowSystemBars_clearsSystemUIFlags() {
        doCallRealMethod().when(mDisplayPolicy).updateSystemUiVisibilityLw();
        mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN;
        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        mWindow.mAttrs.flags =
@@ -829,12 +851,15 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {

    @Test
    public void testScreenDecorWindows() {
        final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow");
        final WindowState decorWindow = spy(
                createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow"));
        mWindow.mAttrs.flags = FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR
                | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR;
        addWindow(decorWindow);
        addWindow(mWindow);
        doReturn(new Rect(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight))
                .when(decorWindow).getBounds();

        // Decor on top
        updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP);
+3 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;

import static org.junit.Assert.assertEquals;
@@ -68,7 +68,8 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {

    @Before
    public void setUpDisplayPolicy() {
        mDisplayPolicy = spy(mDisplayContent.getDisplayPolicy());
        mDisplayPolicy = mDisplayContent.getDisplayPolicy();
        spyOn(mDisplayPolicy);

        final TestContextWrapper context = new TestContextWrapper(
                mDisplayPolicy.getContext(), mDisplayPolicy.getCurrentUserResources());