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);