diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6b0a73b..1c2a6aa 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10535,8 +10535,9 @@
                         final PinnedActivityStack pinnedStack =
                                 mStackSupervisor.getStack(PINNED_STACK_ID);
                         if (pinnedStack != null) {
-                            pinnedStack.animateResizePinnedStack(null /* sourceBounds */,
-                                    destBounds, animationDuration);
+                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
+                                    destBounds, animationDuration,
+                                    false /* schedulePipModeChangedOnAnimationEnd */);
                         }
                     } else {
                         throw new IllegalArgumentException("Stack: " + stackId
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 4c84d98..825e8ac 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -589,6 +589,13 @@
     }
 
     /**
+     * Returns whether to defer the scheduling of the multi-window mode.
+     */
+    boolean deferScheduleMultiWindowModeChanged() {
+        return false;
+    }
+
+    /**
      * Defers updating the bounds of the stack. If the stack was resized/repositioned while
      * deferring, the bounds will update in {@link #continueUpdateBounds()}.
      */
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 4d16e33..43ae4b2 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2504,7 +2504,7 @@
         // incorrect if AMS.resizeStackWithBoundsFromWindowManager() is already called while waiting
         // for the AMS lock to be freed. So check and make sure these bounds are still good.
         final PinnedStackWindowController stackController = stack.getWindowContainerController();
-        if (stackController.pinnedStackResizeAllowed()) {
+        if (stackController.pinnedStackResizeDisallowed()) {
             return;
         }
 
@@ -2873,7 +2873,7 @@
         return true;
     }
 
-    void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceBounds, float aspectRatio,
+    void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
             boolean moveHomeStackToFront, String reason) {
 
         mWindowManager.deferSurfaceLayout();
@@ -2948,11 +2948,8 @@
         final Rect destBounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
                 aspectRatio, false /* useExistingStackBounds */);
 
-        // TODO(b/36099777): Schedule the PiP mode change here immediately until we can defer all
-        // callbacks until after the bounds animation
-        scheduleUpdatePictureInPictureModeIfNeeded(r.getTask(), destBounds, true /* immediate */);
-
-        stack.animateResizePinnedStack(sourceBounds, destBounds, -1 /* animationDuration */);
+        stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
+                true /* schedulePipModeChangedOnAnimationEnd */);
         mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName);
     }
 
@@ -4179,6 +4176,12 @@
     }
 
     void scheduleUpdateMultiWindowMode(TaskRecord task) {
+        // If the stack is animating in a way where we will be forcing a multi-mode change at the
+        // end, then ensure that we defer all in between multi-window mode changes
+        if (task.getStack().deferScheduleMultiWindowModeChanged()) {
+            return;
+        }
+
         for (int i = task.mActivities.size() - 1; i >= 0; i--) {
             final ActivityRecord r = task.mActivities.get(i);
             if (r.app != null && r.app.thread != null) {
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index cd9c42c..a4932bb 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -43,9 +43,10 @@
         return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds);
     }
 
-    void animateResizePinnedStack(Rect sourceBounds, Rect destBounds, int animationDuration) {
-        getWindowContainerController().animateResizePinnedStack(sourceBounds, destBounds,
-                animationDuration);
+    void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration,
+            boolean schedulePipModeChangedOnAnimationEnd) {
+        getWindowContainerController().animateResizePinnedStack(toBounds, sourceHintBounds,
+                animationDuration, schedulePipModeChangedOnAnimationEnd);
     }
 
     void setPictureInPictureAspectRatio(float aspectRatio) {
@@ -60,7 +61,18 @@
         return getWindowContainerController().isAnimatingBoundsToFullscreen();
     }
 
-    @Override
+    /**
+     * Returns whether to defer the scheduling of the multi-window mode.
+     */
+    boolean deferScheduleMultiWindowModeChanged() {
+        // For the pinned stack, the deferring of the multi-window mode changed is tied to the
+        // transition animation into picture-in-picture, and is called once the animation completes,
+        // or is interrupted in a way that would leave the stack in a non-fullscreen state.
+        // @see BoundsAnimationController
+        // @see BoundsAnimationControllerTests
+        return mWindowContainerController.deferScheduleMultiWindowModeChanged();
+    }
+
     public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
         // It is guaranteed that the activities requiring the update will be in the pinned stack at
         // this point (either reparented before the animation into PiP, or before reparenting after
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index f41eed5..e634552 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -22,6 +22,7 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
+import android.annotation.IntDef;
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Handler;
@@ -35,6 +36,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Enables animating bounds of objects.
  *
@@ -43,7 +47,7 @@
  * relaunching it would cause poorer experience), these class provides a way to directly animate
  * the bounds of the resized object.
  *
- * The object that is resized needs to implement {@link AnimateBoundsUser} interface.
+ * The object that is resized needs to implement {@link BoundsAnimationTarget} interface.
  *
  * NOTE: All calls to methods in this class should be done on the UI thread
  */
@@ -56,8 +60,19 @@
 
     private static final int DEFAULT_TRANSITION_DURATION = 425;
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NO_PIP_MODE_CHANGED_CALLBACKS, SCHEDULE_PIP_MODE_CHANGED_ON_START,
+        SCHEDULE_PIP_MODE_CHANGED_ON_END})
+    public @interface SchedulePipModeChangedState {}
+    /** Do not schedule any PiP mode changed callbacks as a part of this animation. */
+    public static final int NO_PIP_MODE_CHANGED_CALLBACKS = 0;
+    /** Schedule a PiP mode changed callback when this animation starts. */
+    public static final int SCHEDULE_PIP_MODE_CHANGED_ON_START = 1;
+    /** Schedule a PiP mode changed callback when this animation ends. */
+    public static final int SCHEDULE_PIP_MODE_CHANGED_ON_END = 2;
+
     // Only accessed on UI thread.
-    private ArrayMap<AnimateBoundsUser, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
+    private ArrayMap<BoundsAnimationTarget, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
 
     private final class AppTransitionNotifier
             extends WindowManagerInternal.AppTransitionListener implements Runnable {
@@ -108,40 +123,42 @@
     @VisibleForTesting
     final class BoundsAnimator extends ValueAnimator
             implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
-        private final AnimateBoundsUser mTarget;
+        private final BoundsAnimationTarget mTarget;
         private final Rect mFrom = new Rect();
         private final Rect mTo = new Rect();
         private final Rect mTmpRect = new Rect();
         private final Rect mTmpTaskBounds = new Rect();
-        private final boolean mMoveToFullScreen;
-        // True if this this animation was cancelled and will be replaced the another animation from
-        // the same {@link #AnimateBoundsUser} target.
+
+        // True if this this animation was canceled and will be replaced the another animation from
+        // the same {@link #BoundsAnimationTarget} target.
         private boolean mSkipFinalResize;
         // True if this animation replaced a previous animation of the same
-        // {@link #AnimateBoundsUser} target.
+        // {@link #BoundsAnimationTarget} target.
         private final boolean mSkipAnimationStart;
-        // True if this animation was cancelled by the user, not as a part of a replacing animation
+        // True if this animation was canceled by the user, not as a part of a replacing animation
         private boolean mSkipAnimationEnd;
-        // True if this animation is not replacing a previous animation, or if the previous
-        // animation is animating to a different fullscreen state than the current animation.
-        // We use this to ensure that we always provide a consistent set/order of callbacks when we
-        // transition to/from PiP.
-        private final boolean mAnimatingToNewFullscreenState;
+        // True if the animation target should be moved to the fullscreen stack at the end of this
+        // animation
+        private boolean mMoveToFullscreen;
+
+        // Whether to schedule PiP mode changes on animation start/end
+        private @SchedulePipModeChangedState int mSchedulePipModeChangedState;
 
         // Depending on whether we are animating from
         // a smaller to a larger size
         private final int mFrozenTaskWidth;
         private final int mFrozenTaskHeight;
 
-        BoundsAnimator(AnimateBoundsUser target, Rect from, Rect to, boolean moveToFullScreen,
-                boolean replacingExistingAnimation, boolean animatingToNewFullscreenState) {
+        BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to,
+                @SchedulePipModeChangedState int schedulePipModeChangedState,
+                boolean moveToFullscreen, boolean replacingExistingAnimation) {
             super();
             mTarget = target;
             mFrom.set(from);
             mTo.set(to);
-            mMoveToFullScreen = moveToFullScreen;
             mSkipAnimationStart = replacingExistingAnimation;
-            mAnimatingToNewFullscreenState = animatingToNewFullscreenState;
+            mSchedulePipModeChangedState = schedulePipModeChangedState;
+            mMoveToFullscreen = moveToFullscreen;
             addUpdateListener(this);
             addListener(this);
 
@@ -161,7 +178,8 @@
         @Override
         public void onAnimationStart(Animator animation) {
             if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
-                    + " mSkipAnimationStart=" + mSkipAnimationStart);
+                    + " mSkipAnimationStart=" + mSkipAnimationStart
+                    + " mSchedulePipModeChangedState=" + mSchedulePipModeChangedState);
             mFinishAnimationAfterTransition = false;
             mTmpRect.set(mFrom.left, mFrom.top, mFrom.left + mFrozenTaskWidth,
                     mFrom.top + mFrozenTaskHeight);
@@ -170,13 +188,8 @@
             // we trigger any size changes, so it can swap surfaces
             // in to appropriate modes, or do as it wishes otherwise.
             if (!mSkipAnimationStart) {
-                mTarget.onAnimationStart(mMoveToFullScreen);
-            }
-
-            // If we are animating to a new fullscreen state (either to/from fullscreen), then
-            // notify the target of the change with the new frozen task bounds
-            if (mAnimatingToNewFullscreenState && mMoveToFullScreen) {
-                mTarget.updatePictureInPictureMode(null);
+                mTarget.onAnimationStart(mSchedulePipModeChangedState ==
+                        SCHEDULE_PIP_MODE_CHANGED_ON_START);
             }
 
             // Immediately update the task bounds if they have to become larger, but preserve
@@ -206,20 +219,26 @@
                 // any further animation.
                 if (DEBUG) Slog.d(TAG, "animateUpdate: cancelled");
 
+                // If we have already scheduled a PiP mode changed at the start of the animation,
+                // then we need to clean up and schedule one at the end, since we have canceled the
+                // animation to the final state.
+                if (mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                    mSchedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
+                }
+
                 // Since we are cancelling immediately without a replacement animation, send the
                 // animation end to maintain callback parity, but also skip any further resizes
-                prepareCancel(false /* skipAnimationEnd */, true /* skipFinalResize */);
-                cancel();
+                cancelAndCallAnimationEnd();
             }
         }
 
         @Override
         public void onAnimationEnd(Animator animation) {
             if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
-                    + " mMoveToFullScreen=" + mMoveToFullScreen
                     + " mSkipFinalResize=" + mSkipFinalResize
                     + " mFinishAnimationAfterTransition=" + mFinishAnimationAfterTransition
-                    + " mAppTransitionIsRunning=" + mAppTransition.isRunning());
+                    + " mAppTransitionIsRunning=" + mAppTransition.isRunning()
+                    + " callers=" + Debug.getCallers(2));
 
             // There could be another animation running. For example in the
             // move to fullscreen case, recents will also be closing while the
@@ -231,58 +250,57 @@
                 return;
             }
 
-            if (!mSkipFinalResize) {
-                // If not cancelled, resize the pinned stack to the final size. All calls to
-                // setPinnedStackSize() must be done between onAnimationStart() and onAnimationEnd()
-                mTarget.setPinnedStackSize(mTo, null);
+            if (!mSkipAnimationEnd) {
+                // If this animation has already scheduled the picture-in-picture mode on start, and
+                // we are not skipping the final resize due to being canceled, then move the PiP to
+                // fullscreen once the animation ends
+                if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
+                        + " moveToFullscreen=" + mMoveToFullscreen);
+                mTarget.onAnimationEnd(mSchedulePipModeChangedState ==
+                        SCHEDULE_PIP_MODE_CHANGED_ON_END, !mSkipFinalResize ? mTo : null,
+                                mMoveToFullscreen);
             }
 
-            finishAnimation();
-
-            if (mMoveToFullScreen && !mSkipFinalResize) {
-                mTarget.moveToFullscreen();
-            }
+            // Clean up this animation
+            removeListener(this);
+            removeUpdateListener(this);
+            mRunningAnimations.remove(mTarget);
         }
 
         @Override
         public void onAnimationCancel(Animator animation) {
-            finishAnimation();
+            // Always skip the final resize when the animation is canceled
+            mSkipFinalResize = true;
+            mMoveToFullscreen = false;
         }
 
-        public void prepareCancel(boolean skipAnimationEnd, boolean skipFinalResize) {
-            if (DEBUG) Slog.d(TAG, "prepareCancel: skipAnimationEnd=" + skipAnimationEnd
-                    + " skipFinalResize=" + skipFinalResize);
-            mSkipAnimationEnd = skipAnimationEnd;
-            mSkipFinalResize = skipFinalResize;
+        private void cancelAndCallAnimationEnd() {
+            if (DEBUG) Slog.d(TAG, "cancelAndCallAnimationEnd: mTarget=" + mTarget);
+            mSkipAnimationEnd = false;
+            super.cancel();
         }
 
         @Override
         public void cancel() {
             if (DEBUG) Slog.d(TAG, "cancel: mTarget=" + mTarget);
+            mSkipAnimationEnd = true;
             super.cancel();
         }
 
-        /** Returns true if the animation target is the same as the input bounds. */
+        /**
+         * @return true if the animation target is the same as the input bounds.
+         */
         boolean isAnimatingTo(Rect bounds) {
             return mTo.equals(bounds);
         }
 
-        private boolean animatingToLargerSize() {
-            if (mFrom.width() * mFrom.height() > mTo.width() * mTo.height()) {
-                return false;
-            }
-            return true;
-        }
-
-        private void finishAnimation() {
-            if (DEBUG) Slog.d(TAG, "finishAnimation: mTarget=" + mTarget
-                    + " callers" + Debug.getCallers(2));
-            if (!mSkipAnimationEnd) {
-                mTarget.onAnimationEnd();
-            }
-            removeListener(this);
-            removeUpdateListener(this);
-            mRunningAnimations.remove(mTarget);
+        /**
+         * @return true if we are animating to a larger surface size
+         */
+        @VisibleForTesting
+        boolean animatingToLargerSize() {
+            // TODO: Fix this check for aspect ratio changes
+            return (mFrom.width() * mFrom.height() <= mTo.width() * mTo.height());
         }
 
         @Override
@@ -291,63 +309,23 @@
         }
     }
 
-    public interface AnimateBoundsUser {
-        /**
-         * Sets the size of the target (without any intermediate steps, like scheduling animation)
-         * but freezes the bounds of any tasks in the target at taskBounds,
-         * to allow for more flexibility during resizing. Only works for the pinned stack at the
-         * moment.
-         *
-         * @return Whether the target should continue to be animated and this call was successful.
-         * If false, the animation will be cancelled because the user has determined that the
-         * animation is now invalid and not required. In such a case, the cancel will trigger the
-         * animation end callback as well, but will not send any further size changes.
-         */
-        boolean setPinnedStackSize(Rect bounds, Rect taskBounds);
-
-        /**
-         * Callback for the target to inform it that the animation has started, so it can do some
-         * necessary preparation.
-         */
-        void onAnimationStart(boolean toFullscreen);
-
-        /**
-         * Callback for the target to inform it that the animation is going to a new fullscreen
-         * state and should update the picture-in-picture mode accordingly.
-         *
-         * @param targetStackBounds the target stack bounds we are animating to, can be null if
-         *                          we are animating to fullscreen
-         */
-        void updatePictureInPictureMode(Rect targetStackBounds);
-
-        /**
-         * Callback for the target to inform it that the animation has ended, so it can do some
-         * necessary cleanup.
-         */
-        void onAnimationEnd();
-
-        /**
-         * Callback for the target to inform it to reparent to the fullscreen stack.
-         */
-        void moveToFullscreen();
-    }
-
-    public void animateBounds(final AnimateBoundsUser target, Rect from, Rect to,
-            int animationDuration, boolean moveToFullscreen) {
-        animateBoundsImpl(target, from, to, animationDuration, moveToFullscreen);
+    public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to,
+            int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
+            boolean moveToFullscreen) {
+        animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState,
+                moveToFullscreen);
     }
 
     @VisibleForTesting
-    BoundsAnimator animateBoundsImpl(final AnimateBoundsUser target, Rect from, Rect to,
-            int animationDuration, boolean moveToFullscreen) {
+    BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to,
+            int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
+            boolean moveToFullscreen) {
         final BoundsAnimator existing = mRunningAnimations.get(target);
         final boolean replacing = existing != null;
-        final boolean animatingToNewFullscreenState = (existing == null) ||
-                (existing.mMoveToFullScreen != moveToFullscreen);
 
         if (DEBUG) Slog.d(TAG, "animateBounds: target=" + target + " from=" + from + " to=" + to
-                + " moveToFullscreen=" + moveToFullscreen + " replacing=" + replacing
-                + " animatingToNewFullscreenState=" + animatingToNewFullscreenState);
+                + " schedulePipModeChangedState=" + schedulePipModeChangedState
+                + " replacing=" + replacing);
 
         if (replacing) {
             if (existing.isAnimatingTo(to)) {
@@ -355,15 +333,36 @@
                 // one we are trying to start.
                 if (DEBUG) Slog.d(TAG, "animateBounds: same destination as existing=" + existing
                         + " ignoring...");
+
                 return existing;
             }
-            // Since we are replacing, we skip both animation start and end callbacks, and don't
-            // animate to the final bounds when cancelling
-            existing.prepareCancel(true /* skipAnimationEnd */, true /* skipFinalResize */);
+
+            // Update the PiP callback states if we are replacing the animation
+            if (existing.mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                if (schedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: still animating to fullscreen, keep"
+                            + " existing deferred state");
+                } else {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: fullscreen animation canceled, callback"
+                            + " on start already processed, schedule deferred update on end");
+                    schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
+                }
+            } else if (existing.mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_END) {
+                if (schedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: non-fullscreen animation canceled,"
+                            + " callback on start will be processed");
+                } else {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: still animating from fullscreen, keep"
+                            + " existing deferred state");
+                    schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
+                }
+            }
+
+            // Since we are replacing, we skip both animation start and end callbacks
             existing.cancel();
         }
-        final BoundsAnimator animator = new BoundsAnimator(target, from, to, moveToFullscreen,
-                replacing, animatingToNewFullscreenState);
+        final BoundsAnimator animator = new BoundsAnimator(target, from, to,
+                schedulePipModeChangedState, moveToFullscreen, replacing);
         mRunningAnimations.put(target, animator);
         animator.setFloatValues(0f, 1f);
         animator.setDuration((animationDuration != -1 ? animationDuration
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationTarget.java b/services/core/java/com/android/server/wm/BoundsAnimationTarget.java
new file mode 100644
index 0000000..8b1bf7b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/BoundsAnimationTarget.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.graphics.Rect;
+
+/**
+ * The target for a BoundsAnimation.
+ * @see BoundsAnimationController
+ */
+interface BoundsAnimationTarget {
+
+    /**
+     * Callback for the target to inform it that the animation has started, so it can do some
+     * necessary preparation.
+     *
+     * @param schedulePipModeChangedCallback whether or not to schedule the PiP mode changed
+     * callbacks
+     */
+    void onAnimationStart(boolean schedulePipModeChangedCallback);
+
+    /**
+     * Sets the size of the target (without any intermediate steps, like scheduling animation)
+     * but freezes the bounds of any tasks in the target at taskBounds, to allow for more
+     * flexibility during resizing. Only works for the pinned stack at the moment.  This will
+     * only be called between onAnimationStart() and onAnimationEnd().
+     *
+     * @return Whether the target should continue to be animated and this call was successful.
+     * If false, the animation will be cancelled because the user has determined that the
+     * animation is now invalid and not required. In such a case, the cancel will trigger the
+     * animation end callback as well, but will not send any further size changes.
+     */
+    boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds);
+
+    /**
+     * Callback for the target to inform it that the animation has ended, so it can do some
+     * necessary cleanup.
+     *
+     * @param schedulePipModeChangedCallback whether or not to schedule the PiP mode changed
+     * callbacks
+     * @param finalStackSize the final stack bounds to set on the target (can be to indicate that
+     * the animation was cancelled and the target does not need to update to the final stack bounds)
+     * @param moveToFullscreen whether or the target should reparent itself to the fullscreen stack
+     * when the animation completes
+     */
+    void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
+            boolean moveToFullscreen);
+}
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
index 135832e..5b9c16c 100644
--- a/services/core/java/com/android/server/wm/PinnedStackWindowController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -17,6 +17,10 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
+import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
 
 import android.app.RemoteAction;
 import android.graphics.Rect;
@@ -40,36 +44,53 @@
     /**
      * Animates the pinned stack.
      */
-    public void animateResizePinnedStack(Rect sourceBounds, Rect destBounds,
-            int animationDuration) {
+    public void animateResizePinnedStack(Rect toBounds, Rect sourceHintBounds,
+            int animationDuration, boolean schedulePipModeChangedOnAnimationEnd) {
         synchronized (mWindowMap) {
             if (mContainer == null) {
                 throw new IllegalArgumentException("Pinned stack container not found :(");
             }
 
-            // Get non-null fullscreen bounds if the bounds are null
-            final boolean moveToFullscreen = destBounds == null;
-            destBounds = getPinnedStackAnimationBounds(destBounds);
+            // Get the from-bounds
+            final Rect fromBounds = new Rect();
+            mContainer.getBounds(fromBounds);
 
-            // If the bounds are truly null, then there was no fullscreen stack at this time, so
-            // animate this to the full display bounds
-            final Rect toBounds;
-            if (destBounds == null) {
-                toBounds = new Rect();
-                mContainer.getDisplayContent().getLogicalDisplayRect(toBounds);
-            } else {
-                toBounds = destBounds;
+            // Get non-null fullscreen to-bounds for animating if the bounds are null
+            @SchedulePipModeChangedState int schedulePipModeChangedState =
+                NO_PIP_MODE_CHANGED_CALLBACKS;
+            final boolean toFullscreen = toBounds == null;
+            if (toFullscreen) {
+                if (schedulePipModeChangedOnAnimationEnd) {
+                    throw new IllegalArgumentException("Should not defer scheduling PiP mode"
+                            + " change on animation to fullscreen.");
+                }
+                schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
+
+                mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
+                if (!mTmpBoundsRect.isEmpty()) {
+                    // If there is a fullscreen bounds, use that
+                    toBounds = new Rect(mTmpBoundsRect);
+                } else {
+                    // Otherwise, use the display bounds
+                    toBounds = new Rect();
+                    mContainer.getDisplayContent().getLogicalDisplayRect(toBounds);
+                }
+            } else if (schedulePipModeChangedOnAnimationEnd) {
+                schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
             }
 
-            final Rect originalBounds = new Rect();
-            mContainer.getBounds(originalBounds);
-            mContainer.setAnimationFinalBounds(sourceBounds, toBounds);
+            mContainer.setAnimationFinalBounds(sourceHintBounds, toBounds, toFullscreen);
+
+            final Rect finalToBounds = toBounds;
+            final @SchedulePipModeChangedState int finalSchedulePipModeChangedState =
+                schedulePipModeChangedState;
             UiThread.getHandler().post(() -> {
                 if (mContainer == null) {
                     return;
                 }
-                mService.mBoundsAnimationController.animateBounds(mContainer, originalBounds,
-                        toBounds, animationDuration, moveToFullscreen);
+                mService.mBoundsAnimationController.animateBounds(mContainer, fromBounds,
+                        finalToBounds, animationDuration, finalSchedulePipModeChangedState,
+                        toFullscreen);
             });
         }
     }
@@ -93,7 +114,8 @@
 
             if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) != 0) {
                 if (!toBounds.equals(targetBounds)) {
-                    animateResizePinnedStack(null /* sourceBounds */, toBounds, -1 /* duration */);
+                    animateResizePinnedStack(toBounds, null /* sourceHintBounds */,
+                            -1 /* duration */, false /* schedulePipModeChangedOnAnimationEnd */);
                 }
                 pinnedStackController.setAspectRatio(
                         pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
@@ -116,26 +138,31 @@
     }
 
     /**
-     * @return whether the bounds are currently animating to fullscreen.
+     * @return whether the multi-window mode change should be deferred as a part of a transition
+     * from fullscreen to non-fullscreen bounds.
      */
-    public boolean isAnimatingBoundsToFullscreen() {
-        return mContainer.isAnimatingBoundsToFullscreen();
-    }
-
-    public boolean pinnedStackResizeAllowed() {
-        return mContainer.pinnedStackResizeAllowed();
+    public boolean deferScheduleMultiWindowModeChanged() {
+        synchronized(mWindowMap) {
+            return mContainer.deferScheduleMultiWindowModeChanged();
+        }
     }
 
     /**
-     * Checks the {@param bounds} and retirms non-null fullscreen bounds for the pinned stack
-     * animation if necessary.
+     * @return whether the bounds are currently animating to fullscreen.
      */
-    private Rect getPinnedStackAnimationBounds(Rect bounds) {
-        mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
-        if (bounds == null && !mTmpBoundsRect.isEmpty()) {
-            bounds = new Rect(mTmpBoundsRect);
+    public boolean isAnimatingBoundsToFullscreen() {
+        synchronized (mWindowMap) {
+            return mContainer.isAnimatingBoundsToFullscreen();
         }
-        return bounds;
+    }
+
+    /**
+     * @return whether the stack can be resized from the bounds animation.
+     */
+    public boolean pinnedStackResizeDisallowed() {
+        synchronized (mWindowMap) {
+            return mContainer.pinnedStackResizeDisallowed();
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index d7c41d3..d141f7c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -56,7 +56,7 @@
 import java.io.PrintWriter;
 
 public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLayerUser,
-        BoundsAnimationController.AnimateBoundsUser {
+        BoundsAnimationTarget {
     /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
      * restrict IME adjustment so that a min portion of top stack remains visible.*/
     private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f;
@@ -132,7 +132,7 @@
     private boolean mBoundsAnimatingToFullscreen = false;
     private boolean mCancelCurrentBoundsAnimation = false;
     private Rect mBoundsAnimationTarget = new Rect();
-    private Rect mBoundsAnimationSourceBounds = new Rect();
+    private Rect mBoundsAnimationSourceHintBounds = new Rect();
 
     // Temporary storage for the new bounds that should be used after the configuration change.
     // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
@@ -322,18 +322,19 @@
      * Sets the bounds animation target bounds ahead of an animation.  This can't currently be done
      * in onAnimationStart() since that is started on the UiThread.
      */
-    void setAnimationFinalBounds(Rect sourceBounds, Rect destBounds) {
+    void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds, boolean toFullscreen) {
         mBoundsAnimatingRequested = true;
-        if (sourceBounds != null) {
-            mBoundsAnimationSourceBounds.set(sourceBounds);
-        } else {
-            mBoundsAnimationSourceBounds.setEmpty();
-        }
+        mBoundsAnimatingToFullscreen = toFullscreen;
         if (destBounds != null) {
             mBoundsAnimationTarget.set(destBounds);
         } else {
             mBoundsAnimationTarget.setEmpty();
         }
+        if (sourceHintBounds != null) {
+            mBoundsAnimationSourceHintBounds.set(sourceHintBounds);
+        } else {
+            mBoundsAnimationSourceHintBounds.setEmpty();
+        }
     }
 
     /**
@@ -346,8 +347,8 @@
     /**
      * @return the final source bounds for the bounds animation.
      */
-    void getFinalAnimationSourceBounds(Rect outBounds) {
-        outBounds.set(mBoundsAnimationSourceBounds);
+    void getFinalAnimationSourceHintBounds(Rect outBounds) {
+        outBounds.set(mBoundsAnimationSourceHintBounds);
     }
 
     /**
@@ -413,7 +414,7 @@
                 // orientation, clear the animation target bounds since they are obsolete, and
                 // cancel any currently running animations
                 mBoundsAnimationTarget.setEmpty();
-                mBoundsAnimationSourceBounds.setEmpty();
+                mBoundsAnimationSourceHintBounds.setEmpty();
                 mCancelCurrentBoundsAnimation = true;
                 return true;
             }
@@ -1458,13 +1459,16 @@
         }
     }
 
-    public boolean setPinnedStackSize(Rect bounds, Rect tempTaskBounds) {
-        if (mCancelCurrentBoundsAnimation) {
-            return false;
+    public boolean setPinnedStackSize(Rect stackBounds, Rect tempTaskBounds) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
+        synchronized (mService.mWindowMap) {
+            if (mCancelCurrentBoundsAnimation) {
+                return false;
+            }
         }
 
         try {
-            mService.mActivityManager.resizePinnedStack(bounds, tempTaskBounds);
+            mService.mActivityManager.resizePinnedStack(stackBounds, tempTaskBounds);
         } catch (RemoteException e) {
             // I don't believe you.
         }
@@ -1472,11 +1476,11 @@
     }
 
     @Override  // AnimatesBounds
-    public void onAnimationStart(boolean toFullscreen) {
+    public void onAnimationStart(boolean schedulePipModeChangedCallback) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
         synchronized (mService.mWindowMap) {
             mBoundsAnimatingRequested = false;
             mBoundsAnimating = true;
-            mBoundsAnimatingToFullscreen = toFullscreen;
             mCancelCurrentBoundsAnimation = false;
         }
 
@@ -1486,41 +1490,63 @@
             } catch (RemoteException e) {
                 // I don't believe you...
             }
+
+            final PinnedStackWindowController controller =
+                    (PinnedStackWindowController) getController();
+            if (schedulePipModeChangedCallback && controller != null) {
+                // We need to schedule the PiP mode change after the animation down, so use the
+                // final bounds
+                controller.updatePictureInPictureModeForPinnedStackAnimation(null);
+            }
         }
     }
 
     @Override  // AnimatesBounds
-    public void updatePictureInPictureMode(Rect targetStackBounds) {
-        final PinnedStackWindowController controller =
-                (PinnedStackWindowController) getController();
-        if (controller != null) {
-            controller.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
-        }
-    }
-
-    @Override  // AnimatesBounds
-    public void onAnimationEnd() {
+    public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
+            boolean moveToFullscreen) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
         synchronized (mService.mWindowMap) {
             mBoundsAnimating = false;
             mService.requestTraversal();
         }
 
         if (mStackId == PINNED_STACK_ID) {
+            final PinnedStackWindowController controller =
+                    (PinnedStackWindowController) getController();
+            if (schedulePipModeChangedCallback && controller != null) {
+                // We need to schedule the PiP mode change after the animation down, so use the
+                // final bounds
+                controller.updatePictureInPictureModeForPinnedStackAnimation(
+                        mBoundsAnimationTarget);
+            }
+
+            // Update to the final bounds if requested. This is done here instead of in the bounds
+            // animator to allow us to coordinate this after we notify the PiP mode changed
+            if (finalStackSize != null) {
+                setPinnedStackSize(finalStackSize, null);
+            }
+
             try {
                 mService.mActivityManager.notifyPinnedStackAnimationEnded();
+                if (moveToFullscreen) {
+                    mService.mActivityManager.moveTasksToFullscreenStack(mStackId,
+                            true /* onTop */);
+                }
             } catch (RemoteException e) {
                 // I don't believe you...
             }
         }
     }
 
-    @Override
-    public void moveToFullscreen() {
-        try {
-            mService.mActivityManager.moveTasksToFullscreenStack(mStackId, true);
-        } catch (RemoteException e) {
-            e.printStackTrace();
+    /**
+     * @return True if we are currently animating the pinned stack from fullscreen to non-fullscreen
+     *         bounds and we have a deferred PiP mode changed callback set with the animation.
+     */
+    public boolean deferScheduleMultiWindowModeChanged() {
+        if (mStackId == PINNED_STACK_ID) {
+            return (mBoundsAnimatingRequested || mBoundsAnimating);
         }
+        return false;
     }
 
     public boolean hasMovementAnimations() {
@@ -1539,7 +1565,7 @@
         return mBoundsAnimating && mBoundsAnimatingToFullscreen;
     }
 
-    public boolean pinnedStackResizeAllowed() {
+    public boolean pinnedStackResizeDisallowed() {
         if (mBoundsAnimating && mCancelCurrentBoundsAnimation) {
             return true;
         }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0b96f3f..9555c8d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4365,9 +4365,12 @@
         // When we change the Surface size, in scenarios which may require changing
         // the surface position in sync with the resize, we use a preserved surface
         // so we can freeze it while waiting for the client to report draw on the newly
-        // sized surface.
+        // sized surface.  Don't preserve surfaces if the insets change while animating the pinned
+        // stack since it can lead to issues if a new surface is created while calculating the
+        // scale for the animation using the source hint rect
+        // (see WindowStateAnimator#setSurfaceBoundariesLocked()).
         if (isDragResizeChanged() || isResizedWhileNotDragResizing()
-                || surfaceInsetsChanging()) {
+                || (surfaceInsetsChanging() && !inPinnedWorkspace())) {
             mLastSurfaceInsets.set(mAttrs.surfaceInsets);
 
             setDragResizing();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index fa35336..a2889b1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1360,7 +1360,7 @@
             int posX = mTmpSize.left;
             int posY = mTmpSize.top;
             task.mStack.getDimBounds(mTmpStackBounds);
-            task.mStack.getFinalAnimationSourceBounds(mTmpSourceBounds);
+            task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds);
             if (!mTmpSourceBounds.isEmpty()) {
                 // Get the final target stack bounds, if we are not animating, this is just the
                 // current stack bounds
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index 85dc712..7f150a2 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -16,6 +16,11 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
+import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
+
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Rect;
@@ -47,6 +52,12 @@
  * Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks
  * depending on the various interactions.
  *
+ * We are really concerned about only three of the transition states [F = fullscreen, !F = floating]
+ * F->!F, !F->!F, and !F->F. Each animation can only be cancelled from the target mid-transition,
+ * or if a new animation starts on the same target.  The tests below verifies that the target is
+ * notified of all the cases where it is animating and cancelled so that it can respond
+ * appropriately.
+ *
  * Build/Install/Run:
  *  bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests
  */
@@ -109,47 +120,46 @@
     /**
      * A test animate bounds user to track callbacks from the bounds animation.
      */
-    private class TestAnimateBoundsUser implements BoundsAnimationController.AnimateBoundsUser {
+    private class TestBoundsAnimationTarget implements BoundsAnimationTarget {
 
+        boolean mAwaitingAnimationStart;
         boolean mMovedToFullscreen;
         boolean mAnimationStarted;
-        boolean mAnimationStartedToFullscreen;
+        boolean mSchedulePipModeChangedOnStart;
         boolean mAnimationEnded;
-        boolean mUpdatedPictureInPictureModeWithBounds;
+        Rect mAnimationEndFinalStackBounds;
+        boolean mSchedulePipModeChangedOnEnd;
         boolean mBoundsUpdated;
+        boolean mCancelRequested;
         Rect mStackBounds;
         Rect mTaskBounds;
 
-        boolean mRequestCancelAnimation = false;
-
-        void reinitialize(Rect stackBounds, Rect taskBounds) {
+        void initialize(Rect from) {
+            mAwaitingAnimationStart = true;
             mMovedToFullscreen = false;
             mAnimationStarted = false;
-            mAnimationStartedToFullscreen = false;
             mAnimationEnded = false;
-            mUpdatedPictureInPictureModeWithBounds = false;
-            mStackBounds = stackBounds;
-            mTaskBounds = taskBounds;
+            mAnimationEndFinalStackBounds = null;
+            mSchedulePipModeChangedOnStart = false;
+            mSchedulePipModeChangedOnEnd = false;
+            mStackBounds = from;
+            mTaskBounds = null;
             mBoundsUpdated = false;
-            mRequestCancelAnimation = false;
         }
 
         @Override
-        public void onAnimationStart(boolean toFullscreen) {
+        public void onAnimationStart(boolean schedulePipModeChangedCallback) {
+            mAwaitingAnimationStart = false;
             mAnimationStarted = true;
-            mAnimationStartedToFullscreen = toFullscreen;
-        }
-
-        @Override
-        public void updatePictureInPictureMode(Rect targetStackBounds) {
-            mUpdatedPictureInPictureModeWithBounds = true;
+            mSchedulePipModeChangedOnStart = schedulePipModeChangedCallback;
         }
 
         @Override
         public boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds) {
             // TODO: Once we break the runs apart, we should fail() here if this is called outside
             //       of onAnimationStart() and onAnimationEnd()
-            if (mRequestCancelAnimation) {
+            if (mCancelRequested) {
+                mCancelRequested = false;
                 return false;
             } else {
                 mBoundsUpdated = true;
@@ -160,32 +170,206 @@
         }
 
         @Override
-        public void onAnimationEnd() {
+        public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackBounds,
+                boolean moveToFullscreen) {
             mAnimationEnded = true;
+            mAnimationEndFinalStackBounds = finalStackBounds;
+            mSchedulePipModeChangedOnEnd = schedulePipModeChangedCallback;
+            mMovedToFullscreen = moveToFullscreen;
+            mTaskBounds = null;
+        }
+    }
+
+    /**
+     * Drives the animations, makes common assertions along the way.
+     */
+    private class BoundsAnimationDriver {
+
+        private BoundsAnimationController mController;
+        private TestBoundsAnimationTarget mTarget;
+        private BoundsAnimator mAnimator;
+
+        private Rect mFrom;
+        private Rect mTo;
+        private Rect mLargerBounds;
+        private Rect mExpectedFinalBounds;
+
+        BoundsAnimationDriver(BoundsAnimationController controller,
+                TestBoundsAnimationTarget target) {
+            mController = controller;
+            mTarget = target;
         }
 
-        @Override
-        public void moveToFullscreen() {
-            mMovedToFullscreen = true;
+        BoundsAnimationDriver start(Rect from, Rect to) {
+            if (mAnimator != null) {
+                throw new IllegalArgumentException("Call restart() to restart an animation");
+            }
+
+            mTarget.initialize(from);
+
+            // Started, not running
+            assertTrue(mTarget.mAwaitingAnimationStart);
+            assertTrue(!mTarget.mAnimationStarted);
+
+            startImpl(from, to);
+
+            // Started and running
+            assertTrue(!mTarget.mAwaitingAnimationStart);
+            assertTrue(mTarget.mAnimationStarted);
+
+            return this;
+        }
+
+        BoundsAnimationDriver restart(Rect to) {
+            if (mAnimator == null) {
+                throw new IllegalArgumentException("Call start() to start a new animation");
+            }
+
+            BoundsAnimator oldAnimator = mAnimator;
+            boolean toSameBounds = mAnimator.isStarted() && to.equals(mTo);
+
+            // Reset the animation start state
+            mTarget.mAnimationStarted = false;
+
+            // Start animation
+            startImpl(mTarget.mStackBounds, to);
+
+            if (toSameBounds) {
+                // Same animator if same final bounds
+                assertSame(oldAnimator, mAnimator);
+            }
+
+            // No animation start for replacing animation
+            assertTrue(!mTarget.mAnimationStarted);
+            mTarget.mAnimationStarted = true;
+            return this;
+        }
+
+        private BoundsAnimationDriver startImpl(Rect from, Rect to) {
+            boolean fromFullscreen = from.equals(BOUNDS_FULL);
+            boolean toFullscreen = to.equals(BOUNDS_FULL);
+            mFrom = new Rect(from);
+            mTo = new Rect(to);
+            mExpectedFinalBounds = new Rect(to);
+            mLargerBounds = getLargerBounds(mFrom, mTo);
+
+            // Start animation
+            final @SchedulePipModeChangedState int schedulePipModeChangedState = toFullscreen
+                    ? SCHEDULE_PIP_MODE_CHANGED_ON_START
+                    : fromFullscreen
+                            ? SCHEDULE_PIP_MODE_CHANGED_ON_END
+                            : NO_PIP_MODE_CHANGED_CALLBACKS;
+            mAnimator = mController.animateBoundsImpl(mTarget, from, to, DURATION,
+                    schedulePipModeChangedState, toFullscreen);
+
+            // Original stack bounds, frozen task bounds
+            assertEquals(mFrom, mTarget.mStackBounds);
+            assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
+
+            // Animating to larger size
+            if (mFrom.equals(mLargerBounds)) {
+                assertTrue(!mAnimator.animatingToLargerSize());
+            } else if (mTo.equals(mLargerBounds)) {
+                assertTrue(mAnimator.animatingToLargerSize());
+            }
+
+            return this;
+        }
+
+        BoundsAnimationDriver expectStarted(boolean schedulePipModeChanged) {
+            // Callback made
+            assertTrue(mTarget.mAnimationStarted);
+
+            assertEquals(schedulePipModeChanged, mTarget.mSchedulePipModeChangedOnStart);
+            return this;
+        }
+
+        BoundsAnimationDriver update(float t) {
+            mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(t));
+
+            // Temporary stack bounds, frozen task bounds
+            if (t == 0f) {
+                assertEquals(mFrom, mTarget.mStackBounds);
+            } else if (t == 1f) {
+                assertEquals(mTo, mTarget.mStackBounds);
+            } else {
+                assertNotEquals(mFrom, mTarget.mStackBounds);
+                assertNotEquals(mTo, mTarget.mStackBounds);
+            }
+            assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
+            return this;
+        }
+
+        BoundsAnimationDriver cancel() {
+            // Cancel
+            mTarget.mCancelRequested = true;
+            mTarget.mBoundsUpdated = false;
+            mExpectedFinalBounds = null;
+
+            // Update
+            mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(0.5f));
+
+            // Not started, not running, cancel reset
+            assertTrue(!mTarget.mCancelRequested);
+
+            // Stack/task bounds not updated
+            assertTrue(!mTarget.mBoundsUpdated);
+
+            // Callback made
+            assertTrue(mTarget.mAnimationEnded);
+            assertNull(mTarget.mAnimationEndFinalStackBounds);
+
+            return this;
+        }
+
+        BoundsAnimationDriver end() {
+            mAnimator.end();
+
+            // Final stack bounds
+            assertEquals(mTo, mTarget.mStackBounds);
+            assertEquals(mExpectedFinalBounds, mTarget.mAnimationEndFinalStackBounds);
+            assertNull(mTarget.mTaskBounds);
+
+            return this;
+        }
+
+        BoundsAnimationDriver expectEnded(boolean schedulePipModeChanged,
+                boolean moveToFullscreen) {
+            // Callback made
+            assertTrue(mTarget.mAnimationEnded);
+
+            assertEquals(schedulePipModeChanged, mTarget.mSchedulePipModeChangedOnEnd);
+            assertEquals(moveToFullscreen, mTarget.mMovedToFullscreen);
+            return this;
+        }
+
+        private Rect getLargerBounds(Rect r1, Rect r2) {
+            int r1Area = r1.width() * r1.height();
+            int r2Area = r2.width() * r2.height();
+            if (r1Area <= r2Area) {
+                return r2;
+            } else {
+                return r1;
+            }
         }
     }
 
     // Constants
+    private static final boolean SCHEDULE_PIP_MODE_CHANGED = true;
     private static final boolean MOVE_TO_FULLSCREEN = true;
+    private static final int DURATION = 100;
 
     // Some dummy bounds to represent fullscreen and floating bounds
     private static final Rect BOUNDS_FULL = new Rect(0, 0, 100, 100);
-    private static final Rect BOUNDS_FLOATING = new Rect(80, 80, 95, 95);
-    private static final Rect BOUNDS_ALT_FLOATING = new Rect(60, 60, 95, 95);
-
-    // Some dummy duration
-    private static final int DURATION = 100;
+    private static final Rect BOUNDS_FLOATING = new Rect(60, 60, 95, 95);
+    private static final Rect BOUNDS_SMALLER_FLOATING = new Rect(80, 80, 95, 95);
 
     // Common
-    private MockAppTransition mAppTransition;
-    private MockValueAnimator mAnimator;
-    private TestAnimateBoundsUser mTarget;
+    private MockAppTransition mMockAppTransition;
+    private MockValueAnimator mMockAnimator;
+    private TestBoundsAnimationTarget mTarget;
     private BoundsAnimationController mController;
+    private BoundsAnimationDriver mDriver;
 
     // Temp
     private Rect mTmpRect = new Rect();
@@ -196,153 +380,184 @@
 
         final Context context = InstrumentationRegistry.getTargetContext();
         final Handler handler = new Handler(Looper.getMainLooper());
-        mAppTransition = new MockAppTransition(context);
-        mAnimator = new MockValueAnimator();
-        mTarget = new TestAnimateBoundsUser();
-        mController = new BoundsAnimationController(context, mAppTransition, handler);
+        mMockAppTransition = new MockAppTransition(context);
+        mMockAnimator = new MockValueAnimator();
+        mTarget = new TestBoundsAnimationTarget();
+        mController = new BoundsAnimationController(context, mMockAppTransition, handler);
+        mDriver = new BoundsAnimationDriver(mController, mTarget);
     }
 
+    /** BASE TRANSITIONS **/
+
     @UiThreadTest
     @Test
     public void testFullscreenToFloatingTransition() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-
-        // Assert that when we are started, and that we are not going to fullscreen
-        assertTrue(mTarget.mAnimationStarted);
-        assertFalse(mTarget.mAnimationStartedToFullscreen);
-        // Ensure we are not triggering a PiP mode change
-        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
-        // Ensure that the task stack bounds are already frozen to the larger source stack bounds
-        assertEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Drive some animation updates, ensure that only the stack bounds change and the task
-        // bounds are frozen to the original stack bounds (adjusted for the offset)
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
-        assertNotEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(1f));
-        assertNotEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Finish the animation, ensure that it reaches the final bounds with the given state
-        boundsAnimator.end();
-        assertTrue(mTarget.mAnimationEnded);
-        assertEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertNull(mTarget.mTaskBounds);
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
     public void testFloatingToFullscreenTransition() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FLOATING,
-                BOUNDS_FULL, DURATION, MOVE_TO_FULLSCREEN);
-
-        // Assert that when we are started, and that we are going to fullscreen
-        assertTrue(mTarget.mAnimationStarted);
-        assertTrue(mTarget.mAnimationStartedToFullscreen);
-        // Ensure that we update the PiP mode change with the new fullscreen bounds
-        assertTrue(mTarget.mUpdatedPictureInPictureModeWithBounds);
-        // Ensure that the task stack bounds are already frozen to the larger target stack bounds
-        assertEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Drive some animation updates, ensure that only the stack bounds change and the task
-        // bounds are frozen to the original stack bounds (adjusted for the offset)
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(1f));
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Finish the animation, ensure that it reaches the final bounds with the given state
-        boundsAnimator.end();
-        assertTrue(mTarget.mAnimationEnded);
-        assertEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertNull(mTarget.mTaskBounds);
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
-    public void testInterruptAnimationFromUser() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-
-        // Cancel the animation on the next update from the user
-        mTarget.mRequestCancelAnimation = true;
-        mTarget.mBoundsUpdated = false;
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
-        // Ensure that we got no more updates after returning false and the bounds are not updated
-        // to the end value
-        assertFalse(mTarget.mBoundsUpdated);
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mTaskBounds);
-        // Ensure that we received the animation end call
-        assertTrue(mTarget.mAnimationEnded);
+    public void testFloatingToSmallerFloatingTransition() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
-    public void testCancelAnimationFromNewAnimationToExistingBounds() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+    public void testFloatingToLargerFloatingTransition() throws Exception {
+        mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
 
-        // Drive some animation updates
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+    /** F->!F w/ CANCEL **/
 
-        // Cancel the animation as a restart to the same bounds
-        mTarget.reinitialize(null, null);
-        final BoundsAnimator altBoundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-        // Ensure the animator is the same
-        assertSame(boundsAnimator, altBoundsAnimator);
-        // Ensure we haven't restarted or finished the animation
-        assertFalse(mTarget.mAnimationStarted);
-        assertFalse(mTarget.mAnimationEnded);
-        // Ensure that we haven't tried to update the PiP mode
-        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
-    public void testCancelAnimationFromNewAnimationToNewBounds() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+    public void testFullscreenToFloatingCancelFromAnimationToSameBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FLOATING)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
 
-        // Drive some animation updates
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromAnimationToFloatingBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_SMALLER_FLOATING)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
 
-        // Cancel the animation as a restart to new bounds
-        mTarget.reinitialize(null, null);
-        final BoundsAnimator altBoundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_ALT_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-        // Ensure the animator is not the same
-        assertNotSame(boundsAnimator, altBoundsAnimator);
-        // Ensure that we did not get an animation start/end callback
-        assertFalse(mTarget.mAnimationStarted);
-        assertFalse(mTarget.mAnimationEnded);
-        // Ensure that we haven't tried to update the PiP mode
-        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromAnimationToFullscreenBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FULL)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    /** !F->F w/ CANCEL **/
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromAnimationToSameBounds() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FULL)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromAnimationToFloatingBounds() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_SMALLER_FLOATING)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    /** !F->!F w/ CANCEL **/
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToSmallerFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToLargerFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    /** MISC **/
+
+    @UiThreadTest
+    @Test
+    public void testBoundsAreCopied() throws Exception {
+        Rect from = new Rect(0, 0, 100, 100);
+        Rect to = new Rect(25, 25, 75, 75);
+        mDriver.start(from, to)
+                .update(0.25f)
+                .end();
+        assertEquals(new Rect(0, 0, 100, 100), from);
+        assertEquals(new Rect(25, 25, 75, 75), to);
     }
 
     /**
-     * @return the bounds offset to zero/zero.
+     * @return whether the task and stack bounds would be the same if they were at the same offset.
      */
-    private Rect offsetToZero(Rect bounds) {
-        mTmpRect.set(bounds);
-        mTmpRect.offsetTo(0, 0);
-        return mTmpRect;
+    private boolean assertEqualSizeAtOffset(Rect stackBounds, Rect taskBounds) {
+        mTmpRect.set(taskBounds);
+        mTmpRect.offsetTo(stackBounds.left, stackBounds.top);
+        return stackBounds.equals(mTmpRect);
     }
 }
