Small fixes and tweaks to PiP transition.

- Fixing case where default bounds did not account for ime height
- Ensuring that we using the animating/target bounds when calculating
  the new ime-offset bounds
- Tweaking transition interpolators and durations

Bug: 35396882
Test: android.server.cts.ActivityManagerPinnedStackTests
Change-Id: Ia22ea0008d834c47a3f26bf2e1f484c72fae8736
diff --git a/core/java/android/view/IPinnedStackListener.aidl b/core/java/android/view/IPinnedStackListener.aidl
index c7340bf..782f349 100644
--- a/core/java/android/view/IPinnedStackListener.aidl
+++ b/core/java/android/view/IPinnedStackListener.aidl
@@ -38,9 +38,11 @@
      * to be changed (ie. after configuration change, aspect ratio change, etc). It then provides
      * the components that allow the listener to calculate the movement bounds itself. The
      * {@param normalBounds} are also the default bounds that the PiP would be entered in its
-     * current state with the aspect ratio applied.
+     * current state with the aspect ratio applied.  The {@param animatingBounds} are provided
+     * to indicate the current target bounds of the pinned stack (the final bounds if animating,
+     * the current bounds if not), which may be helpful in calculating dependent animation bounds.
      */
-    void onMovementBoundsChanged(in Rect insetBounds, in Rect normalBounds,
+    void onMovementBoundsChanged(in Rect insetBounds, in Rect normalBounds, in Rect animatingBounds,
             boolean fromImeAdjustement);
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 4c5d8a1..ecc2fad 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -122,9 +122,10 @@
 
         @Override
         public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
-                boolean fromImeAdjustement) {
+                Rect animatingBounds, boolean fromImeAdjustement) {
             mHandler.post(() -> {
-                mTouchHandler.onMovementBoundsChanged(insetBounds, normalBounds, fromImeAdjustement);
+                mTouchHandler.onMovementBoundsChanged(insetBounds, normalBounds, animatingBounds,
+                        fromImeAdjustement);
             });
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index a9d7457..20c1136 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -57,10 +57,11 @@
     private static final int DEFAULT_MOVE_STACK_DURATION = 225;
     private static final int SNAP_STACK_DURATION = 225;
     private static final int DISMISS_STACK_DURATION = 375;
-    private static final int SHRINK_STACK_FROM_MENU_DURATION = 150;
-    private static final int EXPAND_STACK_TO_MENU_DURATION = 150;
-    private static final int EXPAND_STACK_TO_FULLSCREEN_DURATION = 225;
+    private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
+    private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
+    private static final int EXPAND_STACK_TO_FULLSCREEN_DURATION = 300;
     private static final int MINIMIZE_STACK_MAX_DURATION = 200;
+    private static final int IME_SHIFT_DURATION = 300;
 
     // The fraction of the stack width that the user has to drag offscreen to minimize the PiP
     private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.2f;
@@ -289,6 +290,14 @@
     }
 
     /**
+     * Animates the PiP to offset it from the IME.
+     */
+    void animateToIMEOffset(Rect toBounds) {
+        cancelAnimations();
+        resizeAndAnimatePipUnchecked(toBounds, IME_SHIFT_DURATION);
+    }
+
+    /**
      * Animates the dismissal of the PiP over the dismiss target bounds.
      */
     Rect animateDismissFromDrag(Rect dismissBounds) {
@@ -310,18 +319,6 @@
     }
 
     /**
-     * Animates the PiP to some given bounds.
-     */
-    void animateToBounds(Rect toBounds) {
-        cancelAnimations();
-        if (!mBounds.equals(toBounds)) {
-            mBoundsAnimator = createAnimationToBounds(mBounds, toBounds,
-                    DEFAULT_MOVE_STACK_DURATION, FAST_OUT_LINEAR_IN, mUpdateBoundsListener);
-            mBoundsAnimator.start();
-        }
-    }
-
-    /**
      * Cancels all existing animations.
      */
     void cancelAnimations() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index ebe6d25..010522d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -180,7 +180,7 @@
         mImeHeight = imeHeight;
     }
 
-    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
+    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect animatingBounds,
             boolean fromImeAdjustement) {
         // Re-calculate the expanded bounds
         mNormalBounds = normalBounds;
@@ -207,7 +207,7 @@
                 // Defer the update of the current movement bounds until after the user finishes
                 // touching the screen
             } else {
-                final Rect bounds = new Rect(mMotionHelper.getBounds());
+                final Rect bounds = new Rect(animatingBounds);
                 final Rect toMovementBounds = mIsMenuVisible
                         ? expandedMovementBounds
                         : normalMovementBounds;
@@ -227,7 +227,7 @@
                         bounds.offsetTo(bounds.left, toMovementBounds.bottom);
                     }
                 }
-                mMotionHelper.animateToBounds(bounds);
+                mMotionHelper.animateToIMEOffset(bounds);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index d506669..9a8974d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -197,7 +197,7 @@
 
         @Override
         public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
-                boolean fromImeAdjustement) {
+                Rect animatingBounds, boolean fromImeAdjustement) {
             mHandler.post(() -> {
                 mDefaultPipBounds.set(normalBounds);
             });
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 837b69e..cd0e6cc 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -23,12 +23,15 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
+import android.content.Context;
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Debug;
 import android.util.ArrayMap;
 import android.util.Slog;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
 import android.view.WindowManagerInternal;
 
@@ -51,6 +54,8 @@
             ? "BoundsAnimationController" : TAG_WM;
     private static final int DEBUG_ANIMATION_SLOW_DOWN_FACTOR = 1;
 
+    private static final int DEFAULT_TRANSITION_DURATION = 425;
+
     // Only accessed on UI thread.
     private ArrayMap<AnimateBoundsUser, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
 
@@ -85,12 +90,15 @@
     private final Handler mHandler;
     private final AppTransition mAppTransition;
     private final AppTransitionNotifier mAppTransitionNotifier = new AppTransitionNotifier();
+    private final Interpolator mFastOutSlowInInterpolator;
     private boolean mFinishAnimationAfterTransition = false;
 
-    BoundsAnimationController(AppTransition transition, Handler handler) {
+    BoundsAnimationController(Context context, AppTransition transition, Handler handler) {
         mHandler = handler;
         mAppTransition = transition;
         mAppTransition.registerListenerLocked(mAppTransitionNotifier);
+        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+                com.android.internal.R.interpolator.fast_out_slow_in);
     }
 
     private final class BoundsAnimator extends ValueAnimator
@@ -297,8 +305,8 @@
         mRunningAnimations.put(target, animator);
         animator.setFloatValues(0f, 1f);
         animator.setDuration((animationDuration != -1 ? animationDuration
-                : DEFAULT_APP_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR);
-        animator.setInterpolator(new LinearInterpolator());
+                : DEFAULT_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR);
+        animator.setInterpolator(mFastOutSlowInInterpolator);
         animator.start();
     }
 }
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 9558068..1d50d0d 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -233,8 +233,8 @@
 
         final Rect defaultBounds = new Rect();
         final Size size = getSize(mDefaultAspectRatio);
-        Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds, 0, 0,
-                defaultBounds);
+        Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
+                0, mIsImeShowing ? mImeHeight : 0, defaultBounds);
         return defaultBounds;
     }
 
@@ -353,14 +353,21 @@
     private void notifyMovementBoundsChanged(boolean fromImeAdjustement) {
         if (mPinnedStackListener != null) {
             try {
-                Rect insetBounds = new Rect();
+                final Rect insetBounds = new Rect();
                 getInsetBounds(insetBounds);
-                Rect normalBounds = getDefaultBounds();
+                final Rect normalBounds = getDefaultBounds();
                 if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
                     transformBoundsToAspectRatio(normalBounds, mAspectRatio);
                 }
+                final Rect animatingBounds = mTmpRect;
+                final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
+                if (pinnedStack != null) {
+                    pinnedStack.getAnimatingBounds(animatingBounds);
+                } else {
+                    animatingBounds.set(normalBounds);
+                }
                 mPinnedStackListener.onMovementBoundsChanged(insetBounds, normalBounds,
-                        fromImeAdjustement);
+                        animatingBounds, fromImeAdjustement);
             } catch (RemoteException e) {
                 Slog.e(TAG_WM, "Error delivering actions changed event.", e);
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index eb3a2d1..66ec8f0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1026,8 +1026,8 @@
         mAppTransition = new AppTransition(context, this);
         mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
 
-        mBoundsAnimationController =
-                new BoundsAnimationController(mAppTransition, UiThread.getHandler());
+        mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,
+                UiThread.getHandler());
 
         mActivityManager = ActivityManager.getService();
         mAmInternal = LocalServices.getService(ActivityManagerInternal.class);