diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 00494611420d3..ee0a1b3e34877 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -423,6 +423,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // Set the exiting state first so if there is fixed rotation later, the running animation // won't be interrupted by alpha animation for existing PiP. mState = State.EXITING_PIP; + + if (Transitions.ENABLE_SHELL_TRANSITIONS) { + mPipTransitionController.startTransition(destinationBounds, wct); + return; + } mSyncTransactionQueue.queue(wct); mSyncTransactionQueue.runInSync(t -> { // Make sure to grab the latest source hint rect as it could have been diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 88ee9c9ef7ed5..7581dfaaa1103 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -25,6 +25,7 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP; import static com.android.wm.shell.pip.PipAnimationController.isInPipDirection; import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection; +import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; import android.app.TaskInfo; import android.content.Context; @@ -53,6 +54,7 @@ public class PipTransition extends PipTransitionController { private final int mEnterExitAnimationDuration; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private Transitions.TransitionFinishCallback mFinishCallback; + private Rect mExitDestinationBounds = new Rect(); public PipTransition(Context context, PipBoundsState pipBoundsState, PipMenuController pipMenuController, @@ -66,12 +68,28 @@ public class PipTransition extends PipTransitionController { .getInteger(R.integer.config_pipResizeAnimationDuration); } + @Override + public void startTransition(Rect destinationBounds, WindowContainerTransaction out) { + mExitDestinationBounds.set(destinationBounds); + mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this); + } + @Override public boolean startAnimation(@android.annotation.NonNull IBinder transition, @android.annotation.NonNull TransitionInfo info, @android.annotation.NonNull SurfaceControl.Transaction startTransaction, @android.annotation.NonNull SurfaceControl.Transaction finishTransaction, @android.annotation.NonNull Transitions.TransitionFinishCallback finishCallback) { + + if (info.getType() == TRANSIT_EXIT_PIP && info.getChanges().size() == 1) { + final TransitionInfo.Change change = info.getChanges().get(0); + mFinishCallback = finishCallback; + boolean success = startExpandAnimation(change.getTaskInfo(), change.getLeash(), + new Rect(mExitDestinationBounds)); + mExitDestinationBounds.setEmpty(); + return success; + } + for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getTaskInfo() != null @@ -109,6 +127,21 @@ public class PipTransition extends PipTransitionController { finishResizeForMenu(destinationBounds); } + private boolean startExpandAnimation(final TaskInfo taskInfo, final SurfaceControl leash, + final Rect destinationBounds) { + PipAnimationController.PipTransitionAnimator animator = + mPipAnimationController.getAnimator(taskInfo, leash, mPipBoundsState.getBounds(), + mPipBoundsState.getBounds(), destinationBounds, null, + TRANSITION_DIRECTION_LEAVE_PIP, 0 /* startingAngle */, Surface.ROTATION_0); + + animator.setTransitionDirection(TRANSITION_DIRECTION_LEAVE_PIP) + .setPipAnimationCallback(mPipAnimationCallback) + .setDuration(mEnterExitAnimationDuration) + .start(); + + return true; + } + private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash, final SurfaceControl.Transaction startTransaction, final SurfaceControl.Transaction finishTransaction) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java index d801c918973a9..bc262560844df 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.os.Handler; import android.os.Looper; import android.view.SurfaceControl; +import android.window.WindowContainerTransaction; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.transition.Transitions; @@ -46,6 +47,7 @@ public abstract class PipTransitionController implements Transitions.TransitionH protected final PipBoundsState mPipBoundsState; protected final ShellTaskOrganizer mShellTaskOrganizer; protected final PipMenuController mPipMenuController; + protected final Transitions mTransitions; private final Handler mMainHandler; private final List mPipTransitionCallbacks = new ArrayList<>(); @@ -98,6 +100,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH SurfaceControl.Transaction tx) { } + /** + * Called when the Shell wants to starts a transition/animation. + */ + public void startTransition(Rect destinationBounds, WindowContainerTransaction out) { + // Default implementation does nothing. + } + public PipTransitionController(PipBoundsState pipBoundsState, PipMenuController pipMenuController, PipBoundsAlgorithm pipBoundsAlgorithm, PipAnimationController pipAnimationController, Transitions transitions, @@ -107,6 +116,7 @@ public abstract class PipTransitionController implements Transitions.TransitionH mShellTaskOrganizer = shellTaskOrganizer; mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipAnimationController = pipAnimationController; + mTransitions = transitions; mMainHandler = new Handler(Looper.getMainLooper()); if (Transitions.ENABLE_SHELL_TRANSITIONS) { transitions.addHandler(this); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index 81309431f3962..64faed2061091 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -77,6 +77,9 @@ public class Transitions implements RemoteCallable { /** Transition type for launching 2 tasks simultaneously. */ public static final int TRANSIT_SPLIT_SCREEN_PAIR_OPEN = TRANSIT_FIRST_CUSTOM + 2; + /** Transition type for exiting PIP via the Shell, either via Expand or Dismiss. */ + public static final int TRANSIT_EXIT_PIP = TRANSIT_FIRST_CUSTOM + 3; + private final WindowOrganizer mOrganizer; private final Context mContext; private final ShellExecutor mMainExecutor;