Change PIP exit transition to a scale and uncrop
If there's a source hint rect available, perform an uncrop and scale animation from PIP -> Fullscreen similar to the enter transition. Bug: 167447693 Test: restore PIP to fullscreen, see scale and uncrop animation instead of squishiness Change-Id: Idce6d6d6d1f365f0a3adc5256a980066e721659e
This commit is contained in:
@@ -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<Rect> 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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
@@ -986,7 +986,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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user