Add unit tests for PipSnapAlgorithm

Bug: 169373982
Test: com.android.shell.wm.pip
Change-Id: Iecc7ede73644f975c8bc71300e72925bd220f28d
This commit is contained in:
jorgegil@google.com
2020-11-18 11:10:30 -08:00
parent 82b6802083
commit cb5acc2f2b
5 changed files with 269 additions and 28 deletions

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -0,0 +1,237 @@
/*
* 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);
}
}

View File

@@ -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);