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

Commit 6d0518e9 authored by Vali Calinescu's avatar Vali Calinescu Committed by Android (Google) Code Review
Browse files

Merge "Fix display cutout vertical centering bug" into tm-qpr-dev

parents 4dc75678 c022f353
Loading
Loading
Loading
Loading
+22 −23
Original line number Diff line number Diff line
@@ -8042,11 +8042,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // Horizontal position
        int offsetX = 0;
        if (parentBounds.width() != screenResolvedBounds.width()) {
            if (screenResolvedBounds.width() >= parentAppBounds.width()) {
                // If resolved bounds overlap with insets, center within app bounds.
                offsetX = getCenterOffset(
                        parentAppBounds.width(), screenResolvedBounds.width());
            } else {
            if (screenResolvedBounds.width() <= parentAppBounds.width()) {
                float positionMultiplier =
                        mLetterboxUiController.getHorizontalPositionMultiplier(
                                newParentConfiguration);
@@ -8058,11 +8054,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // Vertical position
        int offsetY = 0;
        if (parentBounds.height() != screenResolvedBounds.height()) {
            if (screenResolvedBounds.height() >= parentAppBounds.height()) {
                // If resolved bounds overlap with insets, center within app bounds.
                offsetY = getCenterOffset(
                        parentAppBounds.height(), screenResolvedBounds.height());
            } else {
            if (screenResolvedBounds.height() <= parentAppBounds.height()) {
                float positionMultiplier =
                        mLetterboxUiController.getVerticalPositionMultiplier(
                                newParentConfiguration);
@@ -8080,6 +8072,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            offsetBounds(resolvedConfig, offsetX, offsetY);
        }

        // If the top is aligned with parentAppBounds add the vertical insets back so that the app
        // content aligns with the status bar
        if (resolvedConfig.windowConfiguration.getAppBounds().top == parentAppBounds.top) {
            resolvedConfig.windowConfiguration.getBounds().top = parentBounds.top;
            if (mSizeCompatBounds != null) {
                mSizeCompatBounds.top = parentBounds.top;
            }
        }

        // Since bounds has changed, the configuration needs to be computed accordingly.
        getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration);
    }
@@ -8803,24 +8804,22 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // Also account for the insets (e.g. display cutouts, navigation bar), which will be
        // clipped away later in {@link Task#computeConfigResourceOverrides()}, i.e., the out
        // bounds are the app bounds restricted by aspect ratio + clippable insets. Otherwise,
        // the app bounds would end up too small.
        // the app bounds would end up too small. To achieve this we will also add clippable insets
        // when the corresponding dimension fully fills the parent

        int right = activityWidth + containingAppBounds.left;
        int left = containingAppBounds.left;
        if (right >= containingAppBounds.right) {
            right += containingBounds.right - containingAppBounds.right;
            right = containingBounds.right;
            left = containingBounds.left;
        }
        int bottom = activityHeight + containingAppBounds.top;
        int top = containingAppBounds.top;
        if (bottom >= containingAppBounds.bottom) {
            bottom += containingBounds.bottom - containingAppBounds.bottom;
            bottom = containingBounds.bottom;
            top = containingBounds.top;
        }
        outBounds.set(containingBounds.left, containingBounds.top, right, bottom);

        // If the bounds are restricted by fixed aspect ratio, then out bounds should be put in the
        // container app bounds. Otherwise the entire container bounds are available.
        if (!outBounds.equals(containingBounds)) {
            // The horizontal position should not cover insets (e.g. display cutout).
            outBounds.left = containingAppBounds.left;
        }

        outBounds.set(left, top, right, bottom);
        return true;
    }

+79 −6
Original line number Diff line number Diff line
@@ -210,10 +210,8 @@ public class SizeCompatTests extends WindowTestsBase {
        assertFitted();

        // After the orientation of activity is changed, the display is rotated, the aspect
        // ratio should be the same (bounds=[100, 0 - 800, 583], appBounds=[100, 0 - 800, 583]).
        // ratio should be the same (bounds=[0, 0 - 800, 583], appBounds=[100, 0 - 800, 583]).
        assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
        // The notch is no longer on top.
        assertEquals(appBounds, mActivity.getBounds());
        // Activity max bounds are sandboxed.
        assertActivityMaxBoundsSandboxed();

@@ -467,8 +465,6 @@ public class SizeCompatTests extends WindowTestsBase {
        assertEquals(ROTATION_270, mTask.getWindowConfiguration().getRotation());

        assertEquals(origBounds.width(), currentBounds.width());
        // The notch is on horizontal side, so current height changes from 1460 to 1400.
        assertEquals(origBounds.height() - notchHeight, currentBounds.height());
        // Make sure the app size is the same
        assertEquals(origAppBounds.width(), appBounds.width());
        assertEquals(origAppBounds.height(), appBounds.height());
@@ -2354,7 +2350,7 @@ public class SizeCompatTests extends WindowTestsBase {
        mActivity.mRootWindowContainer.performSurfacePlacement();

        Rect mBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
        assertEquals(mBounds, new Rect(0, 750, 1000, 1950));
        assertEquals(mBounds, new Rect(0, 900, 1000, 2000));

        DisplayPolicy displayPolicy = mActivity.getDisplayContent().getDisplayPolicy();
        LetterboxDetails[] expectedLetterboxDetails = {new LetterboxDetails(
@@ -2533,6 +2529,64 @@ public class SizeCompatTests extends WindowTestsBase {
        assertEquals(sizeCompatScaled, mActivity.getBounds());
    }

    @Test
    public void testApplyAspectRatio_activityAlignWithParentAppVertical() {
        // The display's app bounds will be (0, 100, 1000, 2350)
        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500)
                .setCanRotate(false)
                .setCutout(0, 100, 0, 150)
                .build();

        setUpApp(display);
        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
        // The activity height is 2100 and the display's app bounds height is 2250, so the activity
        // can be aligned inside parentAppBounds
        assertEquals(mActivity.getBounds(), new Rect(0, 0, 1000, 2200));
    }
    @Test
    public void testApplyAspectRatio_activityCannotAlignWithParentAppVertical() {
        // The display's app bounds will be (0, 100, 1000, 2150)
        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2300)
                .setCanRotate(false)
                .setCutout(0, 100, 0, 150)
                .build();

        setUpApp(display);
        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
        // The activity height is 2100 and the display's app bounds height is 2050, so the activity
        // cannot be aligned inside parentAppBounds and it will fill the parentBounds of the display
        assertEquals(mActivity.getBounds(), display.getBounds());
    }

    @Test
    public void testApplyAspectRatio_activityAlignWithParentAppHorizontal() {
        // The display's app bounds will be (100, 0, 2350, 1000)
        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2500, 1000)
                .setCanRotate(false)
                .setCutout(100, 0, 150, 0)
                .build();

        setUpApp(display);
        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
        // The activity width is 2100 and the display's app bounds width is 2250, so the activity
        // can be aligned inside parentAppBounds
        assertEquals(mActivity.getBounds(), new Rect(175, 0, 2275, 1000));
    }
    @Test
    public void testApplyAspectRatio_activityCannotAlignWithParentAppHorizontal() {
        // The display's app bounds will be (100, 0, 2150, 1000)
        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2300, 1000)
                .setCanRotate(false)
                .setCutout(100, 0, 150, 0)
                .build();

        setUpApp(display);
        prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
        // The activity width is 2100 and the display's app bounds width is 2050, so the activity
        // cannot be aligned inside parentAppBounds and it will fill the parentBounds of the display
        assertEquals(mActivity.getBounds(), display.getBounds());
    }

    @Test
    public void testUpdateResolvedBoundsHorizontalPosition_activityFillParentWidth() {
        // When activity width equals parent width, multiplier shouldn't have any effect.
@@ -2608,6 +2662,25 @@ public class SizeCompatTests extends WindowTestsBase {
                /* sizeCompatScaled */ new Rect(0, 1050, 700, 1400));
    }

    @Test
    public void testUpdateResolvedBoundsPosition_alignToTop() {
        final int notchHeight = 100;
        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2800)
                .setNotch(notchHeight)
                .build();
        setUpApp(display);

        // Prepare unresizable activity with max aspect ratio
        prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED);

        Rect mBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
        Rect appBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
        // The insets should be cut for aspect ratio and then added back because the appBounds
        // are aligned to the top of the parentAppBounds
        assertEquals(mBounds, new Rect(0, 0, 1000, 1200));
        assertEquals(appBounds, new Rect(0, notchHeight, 1000, 1200));
    }

    private void assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
            float letterboxVerticalPositionMultiplier, Rect fixedOrientationLetterbox,
            Rect sizeCompatUnscaled, Rect sizeCompatScaled) {
+15 −2
Original line number Diff line number Diff line
@@ -143,11 +143,24 @@ class TestDisplayContent extends DisplayContent {
            mInfo.ownerUid = ownerUid;
            return this;
        }
        Builder setNotch(int height) {
        Builder setCutout(int left, int top, int right, int bottom) {
            final int cutoutFillerSize = 80;
            Rect boundLeft = left != 0 ? new Rect(0, 0, left, cutoutFillerSize) : null;
            Rect boundTop = top != 0 ? new Rect(0, 0, cutoutFillerSize, top) : null;
            Rect boundRight = right != 0 ? new Rect(mInfo.logicalWidth - right, 0,
                    mInfo.logicalWidth, cutoutFillerSize) : null;
            Rect boundBottom = bottom != 0
                    ? new Rect(0, mInfo.logicalHeight - bottom, cutoutFillerSize,
                    mInfo.logicalHeight) : null;

            mInfo.displayCutout = new DisplayCutout(
                    Insets.of(0, height, 0, 0), null, new Rect(20, 0, 80, height), null, null);
                    Insets.of(left, top, right, bottom),
                    boundLeft, boundTop, boundRight, boundBottom);
            return this;
        }
        Builder setNotch(int height) {
            return setCutout(0, height, 0, 0);
        }
        Builder setStatusBarHeight(int height) {
            mStatusBarHeight = height;
            return this;