diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 8bfba9e7b715f..9437485165a0a 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -983,6 +983,9 @@ 30dp + + 8dp + 18dp 18dp diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java index 36b5fade1929d..67802bc9888d3 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java @@ -37,7 +37,6 @@ public class PipAnimationController { private static final float FRACTION_START = 0f; private static final float FRACTION_END = 1f; - public static final int DURATION_NONE = 0; public static final int DURATION_DEFAULT_MS = 425; public static final int ANIM_TYPE_BOUNDS = 0; public static final int ANIM_TYPE_ALPHA = 1; @@ -49,6 +48,20 @@ public class PipAnimationController { @Retention(RetentionPolicy.SOURCE) public @interface AnimationType {} + static final int TRANSITION_DIRECTION_NONE = 0; + static final int TRANSITION_DIRECTION_SAME = 1; + static final int TRANSITION_DIRECTION_TO_PIP = 2; + static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3; + + @IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = { + TRANSITION_DIRECTION_NONE, + TRANSITION_DIRECTION_SAME, + TRANSITION_DIRECTION_TO_PIP, + TRANSITION_DIRECTION_TO_FULLSCREEN + }) + @Retention(RetentionPolicy.SOURCE) + @interface TransitionDirection {} + private final Interpolator mFastOutSlowInInterpolator; private PipTransitionAnimator mCurrentAnimator; @@ -58,30 +71,28 @@ public class PipAnimationController { com.android.internal.R.interpolator.fast_out_slow_in); } - PipTransitionAnimator getAnimator(SurfaceControl leash, boolean scheduleFinishPip, + @SuppressWarnings("unchecked") + PipTransitionAnimator getAnimator(SurfaceControl leash, Rect destinationBounds, float alphaStart, float alphaEnd) { if (mCurrentAnimator == null) { mCurrentAnimator = setupPipTransitionAnimator( - PipTransitionAnimator.ofAlpha(leash, scheduleFinishPip, destinationBounds, - alphaStart, alphaEnd)); + PipTransitionAnimator.ofAlpha(leash, destinationBounds, alphaStart, alphaEnd)); } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA && mCurrentAnimator.isRunning()) { mCurrentAnimator.updateEndValue(alphaEnd); } else { mCurrentAnimator.cancel(); mCurrentAnimator = setupPipTransitionAnimator( - PipTransitionAnimator.ofAlpha(leash, scheduleFinishPip, destinationBounds, - alphaStart, alphaEnd)); + PipTransitionAnimator.ofAlpha(leash, destinationBounds, alphaStart, alphaEnd)); } return mCurrentAnimator; } - PipTransitionAnimator getAnimator(SurfaceControl leash, boolean scheduleFinishPip, - Rect startBounds, Rect endBounds) { + @SuppressWarnings("unchecked") + PipTransitionAnimator getAnimator(SurfaceControl leash, Rect startBounds, Rect endBounds) { if (mCurrentAnimator == null) { mCurrentAnimator = setupPipTransitionAnimator( - PipTransitionAnimator.ofBounds(leash, scheduleFinishPip, - startBounds, endBounds)); + PipTransitionAnimator.ofBounds(leash, startBounds, endBounds)); } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_BOUNDS && mCurrentAnimator.isRunning()) { mCurrentAnimator.setDestinationBounds(endBounds); @@ -90,8 +101,7 @@ public class PipAnimationController { } else { mCurrentAnimator.cancel(); mCurrentAnimator = setupPipTransitionAnimator( - PipTransitionAnimator.ofBounds(leash, scheduleFinishPip, - startBounds, endBounds)); + PipTransitionAnimator.ofBounds(leash, startBounds, endBounds)); } return mCurrentAnimator; } @@ -134,7 +144,6 @@ public class PipAnimationController { public abstract static class PipTransitionAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { - private final boolean mScheduleFinishPip; private final SurfaceControl mLeash; private final @AnimationType int mAnimationType; private final Rect mDestinationBounds = new Rect(); @@ -144,11 +153,11 @@ public class PipAnimationController { private T mCurrentValue; private PipAnimationCallback mPipAnimationCallback; private SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; + private @TransitionDirection int mTransitionDirection; + private int mCornerRadius; - private PipTransitionAnimator(SurfaceControl leash, boolean scheduleFinishPip, - @AnimationType int animationType, Rect destinationBounds, - T startValue, T endValue) { - mScheduleFinishPip = scheduleFinishPip; + private PipTransitionAnimator(SurfaceControl leash, @AnimationType int animationType, + Rect destinationBounds, T startValue, T endValue) { mLeash = leash; mAnimationType = animationType; mDestinationBounds.set(destinationBounds); @@ -157,6 +166,7 @@ public class PipAnimationController { addListener(this); addUpdateListener(this); mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; + mTransitionDirection = TRANSITION_DIRECTION_NONE; } @Override @@ -202,8 +212,15 @@ public class PipAnimationController { return this; } - boolean shouldScheduleFinishPip() { - return mScheduleFinishPip; + @TransitionDirection int getTransitionDirection() { + return mTransitionDirection; + } + + PipTransitionAnimator setTransitionDirection(@TransitionDirection int direction) { + if (direction != TRANSITION_DIRECTION_SAME) { + mTransitionDirection = direction; + } + return this; } T getStartValue() { @@ -226,6 +243,19 @@ public class PipAnimationController { mCurrentValue = value; } + int getCornerRadius() { + return mCornerRadius; + } + + PipTransitionAnimator setCornerRadius(int cornerRadius) { + mCornerRadius = cornerRadius; + return this; + } + + boolean shouldApplyCornerRadius() { + return mTransitionDirection != TRANSITION_DIRECTION_TO_FULLSCREEN; + } + /** * Updates the {@link #mEndValue}. * @@ -251,9 +281,9 @@ public class PipAnimationController { abstract void applySurfaceControlTransaction(SurfaceControl leash, SurfaceControl.Transaction tx, float fraction); - static PipTransitionAnimator ofAlpha(SurfaceControl leash, boolean scheduleFinishPip, + static PipTransitionAnimator ofAlpha(SurfaceControl leash, Rect destinationBounds, float startValue, float endValue) { - return new PipTransitionAnimator(leash, scheduleFinishPip, ANIM_TYPE_ALPHA, + return new PipTransitionAnimator(leash, ANIM_TYPE_ALPHA, destinationBounds, startValue, endValue) { @Override void applySurfaceControlTransaction(SurfaceControl leash, @@ -266,16 +296,18 @@ public class PipAnimationController { final Rect bounds = getDestinationBounds(); tx.setPosition(leash, bounds.left, bounds.top) .setWindowCrop(leash, bounds.width(), bounds.height()); + tx.setCornerRadius(leash, + shouldApplyCornerRadius() ? getCornerRadius() : 0); } tx.apply(); } }; } - static PipTransitionAnimator ofBounds(SurfaceControl leash, boolean scheduleFinishPip, + static PipTransitionAnimator ofBounds(SurfaceControl leash, Rect startValue, Rect endValue) { // construct new Rect instances in case they are recycled - return new PipTransitionAnimator(leash, scheduleFinishPip, ANIM_TYPE_BOUNDS, + return new PipTransitionAnimator(leash, ANIM_TYPE_BOUNDS, endValue, new Rect(startValue), new Rect(endValue)) { private final Rect mTmpRect = new Rect(); @@ -299,6 +331,8 @@ public class PipAnimationController { if (Float.compare(fraction, FRACTION_START) == 0) { // Ensure the start condition tx.setAlpha(leash, 1f); + tx.setCornerRadius(leash, + shouldApplyCornerRadius() ? getCornerRadius() : 0); } 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 4766ebce1743e..3933af00a47a8 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -19,6 +19,10 @@ package com.android.systemui.pip; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_BOUNDS; import static com.android.systemui.pip.PipAnimationController.DURATION_DEFAULT_MS; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_NONE; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_SAME; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP; import android.annotation.NonNull; import android.annotation.Nullable; @@ -30,7 +34,6 @@ import android.content.Context; import android.graphics.Rect; import android.os.Handler; import android.os.Looper; -import android.os.Message; import android.os.RemoteException; import android.util.Log; import android.view.DisplayInfo; @@ -40,6 +43,7 @@ import android.view.SurfaceControl; import android.view.WindowContainerTransaction; import com.android.internal.os.SomeArgs; +import com.android.systemui.R; import com.android.systemui.pip.phone.PipUpdateThread; import java.util.ArrayList; @@ -74,6 +78,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { private final List mPipTransitionCallbacks = new ArrayList<>(); private final Rect mDisplayBounds = new Rect(); private final Rect mLastReportedBounds = new Rect(); + private final int mCornerRadius; // These callbacks are called on the update thread private final PipAnimationController.PipAnimationCallback mPipAnimationCallback = @@ -97,7 +102,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { callback.onPipTransitionFinished(); } }); - finishResize(animator.getDestinationBounds(), tx, animator.shouldScheduleFinishPip()); + finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection()); } @Override @@ -111,57 +116,53 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } }; - private Handler.Callback mUpdateCallbacks = new Handler.Callback() { - @Override - public boolean handleMessage(Message msg) { - SomeArgs args = (SomeArgs) msg.obj; - Consumer updateBoundsCallback = (Consumer) args.arg1; - switch (msg.what) { - case MSG_RESIZE_IMMEDIATE: { - Rect toBounds = (Rect) args.arg2; - resizePip(toBounds); - if (updateBoundsCallback != null) { - updateBoundsCallback.accept(toBounds); - } - break; - } - case MSG_RESIZE_ANIMATE: { - Rect currentBounds = (Rect) args.arg2; - Rect toBounds = (Rect) args.arg3; - boolean scheduleFinishPip = args.argi1 != 0; - int duration = args.argi2; - animateResizePip(scheduleFinishPip, currentBounds, toBounds, duration); - if (updateBoundsCallback != null) { - updateBoundsCallback.accept(toBounds); - } - break; - } - case MSG_OFFSET_ANIMATE: { - Rect originalBounds = (Rect) args.arg2; - final int offset = args.argi1; - final int duration = args.argi2; - offsetPip(originalBounds, 0 /* xOffset */, offset, duration); - Rect toBounds = new Rect(originalBounds); - toBounds.offset(0, offset); - if (updateBoundsCallback != null) { - updateBoundsCallback.accept(toBounds); - } - break; - } - case MSG_FINISH_RESIZE: { - SurfaceControl.Transaction tx = (SurfaceControl.Transaction) args.arg2; - Rect toBounds = (Rect) args.arg3; - boolean scheduleFinishPip = args.argi1 != 0; - finishResize(toBounds, tx, scheduleFinishPip); - if (updateBoundsCallback != null) { - updateBoundsCallback.accept(toBounds); - } - break; + @SuppressWarnings("unchecked") + private Handler.Callback mUpdateCallbacks = (msg) -> { + SomeArgs args = (SomeArgs) msg.obj; + Consumer updateBoundsCallback = (Consumer) args.arg1; + switch (msg.what) { + case MSG_RESIZE_IMMEDIATE: { + Rect toBounds = (Rect) args.arg2; + resizePip(toBounds); + if (updateBoundsCallback != null) { + updateBoundsCallback.accept(toBounds); } + break; + } + case MSG_RESIZE_ANIMATE: { + Rect currentBounds = (Rect) args.arg2; + Rect toBounds = (Rect) args.arg3; + int duration = args.argi2; + animateResizePip(currentBounds, toBounds, args.argi1 /* direction */, duration); + if (updateBoundsCallback != null) { + updateBoundsCallback.accept(toBounds); + } + break; + } + case MSG_OFFSET_ANIMATE: { + Rect originalBounds = (Rect) args.arg2; + final int offset = args.argi1; + final int duration = args.argi2; + offsetPip(originalBounds, 0 /* xOffset */, offset, duration); + Rect toBounds = new Rect(originalBounds); + toBounds.offset(0, offset); + if (updateBoundsCallback != null) { + updateBoundsCallback.accept(toBounds); + } + break; + } + case MSG_FINISH_RESIZE: { + SurfaceControl.Transaction tx = (SurfaceControl.Transaction) args.arg2; + Rect toBounds = (Rect) args.arg3; + finishResize(tx, toBounds, args.argi1 /* direction */); + if (updateBoundsCallback != null) { + updateBoundsCallback.accept(toBounds); + } + break; } - args.recycle(); - return true; } + args.recycle(); + return true; }; private ActivityManager.RunningTaskInfo mTaskInfo; @@ -176,6 +177,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mTaskOrganizerController = ActivityTaskManager.getTaskOrganizerController(); mPipBoundsHandler = boundsHandler; mPipAnimationController = new PipAnimationController(context); + mCornerRadius = context.getResources().getDimensionPixelSize(R.dimen.pip_corner_radius); } public Handler getUpdateHandler() { @@ -191,7 +193,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { /** * Sets the preferred animation type for one time. - * This is typically used to set the animation type to {@link #ANIM_TYPE_ALPHA}. + * This is typically used to set the animation type to + * {@link PipAnimationController#ANIM_TYPE_ALPHA}. */ public void setOneShotAnimationType(@PipAnimationController.AnimationType int animationType) { mOneShotAnimationType = animationType; @@ -200,13 +203,14 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { /** * Updates the display dimension with given {@link DisplayInfo} */ + @SuppressWarnings("unchecked") public void onDisplayInfoChanged(DisplayInfo displayInfo) { final Rect newDisplayBounds = new Rect(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); if (!mDisplayBounds.equals(newDisplayBounds)) { // Updates the exiting PiP animation in case the screen rotation changes in the middle. // It's a legit case that PiP window is in portrait mode on home screen and - // the application requests landscape onces back to fullscreen mode. + // the application requests landscape once back to fullscreen mode. final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController.getCurrentAnimator(); if (animator != null @@ -250,12 +254,13 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) { final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); - scheduleAnimateResizePip(true /* scheduleFinishPip */, - currentBounds, destinationBounds, DURATION_DEFAULT_MS, null); + scheduleAnimateResizePip(currentBounds, destinationBounds, + TRANSITION_DIRECTION_TO_PIP, DURATION_DEFAULT_MS, null); } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { mUpdateHandler.post(() -> mPipAnimationController - .getAnimator(mLeash, true /* scheduleFinishPip */, - destinationBounds, 0f, 1f) + .getAnimator(mLeash, destinationBounds, 0f, 1f) + .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP) + .setCornerRadius(mCornerRadius) .setPipAnimationCallback(mPipAnimationCallback) .setDuration(DURATION_DEFAULT_MS) .start()); @@ -272,7 +277,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { Log.wtf(TAG, "Unrecognized token: " + token); return; } - scheduleAnimateResizePip(mDisplayBounds, DURATION_DEFAULT_MS, null); + scheduleAnimateResizePip(mLastReportedBounds, mDisplayBounds, + TRANSITION_DIRECTION_TO_FULLSCREEN, DURATION_DEFAULT_MS, null); mInPip = false; } @@ -310,12 +316,12 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { */ public void scheduleAnimateResizePip(Rect toBounds, int duration, Consumer updateBoundsCallback) { - scheduleAnimateResizePip(false /* scheduleFinishPip */, - mLastReportedBounds, toBounds, duration, updateBoundsCallback); + scheduleAnimateResizePip(mLastReportedBounds, toBounds, + TRANSITION_DIRECTION_NONE, duration, updateBoundsCallback); } - private void scheduleAnimateResizePip(boolean scheduleFinishPip, - Rect currentBounds, Rect destinationBounds, int durationMs, + private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds, + @PipAnimationController.TransitionDirection int direction, int durationMs, Consumer updateBoundsCallback) { Objects.requireNonNull(mToken, "Requires valid IWindowContainer"); if (!mInPip) { @@ -326,7 +332,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { args.arg1 = updateBoundsCallback; args.arg2 = currentBounds; args.arg3 = destinationBounds; - args.argi1 = scheduleFinishPip ? 1 : 0; + args.argi1 = direction; args.argi2 = durationMs; mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_RESIZE_ANIMATE, args)); } @@ -351,25 +357,25 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { Objects.requireNonNull(mToken, "Requires valid IWindowContainer"); SurfaceControl.Transaction tx = new SurfaceControl.Transaction() .setPosition(mLeash, destinationBounds.left, destinationBounds.top) - .setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height()); - scheduleFinishResizePip(tx, destinationBounds, false /* scheduleFinishPip */, - null); + .setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height()) + .setCornerRadius(mLeash, mInPip ? mCornerRadius : 0); + scheduleFinishResizePip(tx, destinationBounds, TRANSITION_DIRECTION_NONE, null); } private void scheduleFinishResizePip(SurfaceControl.Transaction tx, - Rect destinationBounds, boolean scheduleFinishPip, + Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, Consumer updateBoundsCallback) { Objects.requireNonNull(mToken, "Requires valid IWindowContainer"); SomeArgs args = SomeArgs.obtain(); args.arg1 = updateBoundsCallback; args.arg2 = tx; args.arg3 = destinationBounds; - args.argi1 = scheduleFinishPip ? 1 : 0; + args.argi1 = direction; mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_FINISH_RESIZE, args)); } /** - * Offset the PiP window, animate if the given duration is not {@link #DURATION_NONE} + * Offset the PiP window by a given offset on Y-axis, triggered also from screen rotation. */ public void scheduleOffsetPip(Rect originalBounds, int offset, int duration, Consumer updateBoundsCallback) { @@ -398,8 +404,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } final Rect destinationBounds = new Rect(originalBounds); destinationBounds.offset(xOffset, yOffset); - animateResizePip(false /* scheduleFinishPip*/, originalBounds, destinationBounds, - durationMs); + animateResizePip(originalBounds, destinationBounds, TRANSITION_DIRECTION_SAME, durationMs); } private void resizePip(Rect destinationBounds) { @@ -416,11 +421,12 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { new SurfaceControl.Transaction() .setPosition(mLeash, destinationBounds.left, destinationBounds.top) .setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height()) + .setCornerRadius(mLeash, mInPip ? mCornerRadius : 0) .apply(); } - private void finishResize(Rect destinationBounds, SurfaceControl.Transaction tx, - boolean shouldScheduleFinishPip) { + private void finishResize(SurfaceControl.Transaction tx, Rect destinationBounds, + @PipAnimationController.TransitionDirection int direction) { if (Looper.myLooper() != mUpdateHandler.getLooper()) { throw new RuntimeException("Callers should call scheduleResizePip() instead of this " + "directly"); @@ -428,7 +434,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mLastReportedBounds.set(destinationBounds); try { final WindowContainerTransaction wct = new WindowContainerTransaction(); - if (shouldScheduleFinishPip) { + if (direction == TRANSITION_DIRECTION_TO_PIP) { wct.scheduleFinishEnterPip(mToken, destinationBounds); } else { wct.setBounds(mToken, destinationBounds); @@ -440,8 +446,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } } - private void animateResizePip(boolean scheduleFinishPip, Rect currentBounds, - Rect destinationBounds, int durationMs) { + private void animateResizePip(Rect currentBounds, Rect destinationBounds, + @PipAnimationController.TransitionDirection int direction, int durationMs) { if (Looper.myLooper() != mUpdateHandler.getLooper()) { throw new RuntimeException("Callers should call scheduleAnimateResizePip() instead of " + "this directly"); @@ -452,7 +458,9 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { return; } mUpdateHandler.post(() -> mPipAnimationController - .getAnimator(mLeash, scheduleFinishPip, currentBounds, destinationBounds) + .getAnimator(mLeash, currentBounds, destinationBounds) + .setTransitionDirection(direction) + .setCornerRadius(mCornerRadius) .setPipAnimationCallback(mPipAnimationCallback) .setDuration(durationMs) .start()); 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 cd461101e3c4b..a2ab78483b686 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java @@ -16,9 +16,10 @@ package com.android.systemui.pip; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP; + import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; @@ -64,7 +65,7 @@ public class PipAnimationControllerTest extends SysuiTestCase { @Test public void getAnimator_withAlpha_returnFloatAnimator() { final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController - .getAnimator(mLeash, true /* scheduleFinishPip */, new Rect(), 0f, 1f); + .getAnimator(mLeash, new Rect(), 0f, 1f); assertEquals("Expect ANIM_TYPE_ALPHA animation", animator.getAnimationType(), PipAnimationController.ANIM_TYPE_ALPHA); @@ -73,7 +74,7 @@ public class PipAnimationControllerTest extends SysuiTestCase { @Test public void getAnimator_withBounds_returnBoundsAnimator() { final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController - .getAnimator(mLeash, true /* scheduleFinishPip */, new Rect(), new Rect()); + .getAnimator(mLeash, new Rect(), new Rect()); assertEquals("Expect ANIM_TYPE_BOUNDS animation", animator.getAnimationType(), PipAnimationController.ANIM_TYPE_BOUNDS); @@ -85,12 +86,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, true /* scheduleFinishPip */, startValue, endValue1); + .getAnimator(mLeash, startValue, endValue1); oldAnimator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new); oldAnimator.start(); final PipAnimationController.PipTransitionAnimator newAnimator = mPipAnimationController - .getAnimator(mLeash, true /* scheduleFinishPip */, startValue, endValue2); + .getAnimator(mLeash, startValue, endValue2); assertEquals("getAnimator with same type returns same animator", oldAnimator, newAnimator); @@ -99,23 +100,28 @@ public class PipAnimationControllerTest extends SysuiTestCase { } @Test - public void getAnimator_scheduleFinishPip() { + public void getAnimator_setTransitionDirection() { PipAnimationController.PipTransitionAnimator animator = mPipAnimationController - .getAnimator(mLeash, true /* scheduleFinishPip */, new Rect(), 0f, 1f); - assertTrue("scheduleFinishPip is true", animator.shouldScheduleFinishPip()); + .getAnimator(mLeash, new Rect(), 0f, 1f) + .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP); + assertEquals("Transition to PiP mode", + animator.getTransitionDirection(), TRANSITION_DIRECTION_TO_PIP); animator = mPipAnimationController - .getAnimator(mLeash, false /* scheduleFinishPip */, new Rect(), 0f, 1f); - assertFalse("scheduleFinishPip is false", animator.shouldScheduleFinishPip()); + .getAnimator(mLeash, new Rect(), 0f, 1f) + .setTransitionDirection(TRANSITION_DIRECTION_TO_FULLSCREEN); + assertEquals("Transition to fullscreen mode", + animator.getTransitionDirection(), TRANSITION_DIRECTION_TO_FULLSCREEN); } @Test + @SuppressWarnings("unchecked") public void pipTransitionAnimator_updateEndValue() { final Rect startValue = new Rect(0, 0, 100, 100); 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, true /* scheduleFinishPip */, startValue, endValue1); + .getAnimator(mLeash, startValue, endValue1); animator.updateEndValue(endValue2); @@ -127,7 +133,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, true /* scheduleFinishPip */, startValue, endValue); + .getAnimator(mLeash, startValue, endValue); animator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new); animator.setPipAnimationCallback(mPipAnimationCallback); @@ -166,6 +172,11 @@ public class PipAnimationControllerTest extends SysuiTestCase { return this; } + @Override + public SurfaceControl.Transaction setCornerRadius(SurfaceControl leash, float radius) { + return this; + } + @Override public void apply() {} }