Merge "Ensure clear state when getDestinationBounds for PiP" into rvc-dev am: a68d92a8fc

Change-Id: I7ae36885762b75939182d2731644fab733cd854b
This commit is contained in:
Hongwei Wang
2020-04-08 04:37:54 +00:00
committed by Automerger Merge Worker
3 changed files with 64 additions and 37 deletions

View File

@@ -231,7 +231,12 @@ public class PipBoundsHandler {
/** /**
* @return {@link Rect} of the destination PiP window bounds. * @return {@link Rect} of the destination PiP window bounds.
*/ */
Rect getDestinationBounds(float aspectRatio, Rect bounds, Size minimalSize) { Rect getDestinationBounds(ComponentName componentName, float aspectRatio, Rect bounds,
Size minimalSize) {
if (!componentName.equals(mLastPipComponentName)) {
onResetReentryBoundsUnchecked();
mLastPipComponentName = componentName;
}
final Rect destinationBounds; final Rect destinationBounds;
if (bounds == null) { if (bounds == null) {
final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize); final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
@@ -246,11 +251,7 @@ public class PipBoundsHandler {
transformBoundsToAspectRatio(destinationBounds, aspectRatio, transformBoundsToAspectRatio(destinationBounds, aspectRatio,
false /* useCurrentMinEdgeSize */); false /* useCurrentMinEdgeSize */);
} }
if (destinationBounds.equals(bounds)) {
return bounds;
}
mAspectRatio = aspectRatio; mAspectRatio = aspectRatio;
onResetReentryBoundsUnchecked();
mLastDestinationBounds.set(destinationBounds); mLastDestinationBounds.set(destinationBounds);
return destinationBounds; return destinationBounds;
} }
@@ -483,6 +484,7 @@ public class PipBoundsHandler {
pw.println(prefix + TAG); pw.println(prefix + TAG);
pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName); pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName);
pw.println(innerPrefix + "mReentrySnapFraction=" + mReentrySnapFraction); pw.println(innerPrefix + "mReentrySnapFraction=" + mReentrySnapFraction);
pw.println(innerPrefix + "mReentrySize=" + mReentrySize);
pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo); pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo);
pw.println(innerPrefix + "mDefaultAspectRatio=" + mDefaultAspectRatio); pw.println(innerPrefix + "mDefaultAspectRatio=" + mDefaultAspectRatio);
pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio); pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio);

View File

@@ -247,7 +247,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
public void onTaskAppeared(ActivityManager.RunningTaskInfo info) { public void onTaskAppeared(ActivityManager.RunningTaskInfo info) {
Objects.requireNonNull(info, "Requires RunningTaskInfo"); Objects.requireNonNull(info, "Requires RunningTaskInfo");
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
getAspectRatioOrDefault(info.pictureInPictureParams), info.topActivity, getAspectRatioOrDefault(info.pictureInPictureParams),
null /* bounds */, getMinimalSize(info.topActivityInfo)); null /* bounds */, getMinimalSize(info.topActivityInfo));
Objects.requireNonNull(destinationBounds, "Missing destination bounds"); Objects.requireNonNull(destinationBounds, "Missing destination bounds");
mTaskInfo = info; mTaskInfo = info;
@@ -303,7 +303,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
return; return;
} }
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
getAspectRatioOrDefault(newParams), info.topActivity, getAspectRatioOrDefault(newParams),
null /* bounds */, getMinimalSize(info.topActivityInfo)); null /* bounds */, getMinimalSize(info.topActivityInfo));
Objects.requireNonNull(destinationBounds, "Missing destination bounds"); Objects.requireNonNull(destinationBounds, "Missing destination bounds");
scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration, scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration,
@@ -335,7 +335,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
} }
final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(
getAspectRatioOrDefault(mTaskInfo.pictureInPictureParams), mTaskInfo.topActivity, getAspectRatioOrDefault(mTaskInfo.pictureInPictureParams),
null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
if (newDestinationBounds.equals(currentDestinationBounds)) return; if (newDestinationBounds.equals(currentDestinationBounds)) return;
if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) { if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) {

View File

@@ -17,6 +17,7 @@
package com.android.systemui.pip; package com.android.systemui.pip;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import android.content.ComponentName; import android.content.ComponentName;
@@ -56,11 +57,15 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
private PipBoundsHandler mPipBoundsHandler; private PipBoundsHandler mPipBoundsHandler;
private DisplayInfo mDefaultDisplayInfo; private DisplayInfo mDefaultDisplayInfo;
private ComponentName mTestComponentName1;
private ComponentName mTestComponentName2;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
initializeMockResources(); initializeMockResources();
mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext)); mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext));
mTestComponentName1 = new ComponentName(mContext, "component1");
mTestComponentName2 = new ComponentName(mContext, "component2");
mPipBoundsHandler.onDisplayInfoChanged(mDefaultDisplayInfo); mPipBoundsHandler.onDisplayInfoChanged(mDefaultDisplayInfo);
} }
@@ -121,7 +126,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
}; };
for (float aspectRatio : aspectRatios) { for (float aspectRatio : aspectRatios) {
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); mTestComponentName1, aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
final float actualAspectRatio = final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f); destinationBounds.width() / (destinationBounds.height() * 1f);
assertEquals("Destination bounds matches the given aspect ratio", assertEquals("Destination bounds matches the given aspect ratio",
@@ -137,7 +142,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
}; };
for (float aspectRatio : invalidAspectRatios) { for (float aspectRatio : invalidAspectRatios) {
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); mTestComponentName1, aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
final float actualAspectRatio = final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f); destinationBounds.width() / (destinationBounds.height() * 1f);
assertEquals("Destination bounds fallbacks to default aspect ratio", assertEquals("Destination bounds fallbacks to default aspect ratio",
@@ -153,7 +158,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left; currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
aspectRatio, currentBounds, EMPTY_MINIMAL_SIZE); mTestComponentName1, aspectRatio, currentBounds, EMPTY_MINIMAL_SIZE);
final float actualAspectRatio = final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f); destinationBounds.width() / (destinationBounds.height() * 1f);
@@ -177,7 +182,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
final float aspectRatio = aspectRatios[i]; final float aspectRatio = aspectRatios[i];
final Size minimalSize = minimalSizes[i]; final Size minimalSize = minimalSizes[i];
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
aspectRatio, EMPTY_CURRENT_BOUNDS, minimalSize); mTestComponentName1, aspectRatio, EMPTY_CURRENT_BOUNDS, minimalSize);
assertTrue("Destination bounds is no smaller than minimal requirement", assertTrue("Destination bounds is no smaller than minimal requirement",
(destinationBounds.width() == minimalSize.getWidth() (destinationBounds.width() == minimalSize.getWidth()
&& destinationBounds.height() >= minimalSize.getHeight()) && destinationBounds.height() >= minimalSize.getHeight())
@@ -198,89 +203,100 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2); final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2);
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
aspectRatio, currentBounds, minSize); mTestComponentName1, aspectRatio, currentBounds, minSize);
assertTrue("Destination bounds ignores minimal size", assertTrue("Destination bounds ignores minimal size",
destinationBounds.width() > minSize.getWidth() destinationBounds.width() > minSize.getWidth()
&& destinationBounds.height() > minSize.getHeight()); && destinationBounds.height() > minSize.getHeight());
} }
@Test
public void getDestinationBounds_withDifferentComponentName_ignoreLastPosition() {
final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
oldPosition.offset(0, -100);
mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldPosition);
final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName2,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
assertNonBoundsInclusionWithMargin("ignore saved bounds", oldPosition, newPosition);
}
@Test @Test
public void setShelfHeight_offsetBounds() { public void setShelfHeight_offsetBounds() {
final int shelfHeight = 100; final int shelfHeight = 100;
final Rect oldPosition = mPipBoundsHandler.getDestinationBounds( final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
mPipBoundsHandler.setShelfHeight(true, shelfHeight); mPipBoundsHandler.setShelfHeight(true, shelfHeight);
final Rect newPosition = mPipBoundsHandler.getDestinationBounds( final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
oldPosition.offset(0, -shelfHeight); oldPosition.offset(0, -shelfHeight);
assertBoundsWithMargin("offsetBounds by shelf", oldPosition, newPosition); assertBoundsInclusionWithMargin("offsetBounds by shelf", oldPosition, newPosition);
} }
@Test @Test
public void onImeVisibilityChanged_offsetBounds() { public void onImeVisibilityChanged_offsetBounds() {
final int imeHeight = 100; final int imeHeight = 100;
final Rect oldPosition = mPipBoundsHandler.getDestinationBounds( final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight); mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight);
final Rect newPosition = mPipBoundsHandler.getDestinationBounds( final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
oldPosition.offset(0, -imeHeight); oldPosition.offset(0, -imeHeight);
assertBoundsWithMargin("offsetBounds by IME", oldPosition, newPosition); assertBoundsInclusionWithMargin("offsetBounds by IME", oldPosition, newPosition);
} }
@Test @Test
public void onSaveReentryBounds_restoreLastPosition() { public void onSaveReentryBounds_restoreLastPosition() {
final ComponentName componentName = new ComponentName(mContext, "component1"); final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
oldPosition.offset(0, -100); oldPosition.offset(0, -100);
mPipBoundsHandler.onSaveReentryBounds(componentName, oldPosition); mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldPosition);
final Rect newPosition = mPipBoundsHandler.getDestinationBounds( final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
assertBoundsWithMargin("restoreLastPosition", oldPosition, newPosition); assertBoundsInclusionWithMargin("restoreLastPosition", oldPosition, newPosition);
} }
@Test @Test
public void onResetReentryBounds_useDefaultBounds() { public void onResetReentryBounds_useDefaultBounds() {
final ComponentName componentName = new ComponentName(mContext, "component1"); final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
final Rect newBounds = new Rect(defaultBounds); final Rect newBounds = new Rect(defaultBounds);
newBounds.offset(0, -100); newBounds.offset(0, -100);
mPipBoundsHandler.onSaveReentryBounds(componentName, newBounds); mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, newBounds);
mPipBoundsHandler.onResetReentryBounds(componentName); mPipBoundsHandler.onResetReentryBounds(mTestComponentName1);
final Rect actualBounds = mPipBoundsHandler.getDestinationBounds( final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
assertBoundsWithMargin("useDefaultBounds", defaultBounds, actualBounds); assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds);
} }
@Test @Test
public void onResetReentryBounds_componentMismatch_restoreLastPosition() { public void onResetReentryBounds_componentMismatch_restoreLastPosition() {
final ComponentName componentName = new ComponentName(mContext, "component1"); final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
final Rect newBounds = new Rect(defaultBounds); final Rect newBounds = new Rect(defaultBounds);
newBounds.offset(0, -100); newBounds.offset(0, -100);
mPipBoundsHandler.onSaveReentryBounds(componentName, newBounds); mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, newBounds);
mPipBoundsHandler.onResetReentryBounds(new ComponentName(mContext, "component2")); mPipBoundsHandler.onResetReentryBounds(mTestComponentName2);
final Rect actualBounds = mPipBoundsHandler.getDestinationBounds( final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE); DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
assertBoundsWithMargin("restoreLastPosition", newBounds, actualBounds); assertBoundsInclusionWithMargin("restoreLastPosition", newBounds, actualBounds);
} }
private void assertBoundsWithMargin(String from, Rect expected, Rect actual) { private void assertBoundsInclusionWithMargin(String from, Rect expected, Rect actual) {
final Rect expectedWithMargin = new Rect(expected); final Rect expectedWithMargin = new Rect(expected);
expectedWithMargin.inset(-ROUNDING_ERROR_MARGIN, -ROUNDING_ERROR_MARGIN); expectedWithMargin.inset(-ROUNDING_ERROR_MARGIN, -ROUNDING_ERROR_MARGIN);
assertTrue(from + ": expect " + expected assertTrue(from + ": expect " + expected
@@ -288,4 +304,13 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
+ " with error margin " + ROUNDING_ERROR_MARGIN, + " with error margin " + ROUNDING_ERROR_MARGIN,
expectedWithMargin.contains(actual)); expectedWithMargin.contains(actual));
} }
private void assertNonBoundsInclusionWithMargin(String from, Rect expected, Rect actual) {
final Rect expectedWithMargin = new Rect(expected);
expectedWithMargin.inset(-ROUNDING_ERROR_MARGIN, -ROUNDING_ERROR_MARGIN);
assertFalse(from + ": expect " + expected
+ " not contains " + actual
+ " with error margin " + ROUNDING_ERROR_MARGIN,
expectedWithMargin.contains(actual));
}
} }