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

Commit cb5acc2f authored by jorgegil@google.com's avatar jorgegil@google.com
Browse files

Add unit tests for PipSnapAlgorithm

Bug: 169373982
Test: com.android.shell.wm.pip
Change-Id: Iecc7ede73644f975c8bc71300e72925bd220f28d
parent 82b68020
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -279,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.
+4 −16
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT;

import android.graphics.Rect;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Calculates the snap targets and the snap position for the PIP given a position and a velocity.
 * All bounds are relative to the display top/left.
@@ -118,26 +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;
    }

    /**
     * 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) {
+8 −9
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 */);
        }

@@ -358,7 +357,7 @@ public class PipTouchHandler {
        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;
    }
+237 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell.pip;

import static org.junit.Assert.assertEquals;

import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

import androidx.test.filters.SmallTest;

import com.android.wm.shell.ShellTestCase;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests for {@link PipSnapAlgorithm}. **/
@RunWith(AndroidTestingRunner.class)
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class PipSnapAlgorithmTest extends ShellTestCase {
    private static final int DEFAULT_STASH_OFFSET = 32;
    private static final Rect DISPLAY_BOUNDS = new Rect(0, 0, 2000, 2000);
    private static final Rect STACK_BOUNDS_CENTERED = new Rect(900, 900, 1100, 1100);
    private static final Rect MOVEMENT_BOUNDS = new Rect(0, 0,
            DISPLAY_BOUNDS.width() - STACK_BOUNDS_CENTERED.width(),
            DISPLAY_BOUNDS.width() - STACK_BOUNDS_CENTERED.width());

    private PipSnapAlgorithm mPipSnapAlgorithm;

    @Before
    public void setUp() {
        mPipSnapAlgorithm = new PipSnapAlgorithm();
    }

    @Test
    public void testApplySnapFraction_topEdge() {
        final float snapFraction = 0.25f;
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);

        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction);

        assertEquals(MOVEMENT_BOUNDS.width() / 4, bounds.left);
        assertEquals(MOVEMENT_BOUNDS.top, bounds.top);
    }

    @Test
    public void testApplySnapFraction_rightEdge() {
        final float snapFraction = 1.5f;
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);

        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction);

        assertEquals(MOVEMENT_BOUNDS.right, bounds.left);
        assertEquals(MOVEMENT_BOUNDS.height() / 2, bounds.top);
    }

    @Test
    public void testApplySnapFraction_bottomEdge() {
        final float snapFraction = 2.25f;
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);

        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction);

        assertEquals((int) (MOVEMENT_BOUNDS.width() * 0.75f), bounds.left);
        assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top);
    }

    @Test
    public void testApplySnapFraction_leftEdge() {
        final float snapFraction = 3.75f;
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);

        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction);

        assertEquals(MOVEMENT_BOUNDS.left, bounds.left);
        assertEquals((int) (MOVEMENT_BOUNDS.height() * 0.25f), bounds.top);
    }

    @Test
    public void testApplySnapFraction_notStashed_isNotOffBounds() {
        final float snapFraction = 2f;
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);

        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction,
                PipBoundsState.STASH_TYPE_NONE, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS);

        assertEquals(MOVEMENT_BOUNDS.right, bounds.left);
        assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top);
    }

    @Test
    public void testApplySnapFraction_stashedLeft() {
        final float snapFraction = 3f;
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);

        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction,
                PipBoundsState.STASH_TYPE_LEFT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS);

        final int offBoundsWidth = bounds.width() - DEFAULT_STASH_OFFSET;
        assertEquals(MOVEMENT_BOUNDS.left - offBoundsWidth, bounds.left);
        assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top);
    }

    @Test
    public void testApplySnapFraction_stashedRight() {
        final float snapFraction = 2f;
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);

        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction,
                PipBoundsState.STASH_TYPE_RIGHT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS);

        assertEquals(DISPLAY_BOUNDS.right - DEFAULT_STASH_OFFSET, bounds.left);
        assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top);
    }

    @Test
    public void testSnapRectToClosestEdge_rightEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move the centered rect slightly to the right side.
        bounds.offset(10, 0);

        mPipSnapAlgorithm.snapRectToClosestEdge(bounds, MOVEMENT_BOUNDS, bounds,
                PipBoundsState.STASH_TYPE_NONE);

        assertEquals(MOVEMENT_BOUNDS.right, bounds.left);
    }

    @Test
    public void testSnapRectToClosestEdge_leftEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move the centered rect slightly to the left side.
        bounds.offset(-10, 0);

        mPipSnapAlgorithm.snapRectToClosestEdge(bounds, MOVEMENT_BOUNDS, bounds,
                PipBoundsState.STASH_TYPE_NONE);

        assertEquals(MOVEMENT_BOUNDS.left, bounds.left);
    }

    @Test
    public void testSnapRectToClosestEdge_topEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move the centered rect slightly to the top half.
        bounds.offset(0, -10);

        mPipSnapAlgorithm.snapRectToClosestEdge(bounds, MOVEMENT_BOUNDS, bounds,
                PipBoundsState.STASH_TYPE_NONE);

        assertEquals(MOVEMENT_BOUNDS.top, bounds.top);
    }

    @Test
    public void testSnapRectToClosestEdge_bottomEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move the centered rect slightly to the bottom half.
        bounds.offset(0, 10);

        mPipSnapAlgorithm.snapRectToClosestEdge(bounds, MOVEMENT_BOUNDS, bounds,
                PipBoundsState.STASH_TYPE_NONE);

        assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top);
    }

    @Test
    public void testSnapRectToClosestEdge_stashed_unStahesBounds() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Stash it on the left side.
        mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, 3.5f,
                PipBoundsState.STASH_TYPE_LEFT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS);

        mPipSnapAlgorithm.snapRectToClosestEdge(bounds, MOVEMENT_BOUNDS, bounds,
                PipBoundsState.STASH_TYPE_LEFT);

        assertEquals(MOVEMENT_BOUNDS.left, bounds.left);
    }

    @Test
    public void testGetSnapFraction_leftEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move it slightly to the left side.
        bounds.offset(-10, 0);

        final float snapFraction = mPipSnapAlgorithm.getSnapFraction(bounds, MOVEMENT_BOUNDS);

        assertEquals(3.5f, snapFraction, 0.1f);
    }

    @Test
    public void testGetSnapFraction_rightEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move it slightly to the right side.
        bounds.offset(10, 0);

        final float snapFraction = mPipSnapAlgorithm.getSnapFraction(bounds, MOVEMENT_BOUNDS);

        assertEquals(1.5f, snapFraction, 0.1f);
    }

    @Test
    public void testGetSnapFraction_topEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move it slightly to the top half.
        bounds.offset(0, -10);

        final float snapFraction = mPipSnapAlgorithm.getSnapFraction(bounds, MOVEMENT_BOUNDS);

        assertEquals(0.5f, snapFraction, 0.1f);
    }

    @Test
    public void testGetSnapFraction_bottomEdge() {
        final Rect bounds = new Rect(STACK_BOUNDS_CENTERED);
        // Move it slightly to the bottom half.
        bounds.offset(0, 10);

        final float snapFraction = mPipSnapAlgorithm.getSnapFraction(bounds, MOVEMENT_BOUNDS);

        assertEquals(2.5f, snapFraction, 0.1f);
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -115,7 +115,8 @@ public class PipTouchHandlerTest extends ShellTestCase {
    @Test
    public void updateMovementBounds_minBounds() {
        Rect expectedMinMovementBounds = new Rect();
        mPipSnapAlgorithm.getMovementBounds(mMinBounds, mInsetBounds, expectedMinMovementBounds, 0);
        mPipBoundsAlgorithm.getMovementBounds(mMinBounds, mInsetBounds, expectedMinMovementBounds,
                0);

        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
@@ -134,7 +135,8 @@ public class PipTouchHandlerTest extends ShellTestCase {
                        R.dimen.pip_expanded_shortest_edge_size), displaySize.x, displaySize.y);
        Rect maxBounds = new Rect(0, 0, maxSize.getWidth(), maxSize.getHeight());
        Rect expectedMaxMovementBounds = new Rect();
        mPipSnapAlgorithm.getMovementBounds(maxBounds, mInsetBounds, expectedMaxMovementBounds, 0);
        mPipBoundsAlgorithm.getMovementBounds(maxBounds, mInsetBounds, expectedMaxMovementBounds,
                0);

        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);