Merge changes from topic "bounds-algo-tests"

* changes:
  Add unit tests for PipSnapAlgorithm
  Add unit tests for PipBoundsAlgorithm
This commit is contained in:
Jorge Gil
2020-11-19 00:50:16 +00:00
committed by Android (Google) Code Review
6 changed files with 486 additions and 111 deletions

View File

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

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

@@ -91,7 +91,7 @@ public class PipTouchHandlerTest extends ShellTestCase {
mPipBoundsState = new PipBoundsState(mContext);
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState);
mPipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
mPipSnapAlgorithm = new PipSnapAlgorithm(mContext);
mPipSnapAlgorithm = new PipSnapAlgorithm();
mPipTouchHandler = new PipTouchHandler(mContext, mPipMenuActivityController,
mPipBoundsAlgorithm, mPipBoundsState, mPipTaskOrganizer,
mFloatingContentCoordinator, mPipUiEventLogger);
@@ -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);
@@ -129,12 +130,13 @@ public class PipTouchHandlerTest extends ShellTestCase {
public void updateMovementBounds_maxBounds() {
Point displaySize = new Point();
mContext.getDisplay().getRealSize(displaySize);
Size maxSize = mPipSnapAlgorithm.getSizeForAspectRatio(1,
Size maxSize = mPipBoundsAlgorithm.getSizeForAspectRatio(1,
mContext.getResources().getDimensionPixelSize(
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);