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

Commit 828490c3 authored by Jorge Gil's avatar Jorge Gil Committed by Android (Google) Code Review
Browse files

Merge changes from topic "bounds-algo-tests"

* changes:
  Add unit tests for PipSnapAlgorithm
  Add unit tests for PipBoundsAlgorithm
parents d0ba3573 cb5acc2f
Loading
Loading
Loading
Loading
+85 −5
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Size;
@@ -42,6 +43,9 @@ public class PipBoundsAlgorithm {
    private final @NonNull PipBoundsState mPipBoundsState;
    private final PipSnapAlgorithm mSnapAlgorithm;

    private float mDefaultSizePercent;
    private float mMinAspectRatioForMinSize;
    private float mMaxAspectRatioForMinSize;
    private float mDefaultAspectRatio;
    private float mMinAspectRatio;
    private float mMaxAspectRatio;
@@ -51,7 +55,7 @@ public class PipBoundsAlgorithm {

    public PipBoundsAlgorithm(Context context, @NonNull PipBoundsState pipBoundsState) {
        mPipBoundsState = pipBoundsState;
        mSnapAlgorithm = new PipSnapAlgorithm(context);
        mSnapAlgorithm = new PipSnapAlgorithm();
        reloadResources(context);
        // Initialize the aspect ratio to the default aspect ratio.  Don't do this in reload
        // resources as it would clobber mAspectRatio when entering PiP from fullscreen which
@@ -83,6 +87,11 @@ public class PipBoundsAlgorithm {
                com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
        mMaxAspectRatio = res.getFloat(
                com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
        mDefaultSizePercent = res.getFloat(
                com.android.internal.R.dimen.config_pictureInPictureDefaultSizePercent);
        mMaxAspectRatioForMinSize = res.getFloat(
                com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
        mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
    }

    /**
@@ -174,7 +183,7 @@ public class PipBoundsAlgorithm {
            final int minEdgeSize = useCurrentMinEdgeSize ? mPipBoundsState.getMinEdgeSize()
                    : defaultMinEdgeSize;
            // Use the existing size but adjusted to the aspect ratio and min edge size.
            size = mSnapAlgorithm.getSizeForAspectRatio(
            size = getSizeForAspectRatio(
                    new Size(stackBounds.width(), stackBounds.height()), aspectRatio, minEdgeSize);
        } else {
            if (overrideMinSize != null) {
@@ -184,7 +193,7 @@ public class PipBoundsAlgorithm {
            } else {
                // Calculate the default size using the display size and default min edge size.
                final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
                size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, mDefaultMinSize,
                size = getSizeForAspectRatio(aspectRatio, mDefaultMinSize,
                        displayInfo.logicalWidth, displayInfo.logicalHeight);
            }
        }
@@ -229,7 +238,7 @@ public class PipBoundsAlgorithm {
                defaultSize = adjustSizeToAspectRatio(overrideMinSize, mDefaultAspectRatio);
            } else {
                // Calculate the default size using the display size and default min edge size.
                defaultSize = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
                defaultSize = getSizeForAspectRatio(mDefaultAspectRatio,
                        mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight);
            }
            Gravity.apply(mDefaultStackGravity, defaultSize.getWidth(), defaultSize.getHeight(),
@@ -270,12 +279,27 @@ public class PipBoundsAlgorithm {
        getInsetBounds(movementBounds);

        // Apply the movement bounds adjustments based on the current state.
        mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
        getMovementBounds(stackBounds, movementBounds, movementBounds,
                (adjustForIme && mPipBoundsState.isImeShowing())
                        ? mPipBoundsState.getImeHeight() : 0);

        return movementBounds;
    }

    /**
     * Adjusts movementBoundsOut so that it is the movement bounds for the given stackBounds.
     */
    public void getMovementBounds(Rect stackBounds, Rect insetBounds, Rect movementBoundsOut,
            int bottomOffset) {
        // Adjust the right/bottom to ensure the stack bounds never goes offscreen
        movementBoundsOut.set(insetBounds);
        movementBoundsOut.right = Math.max(insetBounds.left, insetBounds.right
                - stackBounds.width());
        movementBoundsOut.bottom = Math.max(insetBounds.top, insetBounds.bottom
                - stackBounds.height());
        movementBoundsOut.bottom -= bottomOffset;
    }

    /**
     * @return the default snap fraction to apply instead of the default gravity when calculating
     *         the default stack bounds when first entering PiP.
@@ -303,6 +327,62 @@ public class PipBoundsAlgorithm {
        return (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, dpValue, dm);
    }

    /**
     * @return the size of the PiP at the given aspectRatio, ensuring that the minimum edge
     * is at least minEdgeSize.
     */
    public Size getSizeForAspectRatio(float aspectRatio, float minEdgeSize, int displayWidth,
            int displayHeight) {
        final int smallestDisplaySize = Math.min(displayWidth, displayHeight);
        final int minSize = (int) Math.max(minEdgeSize, smallestDisplaySize * mDefaultSizePercent);

        final int width;
        final int height;
        if (aspectRatio <= mMinAspectRatioForMinSize || aspectRatio > mMaxAspectRatioForMinSize) {
            // Beyond these points, we can just use the min size as the shorter edge
            if (aspectRatio <= 1) {
                // Portrait, width is the minimum size
                width = minSize;
                height = Math.round(width / aspectRatio);
            } else {
                // Landscape, height is the minimum size
                height = minSize;
                width = Math.round(height * aspectRatio);
            }
        } else {
            // Within these points, we ensure that the bounds fit within the radius of the limits
            // at the points
            final float widthAtMaxAspectRatioForMinSize = mMaxAspectRatioForMinSize * minSize;
            final float radius = PointF.length(widthAtMaxAspectRatioForMinSize, minSize);
            height = (int) Math.round(Math.sqrt((radius * radius)
                    / (aspectRatio * aspectRatio + 1)));
            width = Math.round(height * aspectRatio);
        }
        return new Size(width, height);
    }

    /**
     * @return the adjusted size so that it conforms to the given aspectRatio, ensuring that the
     * minimum edge is at least minEdgeSize.
     */
    public Size getSizeForAspectRatio(Size size, float aspectRatio, float minEdgeSize) {
        final int smallestSize = Math.min(size.getWidth(), size.getHeight());
        final int minSize = (int) Math.max(minEdgeSize, smallestSize);

        final int width;
        final int height;
        if (aspectRatio <= 1) {
            // Portrait, width is the minimum size.
            width = minSize;
            height = Math.round(width / aspectRatio);
        } else {
            // Landscape, height is the minimum size
            height = minSize;
            width = Math.round(height * aspectRatio);
        }
        return new Size(width, height);
    }

    /**
     * Dumps internal states.
     */
+4 −89
Original line number Diff line number Diff line
@@ -20,11 +20,9 @@ import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_LEFT;
import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE;
import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.Size;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Calculates the snap targets and the snap position for the PIP given a position and a velocity.
@@ -32,19 +30,6 @@ import android.util.Size;
 */
public class PipSnapAlgorithm {

    private final float mDefaultSizePercent;
    private final float mMinAspectRatioForMinSize;
    private final float mMaxAspectRatioForMinSize;

    public PipSnapAlgorithm(Context context) {
        Resources res = context.getResources();
        mDefaultSizePercent = res.getFloat(
                com.android.internal.R.dimen.config_pictureInPictureDefaultSizePercent);
        mMaxAspectRatioForMinSize = res.getFloat(
                com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
        mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
    }

    /**
     * Returns a fraction that describes where the PiP bounds is.
     * See {@link #getSnapFraction(Rect, Rect, int)}.
@@ -135,82 +120,12 @@ public class PipSnapAlgorithm {
        }
    }

    /**
     * Adjusts {@param movementBoundsOut} so that it is the movement bounds for the given
     * {@param stackBounds}.
     */
    public void getMovementBounds(Rect stackBounds, Rect insetBounds, Rect movementBoundsOut,
            int bottomOffset) {
        // Adjust the right/bottom to ensure the stack bounds never goes offscreen
        movementBoundsOut.set(insetBounds);
        movementBoundsOut.right = Math.max(insetBounds.left, insetBounds.right -
                stackBounds.width());
        movementBoundsOut.bottom = Math.max(insetBounds.top, insetBounds.bottom -
                stackBounds.height());
        movementBoundsOut.bottom -= bottomOffset;
    }

    /**
     * @return the size of the PiP at the given {@param aspectRatio}, ensuring that the minimum edge
     * is at least {@param minEdgeSize}.
     */
    public Size getSizeForAspectRatio(float aspectRatio, float minEdgeSize, int displayWidth,
            int displayHeight) {
        final int smallestDisplaySize = Math.min(displayWidth, displayHeight);
        final int minSize = (int) Math.max(minEdgeSize, smallestDisplaySize * mDefaultSizePercent);

        final int width;
        final int height;
        if (aspectRatio <= mMinAspectRatioForMinSize || aspectRatio > mMaxAspectRatioForMinSize) {
            // Beyond these points, we can just use the min size as the shorter edge
            if (aspectRatio <= 1) {
                // Portrait, width is the minimum size
                width = minSize;
                height = Math.round(width / aspectRatio);
            } else {
                // Landscape, height is the minimum size
                height = minSize;
                width = Math.round(height * aspectRatio);
            }
        } else {
            // Within these points, we ensure that the bounds fit within the radius of the limits
            // at the points
            final float widthAtMaxAspectRatioForMinSize = mMaxAspectRatioForMinSize * minSize;
            final float radius = PointF.length(widthAtMaxAspectRatioForMinSize, minSize);
            height = (int) Math.round(Math.sqrt((radius * radius) /
                    (aspectRatio * aspectRatio + 1)));
            width = Math.round(height * aspectRatio);
        }
        return new Size(width, height);
    }

    /**
     * @return the adjusted size so that it conforms to the given aspectRatio, ensuring that the
     * minimum edge is at least minEdgeSize.
     */
    public Size getSizeForAspectRatio(Size size, float aspectRatio, float minEdgeSize) {
        final int smallestSize = Math.min(size.getWidth(), size.getHeight());
        final int minSize = (int) Math.max(minEdgeSize, smallestSize);

        final int width;
        final int height;
        if (aspectRatio <= 1) {
            // Portrait, width is the minimum size.
            width = minSize;
            height = Math.round(width / aspectRatio);
        } else {
            // Landscape, height is the minimum size
            height = minSize;
            width = Math.round(height * aspectRatio);
        }
        return new Size(width, height);
    }

    /**
     * Snaps the {@param stackBounds} to the closest edge of the {@param movementBounds} and writes
     * the new bounds out to {@param boundsOut}.
     */
    public void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut,
    @VisibleForTesting
    void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut,
            @PipBoundsState.StashType int stashType) {
        int leftEdge = stackBounds.left;
        if (stashType == STASH_TYPE_LEFT) {
+9 −10
Original line number Diff line number Diff line
@@ -307,8 +307,7 @@ public class PipTouchHandler {

    public void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) {
        final Rect toMovementBounds = new Rect();
        mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(outBounds, insetBounds,
                toMovementBounds, 0);
        mPipBoundsAlgorithm.getMovementBounds(outBounds, insetBounds, toMovementBounds, 0);
        final int prevBottom = mPipBoundsState.getMovementBounds().bottom
                - mMovementBoundsExtraOffsets;
        if ((prevBottom - mBottomOffsetBufferPx) <= curBounds.top) {
@@ -339,13 +338,13 @@ public class PipTouchHandler {

        // Re-calculate the expanded bounds
        Rect normalMovementBounds = new Rect();
        mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(normalBounds, insetBounds,
        mPipBoundsAlgorithm.getMovementBounds(normalBounds, insetBounds,
                normalMovementBounds, bottomOffset);

        if (mPipBoundsState.getMovementBounds().isEmpty()) {
            // mMovementBounds is not initialized yet and a clean movement bounds without
            // bottom offset shall be used later in this function.
            mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
            mPipBoundsAlgorithm.getMovementBounds(curBounds, insetBounds,
                    mPipBoundsState.getMovementBounds(), 0 /* bottomOffset */);
        }

@@ -353,12 +352,12 @@ public class PipTouchHandler {
        float aspectRatio = (float) normalBounds.width() / normalBounds.height();
        Point displaySize = new Point();
        mContext.getDisplay().getRealSize(displaySize);
        Size expandedSize = mPipBoundsAlgorithm.getSnapAlgorithm().getSizeForAspectRatio(
        Size expandedSize = mPipBoundsAlgorithm.getSizeForAspectRatio(
                aspectRatio, mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
        mPipBoundsState.setExpandedBounds(
                new Rect(0, 0, expandedSize.getWidth(), expandedSize.getHeight()));
        Rect expandedMovementBounds = new Rect();
        mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(
        mPipBoundsAlgorithm.getMovementBounds(
                mPipBoundsState.getExpandedBounds(), insetBounds, expandedMovementBounds,
                bottomOffset);

@@ -381,7 +380,7 @@ public class PipTouchHandler {
            } else {
                final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu();
                final Rect toMovementBounds = new Rect();
                mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
                mPipBoundsAlgorithm.getMovementBounds(curBounds, insetBounds,
                        toMovementBounds, mIsImeShowing ? mImeHeight : 0);
                final int prevBottom = mPipBoundsState.getMovementBounds().bottom
                        - mMovementBoundsExtraOffsets;
@@ -659,7 +658,7 @@ public class PipTouchHandler {

    private void animateToUnexpandedState(Rect restoreBounds) {
        Rect restoredMovementBounds = new Rect();
        mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(restoreBounds,
        mPipBoundsAlgorithm.getMovementBounds(restoreBounds,
                mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
        mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
                restoredMovementBounds, mPipBoundsState.getMovementBounds(), false /* immediate */);
@@ -865,7 +864,7 @@ public class PipTouchHandler {
     * resized.
     */
    private void updateMovementBounds() {
        mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(mPipBoundsState.getBounds(),
        mPipBoundsAlgorithm.getMovementBounds(mPipBoundsState.getBounds(),
                mInsetBounds, mPipBoundsState.getMovementBounds(), mIsImeShowing ? mImeHeight : 0);
        mMotionHelper.onMovementBoundsChanged();

@@ -877,7 +876,7 @@ public class PipTouchHandler {

    private Rect getMovementBounds(Rect curBounds) {
        Rect movementBounds = new Rect();
        mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(curBounds, mInsetBounds,
        mPipBoundsAlgorithm.getMovementBounds(curBounds, mInsetBounds,
                movementBounds, mIsImeShowing ? mImeHeight : 0);
        return movementBounds;
    }
+145 −3
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
    private static final float DEFAULT_ASPECT_RATIO = 1f;
    private static final float MIN_ASPECT_RATIO = 0.5f;
    private static final float MAX_ASPECT_RATIO = 2f;
    private static final int DEFAULT_MIN_EDGE_SIZE = 100;

    private PipBoundsAlgorithm mPipBoundsAlgorithm;
    private DisplayInfo mDefaultDisplayInfo;
@@ -73,7 +74,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
                com.android.internal.R.integer.config_defaultPictureInPictureGravity,
                Gravity.END | Gravity.BOTTOM);
        res.addOverride(
                com.android.internal.R.dimen.default_minimal_size_pip_resizable_task, 100);
                com.android.internal.R.dimen.default_minimal_size_pip_resizable_task,
                DEFAULT_MIN_EDGE_SIZE);
        res.addOverride(
                com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets,
                "16x16");
@@ -111,6 +113,127 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
                ASPECT_RATIO_ERROR_MARGIN);
    }

    @Test
    public void getDefaultBounds_noOverrideMinSize_matchesDefaultSizeAndAspectRatio() {
        final Size defaultSize = mPipBoundsAlgorithm.getSizeForAspectRatio(DEFAULT_ASPECT_RATIO,
                DEFAULT_MIN_EDGE_SIZE, mDefaultDisplayInfo.logicalWidth,
                mDefaultDisplayInfo.logicalHeight);

        mPipBoundsState.setOverrideMinSize(null);
        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        assertEquals(defaultSize, new Size(defaultBounds.width(), defaultBounds.height()));
        assertEquals(DEFAULT_ASPECT_RATIO, getRectAspectRatio(defaultBounds),
                ASPECT_RATIO_ERROR_MARGIN);
    }

    @Test
    public void getDefaultBounds_widerOverrideMinSize_matchesMinSizeWidthAndDefaultAspectRatio() {
        overrideDefaultAspectRatio(1.0f);
        // The min size's aspect ratio is greater than the default aspect ratio.
        final Size overrideMinSize = new Size(150, 120);

        mPipBoundsState.setOverrideMinSize(overrideMinSize);
        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        // The default aspect ratio should trump the min size aspect ratio.
        assertEquals(DEFAULT_ASPECT_RATIO, getRectAspectRatio(defaultBounds),
                ASPECT_RATIO_ERROR_MARGIN);
        // The width of the min size is still used with the default aspect ratio.
        assertEquals(overrideMinSize.getWidth(), defaultBounds.width());
    }

    @Test
    public void getDefaultBounds_tallerOverrideMinSize_matchesMinSizeHeightAndDefaultAspectRatio() {
        overrideDefaultAspectRatio(1.0f);
        // The min size's aspect ratio is greater than the default aspect ratio.
        final Size overrideMinSize = new Size(120, 150);

        mPipBoundsState.setOverrideMinSize(overrideMinSize);
        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        // The default aspect ratio should trump the min size aspect ratio.
        assertEquals(DEFAULT_ASPECT_RATIO, getRectAspectRatio(defaultBounds),
                ASPECT_RATIO_ERROR_MARGIN);
        // The height of the min size is still used with the default aspect ratio.
        assertEquals(overrideMinSize.getHeight(), defaultBounds.height());
    }

    @Test
    public void getDefaultBounds_imeShowing_offsetByImeHeight() {
        final int imeHeight = 30;
        mPipBoundsState.setImeVisibility(false, 0);
        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        mPipBoundsState.setImeVisibility(true, imeHeight);
        final Rect defaultBoundsWithIme = mPipBoundsAlgorithm.getDefaultBounds();

        assertEquals(imeHeight, defaultBounds.top - defaultBoundsWithIme.top);
    }

    @Test
    public void getDefaultBounds_shelfShowing_offsetByShelfHeight() {
        final int shelfHeight = 30;
        mPipBoundsState.setShelfVisibility(false, 0);
        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        mPipBoundsState.setShelfVisibility(true, shelfHeight);
        final Rect defaultBoundsWithShelf = mPipBoundsAlgorithm.getDefaultBounds();

        assertEquals(shelfHeight, defaultBounds.top - defaultBoundsWithShelf.top);
    }

    @Test
    public void getDefaultBounds_imeAndShelfShowing_offsetByTallest() {
        final int imeHeight = 30;
        final int shelfHeight = 40;
        mPipBoundsState.setImeVisibility(false, 0);
        mPipBoundsState.setShelfVisibility(false, 0);
        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        mPipBoundsState.setImeVisibility(true, imeHeight);
        mPipBoundsState.setShelfVisibility(true, shelfHeight);
        final Rect defaultBoundsWithIme = mPipBoundsAlgorithm.getDefaultBounds();

        assertEquals(shelfHeight, defaultBounds.top - defaultBoundsWithIme.top);
    }

    @Test
    public void getDefaultBounds_boundsAtDefaultGravity() {
        final Rect insetBounds = new Rect();
        mPipBoundsAlgorithm.getInsetBounds(insetBounds);
        overrideDefaultStackGravity(Gravity.END | Gravity.BOTTOM);

        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        assertEquals(insetBounds.bottom, defaultBounds.bottom);
        assertEquals(insetBounds.right, defaultBounds.right);
    }

    @Test
    public void getNormalBounds_invalidAspectRatio_returnsDefaultBounds() {
        final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();

        // Set an invalid current aspect ratio.
        mPipBoundsState.setAspectRatio(MIN_ASPECT_RATIO / 2);
        final Rect normalBounds = mPipBoundsAlgorithm.getNormalBounds();

        assertEquals(defaultBounds, normalBounds);
    }

    @Test
    public void getNormalBounds_validAspectRatio_returnsAdjustedDefaultBounds() {
        final Rect defaultBoundsAdjustedToAspectRatio = mPipBoundsAlgorithm.getDefaultBounds();
        mPipBoundsAlgorithm.transformBoundsToAspectRatio(defaultBoundsAdjustedToAspectRatio,
                MIN_ASPECT_RATIO, false /* useCurrentMinEdgeSize */, false /* useCurrentSize */);

        // Set a valid current aspect ratio different that the default.
        mPipBoundsState.setAspectRatio(MIN_ASPECT_RATIO);
        final Rect normalBounds = mPipBoundsAlgorithm.getNormalBounds();

        assertEquals(defaultBoundsAdjustedToAspectRatio, normalBounds);
    }

    @Test
    public void getEntryDestinationBounds_returnBoundsMatchesAspectRatio() {
        final float[] aspectRatios = new float[] {
@@ -121,8 +244,7 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
        for (float aspectRatio : aspectRatios) {
            mPipBoundsState.setAspectRatio(aspectRatio);
            final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
            final float actualAspectRatio =
                    destinationBounds.width() / (destinationBounds.height() * 1f);
            final float actualAspectRatio = getRectAspectRatio(destinationBounds);
            assertEquals("Destination bounds matches the given aspect ratio",
                    aspectRatio, actualAspectRatio, ASPECT_RATIO_ERROR_MARGIN);
        }
@@ -274,6 +396,22 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
        assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds);
    }

    private void overrideDefaultAspectRatio(float aspectRatio) {
        final TestableResources res = mContext.getOrCreateTestableResources();
        res.addOverride(
                com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio,
                aspectRatio);
        mPipBoundsAlgorithm.onConfigurationChanged(mContext);
    }

    private void overrideDefaultStackGravity(int stackGravity) {
        final TestableResources res = mContext.getOrCreateTestableResources();
        res.addOverride(
                com.android.internal.R.integer.config_defaultPictureInPictureGravity,
                stackGravity);
        mPipBoundsAlgorithm.onConfigurationChanged(mContext);
    }

    private void assertBoundsInclusionWithMargin(String from, Rect expected, Rect actual) {
        final Rect expectedWithMargin = new Rect(expected);
        expectedWithMargin.inset(-ROUNDING_ERROR_MARGIN, -ROUNDING_ERROR_MARGIN);
@@ -282,4 +420,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
                + " with error margin " + ROUNDING_ERROR_MARGIN,
                expectedWithMargin.contains(actual));
    }

    private static float getRectAspectRatio(Rect rect) {
        return rect.width() / (rect.height() * 1f);
    }
}
+237 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading