Animate when removing PiP

Fade out the PiP window when PipTaskOrganizer#removePip is called, which
covers the following scenarios:
- Tap on the close button
- Drag the PiP window to close area
- Disable PiP via settings

Note that when dragging to remove, we spring also the window off screen
and therefore, the fade out animation does not really appealing in that
case.

Video is taken with 10x normal duration.

Video: http://rcll/aaaaaabFQoRHlzixHdtY/gZfSf7SaGKepwiqvXA15dx
Bug: 159805747
Test: see video
Change-Id: Icc26c81711bae69bd00a2812661c00fd93055a92
This commit is contained in:
Hongwei Wang
2020-07-14 15:26:32 -07:00
parent ba4faa0229
commit 925a102e10
3 changed files with 35 additions and 18 deletions

View File

@@ -21,7 +21,6 @@ import android.animation.Animator;
import android.animation.RectEvaluator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.content.Context;
import android.graphics.Rect;
import android.view.SurfaceControl;
@@ -56,13 +55,15 @@ public class PipAnimationController {
public static final int TRANSITION_DIRECTION_TO_PIP = 2;
public static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3;
public static final int TRANSITION_DIRECTION_TO_SPLIT_SCREEN = 4;
public static final int TRANSITION_DIRECTION_REMOVE_STACK = 5;
@IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = {
TRANSITION_DIRECTION_NONE,
TRANSITION_DIRECTION_SAME,
TRANSITION_DIRECTION_TO_PIP,
TRANSITION_DIRECTION_TO_FULLSCREEN,
TRANSITION_DIRECTION_TO_SPLIT_SCREEN
TRANSITION_DIRECTION_TO_SPLIT_SCREEN,
TRANSITION_DIRECTION_REMOVE_STACK
})
@Retention(RetentionPolicy.SOURCE)
public @interface TransitionDirection {}
@@ -88,7 +89,7 @@ public class PipAnimationController {
});
@Inject
PipAnimationController(Context context, PipSurfaceTransactionHelper helper) {
PipAnimationController(PipSurfaceTransactionHelper helper) {
mSurfaceTransactionHelper = helper;
}
@@ -338,6 +339,10 @@ public class PipAnimationController {
@Override
void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
if (getTransitionDirection() == TRANSITION_DIRECTION_REMOVE_STACK) {
// while removing the pip stack, no extra work needs to be done here.
return;
}
getSurfaceTransactionHelper()
.resetScale(tx, leash, getDestinationBounds())
.crop(tx, leash, getDestinationBounds())

View File

@@ -24,6 +24,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
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.TRANSITION_DIRECTION_NONE;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_REMOVE_STACK;
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;
@@ -337,23 +338,32 @@ public class PipTaskOrganizer extends TaskOrganizer implements
+ " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken);
return;
}
getUpdateHandler().post(() -> {
try {
// Reset the task bounds first to ensure the activity configuration is reset as well
final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mToken, null);
WindowOrganizer.applyTransaction(wct);
ActivityTaskManager.getService().removeStacksInWindowingModes(
new int[]{ WINDOWING_MODE_PINNED });
} catch (RemoteException e) {
Log.e(TAG, "Failed to remove PiP", e);
}
});
// removePipImmediately is expected when the following animation finishes.
mUpdateHandler.post(() -> mPipAnimationController
.getAnimator(mLeash, mLastReportedBounds, 1f, 0f)
.setTransitionDirection(TRANSITION_DIRECTION_REMOVE_STACK)
.setPipAnimationCallback(mPipAnimationCallback)
.setDuration(mEnterExitAnimationDuration)
.start());
mInitialState.remove(mToken.asBinder());
mExitingPip = true;
}
private void removePipImmediately() {
try {
// Reset the task bounds first to ensure the activity configuration is reset as well
final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setBounds(mToken, null);
WindowOrganizer.applyTransaction(wct);
ActivityTaskManager.getService().removeStacksInWindowingModes(
new int[]{ WINDOWING_MODE_PINNED });
} catch (RemoteException e) {
Log.e(TAG, "Failed to remove PiP", e);
}
}
@Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
Objects.requireNonNull(info, "Requires RunningTaskInfo");
@@ -803,7 +813,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements
+ "directly");
}
mLastReportedBounds.set(destinationBounds);
if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
if (direction == TRANSITION_DIRECTION_REMOVE_STACK) {
removePipImmediately();
return;
} else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
return;
}

View File

@@ -61,8 +61,7 @@ public class PipAnimationControllerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
mPipAnimationController = new PipAnimationController(
mContext, new PipSurfaceTransactionHelper(mContext,
mock(ConfigurationController.class)));
new PipSurfaceTransactionHelper(mContext, mock(ConfigurationController.class)));
mLeash = new SurfaceControl.Builder()
.setContainerLayer()
.setName("FakeLeash")