Loading packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +7 −5 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading Loading @@ -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); Loading packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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) { Loading packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java +54 −29 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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", Loading @@ -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", Loading @@ -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); Loading @@ -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()) Loading @@ -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 Loading @@ -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)); } } } Loading
packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +7 −5 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading Loading @@ -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); Loading
packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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) { Loading
packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java +54 −29 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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", Loading @@ -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", Loading @@ -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); Loading @@ -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()) Loading @@ -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 Loading @@ -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)); } } }