diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java index fd8ca8044acf3..419d8d590124d 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java @@ -109,10 +109,11 @@ public class PipAnimationController { @SuppressWarnings("unchecked") PipTransitionAnimator getAnimator(SurfaceControl leash, Rect startBounds, Rect endBounds, - Rect sourceHintRect) { + Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction) { if (mCurrentAnimator == null) { mCurrentAnimator = setupPipTransitionAnimator( - PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect)); + PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect, + direction)); } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA && mCurrentAnimator.isRunning()) { // If we are still animating the fade into pip, then just move the surface and ensure @@ -127,7 +128,8 @@ public class PipAnimationController { } else { mCurrentAnimator.cancel(); mCurrentAnimator = setupPipTransitionAnimator( - PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect)); + PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect, + direction)); } return mCurrentAnimator; } @@ -281,7 +283,8 @@ public class PipAnimationController { boolean inScaleTransition() { if (mAnimationType != ANIM_TYPE_BOUNDS) return false; - return !isInPipDirection(getTransitionDirection()); + final int direction = getTransitionDirection(); + return !isInPipDirection(direction) && !isOutPipDirection(direction); } /** @@ -357,16 +360,26 @@ public class PipAnimationController { } static PipTransitionAnimator ofBounds(SurfaceControl leash, - Rect startValue, Rect endValue, Rect sourceHintRect) { + Rect startValue, Rect endValue, Rect sourceHintRect, + @PipAnimationController.TransitionDirection int direction) { // Just for simplicity we'll interpolate between the source rect hint insets and empty // insets to calculate the window crop - final Rect initialStartValue = new Rect(startValue); - final Rect sourceHintRectInsets = sourceHintRect != null - ? new Rect(sourceHintRect.left - startValue.left, - sourceHintRect.top - startValue.top, - startValue.right - sourceHintRect.right, - startValue.bottom - sourceHintRect.bottom) - : null; + final Rect initialSourceValue; + if (isOutPipDirection(direction)) { + initialSourceValue = new Rect(endValue); + } else { + initialSourceValue = new Rect(startValue); + } + + final Rect sourceHintRectInsets; + if (sourceHintRect == null) { + sourceHintRectInsets = null; + } else { + sourceHintRectInsets = new Rect(sourceHintRect.left - initialSourceValue.left, + sourceHintRect.top - initialSourceValue.top, + initialSourceValue.right - sourceHintRect.right, + initialSourceValue.bottom - sourceHintRect.bottom); + } final Rect sourceInsets = new Rect(0, 0, 0, 0); // construct new Rect instances in case they are recycled @@ -382,21 +395,23 @@ public class PipAnimationController { final Rect end = getEndValue(); Rect bounds = mRectEvaluator.evaluate(fraction, start, end); setCurrentValue(bounds); - if (inScaleTransition()) { - if (isOutPipDirection(getTransitionDirection())) { + if (inScaleTransition() || sourceHintRect == null) { + if (isOutPipDirection(direction)) { getSurfaceTransactionHelper().scale(tx, leash, end, bounds); } else { getSurfaceTransactionHelper().scale(tx, leash, start, bounds); } } else { - if (sourceHintRectInsets != null) { - Rect insets = mInsetsEvaluator.evaluate(fraction, sourceInsets, - sourceHintRectInsets); - getSurfaceTransactionHelper().scaleAndCrop(tx, leash, initialStartValue, - bounds, insets); + final Rect insets; + if (isOutPipDirection(direction)) { + insets = mInsetsEvaluator.evaluate(fraction, sourceHintRectInsets, + sourceInsets); } else { - getSurfaceTransactionHelper().scale(tx, leash, start, bounds); + insets = mInsetsEvaluator.evaluate(fraction, sourceInsets, + sourceHintRectInsets); } + getSurfaceTransactionHelper().scaleAndCrop(tx, leash, + initialSourceValue, bounds, insets); } tx.apply(); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 9ca5f2a0dfd12..b6334c562a028 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -360,8 +360,8 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize public void onTransactionReady(int id, SurfaceControl.Transaction t) { t.apply(); scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, - null /* sourceHintRect */, direction, animationDurationMs, - null /* updateBoundsCallback */); + getValidSourceHintRect(mTaskInfo, destinationBounds), direction, + animationDurationMs, null /* updateBoundsCallback */); mState = State.EXITING_PIP; } }); @@ -998,7 +998,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize return; } mPipAnimationController - .getAnimator(mLeash, currentBounds, destinationBounds, sourceHintRect) + .getAnimator(mLeash, currentBounds, destinationBounds, sourceHintRect, direction) .setTransitionDirection(direction) .setPipAnimationCallback(mPipAnimationCallback) .setDuration(durationMs) diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java index f0066ba4f66a8..6f5cbe21be75c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java @@ -81,7 +81,7 @@ public class PipAnimationControllerTest extends SysuiTestCase { @Test public void getAnimator_withBounds_returnBoundsAnimator() { final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController - .getAnimator(mLeash, new Rect(), new Rect(), null); + .getAnimator(mLeash, new Rect(), new Rect(), null, TRANSITION_DIRECTION_TO_PIP); assertEquals("Expect ANIM_TYPE_BOUNDS animation", animator.getAnimationType(), PipAnimationController.ANIM_TYPE_BOUNDS); @@ -93,12 +93,12 @@ public class PipAnimationControllerTest extends SysuiTestCase { final Rect endValue1 = new Rect(100, 100, 200, 200); final Rect endValue2 = new Rect(200, 200, 300, 300); final PipAnimationController.PipTransitionAnimator oldAnimator = mPipAnimationController - .getAnimator(mLeash, startValue, endValue1, null); + .getAnimator(mLeash, startValue, endValue1, null, TRANSITION_DIRECTION_TO_PIP); oldAnimator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new); oldAnimator.start(); final PipAnimationController.PipTransitionAnimator newAnimator = mPipAnimationController - .getAnimator(mLeash, startValue, endValue2, null); + .getAnimator(mLeash, startValue, endValue2, null, TRANSITION_DIRECTION_TO_PIP); assertEquals("getAnimator with same type returns same animator", oldAnimator, newAnimator); @@ -128,7 +128,7 @@ public class PipAnimationControllerTest extends SysuiTestCase { final Rect endValue1 = new Rect(100, 100, 200, 200); final Rect endValue2 = new Rect(200, 200, 300, 300); final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController - .getAnimator(mLeash, startValue, endValue1, null); + .getAnimator(mLeash, startValue, endValue1, null, TRANSITION_DIRECTION_TO_PIP); animator.updateEndValue(endValue2); @@ -140,7 +140,7 @@ public class PipAnimationControllerTest extends SysuiTestCase { final Rect startValue = new Rect(0, 0, 100, 100); final Rect endValue = new Rect(100, 100, 200, 200); final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController - .getAnimator(mLeash, startValue, endValue, null); + .getAnimator(mLeash, startValue, endValue, null, TRANSITION_DIRECTION_TO_PIP); animator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new); animator.setPipAnimationCallback(mPipAnimationCallback);