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

Commit 1f931a59 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Respect parent bounds if it can contain the override bounds

The parent configuration may have been transformed (fixed rotation),
in that case the override bounds should be able to fit in the given
parent bounds. Besides, the rotation of task display area is different
than the override bounds. So parent app bounds should be still chosen
as the container area.

Fixes: 154699350
Test: atest AspectRatioTests#testMinAspectLandscapeActivity
            TaskRecordTests#testComputeConfigResourceOverrides
Change-Id: Iaf5c1f838d2c51c6c0175b5e6e947e6690ed9cf3
parent e91800d2
Loading
Loading
Loading
Loading
+25 −23
Original line number Diff line number Diff line
@@ -2285,16 +2285,18 @@ class Task extends WindowContainer<WindowContainer> {
        }
        density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;

        // If bounds have been overridden at this level, restrict config resources to these bounds
        // rather than the parent because the overridden bounds can be larger than the parent.
        boolean hasOverrideBounds = false;
        // The bounds may have been overridden at this level. If the parent cannot cover these
        // bounds, the configuration is still computed according to the override bounds.
        final boolean insideParentBounds;

        final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
        final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds();
        if (resolvedBounds == null || resolvedBounds.isEmpty()) {
            mTmpFullBounds.set(parentConfig.windowConfiguration.getBounds());
            mTmpFullBounds.set(parentBounds);
            insideParentBounds = true;
        } else {
            mTmpFullBounds.set(resolvedBounds);
            hasOverrideBounds = true;
            insideParentBounds = parentBounds.contains(resolvedBounds);
        }

        Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
@@ -2303,30 +2305,30 @@ class Task extends WindowContainer<WindowContainer> {
            outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
        }
        // Non-null compatibility insets means the activity prefers to keep its original size, so
        // the out bounds doesn't need to be restricted by the parent.
        final boolean insideParentBounds = compatInsets == null;
        if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) {
            Rect parentAppBounds;
            if (hasOverrideBounds) {
                // Since we overrode the bounds, restrict appBounds to display non-decor rather
                // than parent. Otherwise, it won't match the overridden bounds.
                final TaskDisplayArea displayArea = getDisplayArea();
                parentAppBounds = displayArea != null
                        ? displayArea.getConfiguration().windowConfiguration.getAppBounds() : null;
        // the out bounds doesn't need to be restricted by the parent or current display.
        final boolean customContainerPolicy = compatInsets != null;
        if (!customContainerPolicy && windowingMode != WINDOWING_MODE_FREEFORM) {
            final Rect containingAppBounds;
            if (insideParentBounds) {
                containingAppBounds = parentConfig.windowConfiguration.getAppBounds();
            } else {
                parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
                // Restrict appBounds to display non-decor rather than parent because the override
                // bounds are beyond the parent. Otherwise, it won't match the overridden bounds.
                final TaskDisplayArea displayArea = getDisplayArea();
                containingAppBounds = displayArea != null
                        ? displayArea.getWindowConfiguration().getAppBounds() : null;
            }
            if (parentAppBounds != null && !parentAppBounds.isEmpty()) {
                outAppBounds.intersect(parentAppBounds);
            if (containingAppBounds != null && !containingAppBounds.isEmpty()) {
                outAppBounds.intersect(containingAppBounds);
            }
        }

        if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
                || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
            if (insideParentBounds && WindowConfiguration.isFloating(windowingMode)) {
            if (!customContainerPolicy && WindowConfiguration.isFloating(windowingMode)) {
                mTmpNonDecorBounds.set(mTmpFullBounds);
                mTmpStableBounds.set(mTmpFullBounds);
            } else if (insideParentBounds
            } else if (!customContainerPolicy
                    && (overrideDisplayInfo != null || getDisplayContent() != null)) {
                final DisplayInfo di = overrideDisplayInfo != null
                        ? overrideDisplayInfo
@@ -2344,7 +2346,7 @@ class Task extends WindowContainer<WindowContainer> {
                if (rotation == ROTATION_UNDEFINED) {
                    rotation = parentConfig.windowConfiguration.getRotation();
                }
                if (rotation != ROTATION_UNDEFINED && compatInsets != null) {
                if (rotation != ROTATION_UNDEFINED && customContainerPolicy) {
                    mTmpNonDecorBounds.set(mTmpFullBounds);
                    mTmpStableBounds.set(mTmpFullBounds);
                    compatInsets.getBoundsByRotation(mTmpBounds, rotation);
@@ -2362,13 +2364,13 @@ class Task extends WindowContainer<WindowContainer> {

            if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
                final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density);
                inOutConfig.screenWidthDp = (insideParentBounds && !hasOverrideBounds)
                inOutConfig.screenWidthDp = (insideParentBounds && !customContainerPolicy)
                        ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp)
                        : overrideScreenWidthDp;
            }
            if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
                final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density);
                inOutConfig.screenHeightDp = (insideParentBounds && !hasOverrideBounds)
                inOutConfig.screenHeightDp = (insideParentBounds && !customContainerPolicy)
                        ? Math.min(overrideScreenHeightDp, parentConfig.screenHeightDp)
                        : overrideScreenHeightDp;
            }
+11 −4
Original line number Diff line number Diff line
@@ -372,7 +372,9 @@ public class TaskRecordTests extends ActivityTestsBase {
        final int longSide = 1200;
        final int shortSide = 600;
        final Rect parentBounds = new Rect(0, 0, 250, 500);
        final Rect parentAppBounds = new Rect(0, 0, 250, 480);
        parentConfig.windowConfiguration.setBounds(parentBounds);
        parentConfig.windowConfiguration.setAppBounds(parentAppBounds);
        parentConfig.densityDpi = 400;
        parentConfig.screenHeightDp = (parentBounds.bottom * 160) / parentConfig.densityDpi; // 200
        parentConfig.screenWidthDp = (parentBounds.right * 160) / parentConfig.densityDpi; // 100
@@ -383,21 +385,25 @@ public class TaskRecordTests extends ActivityTestsBase {

        assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
        assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
        assertEquals(parentAppBounds, inOutConfig.windowConfiguration.getAppBounds());
        assertEquals(Configuration.ORIENTATION_PORTRAIT, inOutConfig.orientation);

        // If bounds are overridden, config properties should be made to match. Surface hierarchy
        // will crop for policy.
        inOutConfig.setToDefaults();
        inOutConfig.windowConfiguration.getBounds().set(0, 0, shortSide, longSide);
        // By default, the parent bounds should limit the existing input bounds.
        final Rect largerPortraitBounds = new Rect(0, 0, shortSide, longSide);
        inOutConfig.windowConfiguration.setBounds(largerPortraitBounds);
        task.computeConfigResourceOverrides(inOutConfig, parentConfig);

        // The override bounds are beyond the parent, the out appBounds should not be intersected
        // by parent appBounds.
        assertEquals(largerPortraitBounds, inOutConfig.windowConfiguration.getAppBounds());
        assertEquals(longSide, inOutConfig.screenHeightDp * parentConfig.densityDpi / 160);
        assertEquals(shortSide, inOutConfig.screenWidthDp * parentConfig.densityDpi / 160);

        inOutConfig.setToDefaults();
        // Landscape bounds.
        inOutConfig.windowConfiguration.getBounds().set(0, 0, longSide, shortSide);
        final Rect largerLandscapeBounds = new Rect(0, 0, longSide, shortSide);
        inOutConfig.windowConfiguration.setBounds(largerLandscapeBounds);

        // Setup the display with a top stable inset. The later assertion will ensure the inset is
        // excluded from screenHeightDp.
@@ -415,6 +421,7 @@ public class TaskRecordTests extends ActivityTestsBase {
                new ActivityRecord.CompatDisplayInsets(display, task);
        task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets);

        assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds());
        assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi,
                inOutConfig.screenHeightDp);
        assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi,