Merge "Use RectFSpringAnim for auto-enter-pip" into sc-dev

This commit is contained in:
Hongwei Wang 2021-06-15 20:50:45 +00:00 committed by Android (Google) Code Review
commit e3bfeddd04
2 changed files with 48 additions and 58 deletions

View File

@ -45,8 +45,6 @@ import static com.android.quickstep.GestureState.STATE_END_TARGET_SET;
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_END;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_START;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
@ -248,7 +246,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
private final Runnable mOnDeferredActivityLaunch = this::onDeferredActivityLaunch;
private static final long SWIPE_PIP_TO_HOME_DURATION = 425;
private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
protected boolean mIsSwipingPipToHome;
@ -1134,17 +1131,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
runningTaskTarget);
mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome() && appCanEnterPip;
final RectFSpringAnim windowAnim;
if (mIsSwipingPipToHome) {
mSwipePipToHomeAnimator = getSwipePipToHomeAnimator(
mSwipePipToHomeAnimator = createWindowAnimationToPip(
homeAnimFactory, runningTaskTarget, start);
mSwipePipToHomeAnimator.setDuration(SWIPE_PIP_TO_HOME_DURATION);
mSwipePipToHomeAnimator.setInterpolator(interpolator);
mSwipePipToHomeAnimator.setFloatValues(FRACTION_START, FRACTION_END);
mSwipePipToHomeAnimator.start();
mRunningWindowAnim = RunningWindowAnim.wrap(mSwipePipToHomeAnimator);
windowAnim = mSwipePipToHomeAnimator;
} else {
mSwipePipToHomeAnimator = null;
RectFSpringAnim windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
windowAnim.addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
@ -1158,9 +1152,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
}
});
windowAnim.start(mContext, velocityPxPerMs);
mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
}
windowAnim.start(mContext, velocityPxPerMs);
mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
homeAnimFactory.setSwipeVelocity(velocityPxPerMs.y);
homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
mLauncherTransitionController = null;
@ -1216,7 +1210,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
}
private SwipePipToHomeAnimator getSwipePipToHomeAnimator(HomeAnimationFactory homeAnimFactory,
private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
RemoteAnimationTargetCompat runningTaskTarget, float startProgress) {
// Directly animate the app to PiP (picture-in-picture) mode
final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask();
@ -1229,16 +1223,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
runningTaskTarget.taskInfo.pictureInPictureParams,
homeRotation,
mDp.hotseatBarSizePx);
final Rect startBounds = new Rect();
updateProgressForStartRect(new Matrix(), startProgress).round(startBounds);
final SwipePipToHomeAnimator swipePipToHomeAnimator = new SwipePipToHomeAnimator(
mContext,
runningTaskTarget.taskId,
taskInfo.topActivity,
runningTaskTarget.leash.getSurfaceControl(),
TaskInfoCompat.getPipSourceRectHint(
runningTaskTarget.taskInfo.pictureInPictureParams),
TaskInfoCompat.getWindowConfigurationBounds(taskInfo),
startBounds,
updateProgressForStartRect(new Matrix(), startProgress),
destinationBounds,
mRecentsView.getPipCornerRadius(),
mRecentsView);
@ -1250,7 +1243,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
AnimatorPlaybackController activityAnimationToHome =
homeAnimFactory.createActivityAnimationToHome();
swipePipToHomeAnimator.addListener(new AnimatorListenerAdapter() {
swipePipToHomeAnimator.addAnimatorListener(new AnimatorListenerAdapter() {
private boolean mHasAnimationEnded;
@Override
public void onAnimationStart(Animator animation) {

View File

@ -20,8 +20,8 @@ import static com.android.systemui.shared.system.InteractionJankMonitorWrapper.C
import android.animation.Animator;
import android.animation.RectEvaluator;
import android.animation.ValueAnimator;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
@ -44,30 +44,24 @@ import com.android.systemui.shared.pip.PipSurfaceTransactionHelper;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
/**
* An {@link Animator} that animates an Activity to PiP (picture-in-picture) window when
* swiping up (in gesture navigation mode). Note that this class is derived from
* {@link com.android.wm.shell.pip.PipAnimationController.PipTransitionAnimator}.
*
* TODO: consider sharing this class including the animator and leash operations between
* Launcher and SysUI. Also, there should be one source of truth for the corner radius of the
* PiP window, which would ideally be on SysUI side as well.
* Subclass of {@link RectFSpringAnim} that animates an Activity to PiP (picture-in-picture) window
* when swiping up (in gesture navigation mode).
*/
public class SwipePipToHomeAnimator extends ValueAnimator {
public class SwipePipToHomeAnimator extends RectFSpringAnim {
private static final String TAG = SwipePipToHomeAnimator.class.getSimpleName();
public static final float FRACTION_START = 0f;
public static final float FRACTION_END = 1f;
private static final float END_PROGRESS = 1.0f;
private final int mTaskId;
private final ComponentName mComponentName;
private final SurfaceControl mLeash;
private final Rect mAppBounds = new Rect();
private final Rect mStartBounds = new Rect();
private final Rect mCurrentBounds = new Rect();
private final Rect mDestinationBounds = new Rect();
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
/** for calculating the transform in {@link #onAnimationUpdate(ValueAnimator)} */
private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
/** for calculating transform in {@link #onAnimationUpdate(AppCloseConfig, RectF, float)} */
private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
private final Rect mSourceHintRectInsets;
private final Rect mSourceInsets = new Rect();
@ -90,6 +84,7 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
private SurfaceControl mContentOverlay;
/**
* @param context {@link Context} provides Launcher resources
* @param taskId Task id associated with this animator, see also {@link #getTaskId()}
* @param componentName Component associated with this animator,
* see also {@link #getComponentName()}
@ -102,20 +97,22 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
* @param destinationBounds Bounds of the destination this animator ends to
* @param cornerRadius Corner radius in pixel value for PiP window
*/
public SwipePipToHomeAnimator(int taskId,
public SwipePipToHomeAnimator(@NonNull Context context,
int taskId,
@NonNull ComponentName componentName,
@NonNull SurfaceControl leash,
@Nullable Rect sourceRectHint,
@NonNull Rect appBounds,
@NonNull Rect startBounds,
@NonNull RectF startBounds,
@NonNull Rect destinationBounds,
int cornerRadius,
@NonNull View view) {
super(startBounds, new RectF(destinationBounds), context);
mTaskId = taskId;
mComponentName = componentName;
mLeash = leash;
mAppBounds.set(appBounds);
mStartBounds.set(startBounds);
startBounds.round(mStartBounds);
mDestinationBounds.set(destinationBounds);
mDestinationBoundsTransformed.set(mDestinationBounds);
mDestinationBoundsAnimation.set(mDestinationBounds);
@ -151,10 +148,10 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
t.reparent(mContentOverlay, mLeash);
t.apply();
addUpdateListener(valueAnimator -> {
float alpha = valueAnimator.getAnimatedFraction() < 0.5f
addOnUpdateListener((values, currentRect, progress) -> {
float alpha = progress < 0.5f
? 0
: Utilities.mapToRange(valueAnimator.getAnimatedFraction(), 0.5f, 1f,
: Utilities.mapToRange(Math.min(progress, 1f), 0.5f, 1f,
0f, 1f, Interpolators.FAST_OUT_SLOW_IN);
t.setAlpha(mContentOverlay, alpha);
t.apply();
@ -166,7 +163,7 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
appBounds.bottom - sourceRectHint.bottom);
}
addListener(new AnimationSuccessListener() {
addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
InteractionJankMonitorWrapper.begin(view, CUJ_APP_CLOSE_TO_PIP);
@ -191,7 +188,7 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
mHasAnimationEnded = true;
}
});
addUpdateListener(this::onAnimationUpdate);
addOnUpdateListener(this::onAnimationUpdate);
}
/** sets the from rotation if it's different from the target rotation. */
@ -219,34 +216,34 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
mAppBounds.top + mDestinationBounds.height());
}
private void onAnimationUpdate(ValueAnimator animator) {
private void onAnimationUpdate(@Nullable AppCloseConfig values, RectF currentRect,
float progress) {
if (mHasAnimationEnded) return;
final SurfaceControl.Transaction tx =
PipSurfaceTransactionHelper.newSurfaceControlTransaction();
onAnimationUpdate(tx, animator.getAnimatedFraction());
onAnimationUpdate(tx, currentRect, progress);
tx.apply();
}
private PictureInPictureSurfaceTransaction onAnimationUpdate(SurfaceControl.Transaction tx,
float fraction) {
final Rect bounds = mRectEvaluator.evaluate(fraction, mStartBounds,
mDestinationBoundsAnimation);
RectF currentRect, float progress) {
currentRect.round(mCurrentBounds);
final PictureInPictureSurfaceTransaction op;
if (mSourceHintRectInsets == null) {
// no source rect hint been set, directly scale the window down
op = onAnimationScale(fraction, tx, bounds);
op = onAnimationScale(progress, tx, mCurrentBounds);
} else {
// scale and crop according to the source rect hint
op = onAnimationScaleAndCrop(fraction, tx, bounds);
op = onAnimationScaleAndCrop(progress, tx, mCurrentBounds);
}
return op;
}
/** scale the window directly with no source rect hint being set */
private PictureInPictureSurfaceTransaction onAnimationScale(
float fraction, SurfaceControl.Transaction tx, Rect bounds) {
float progress, SurfaceControl.Transaction tx, Rect bounds) {
if (mFromRotation == Surface.ROTATION_90 || mFromRotation == Surface.ROTATION_270) {
final RotatedPosition rotatedPosition = getRotatedPosition(fraction);
final RotatedPosition rotatedPosition = getRotatedPosition(progress);
return mSurfaceTransactionHelper.scale(tx, mLeash, mAppBounds, bounds,
rotatedPosition.degree, rotatedPosition.positionX, rotatedPosition.positionY);
} else {
@ -256,12 +253,12 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
/** scale and crop the window with source rect hint */
private PictureInPictureSurfaceTransaction onAnimationScaleAndCrop(
float fraction, SurfaceControl.Transaction tx,
float progress, SurfaceControl.Transaction tx,
Rect bounds) {
final Rect insets = mInsetsEvaluator.evaluate(fraction, mSourceInsets,
final Rect insets = mInsetsEvaluator.evaluate(progress, mSourceInsets,
mSourceHintRectInsets);
if (mFromRotation == Surface.ROTATION_90 || mFromRotation == Surface.ROTATION_270) {
final RotatedPosition rotatedPosition = getRotatedPosition(fraction);
final RotatedPosition rotatedPosition = getRotatedPosition(progress);
return mSurfaceTransactionHelper.scaleAndRotate(tx, mLeash, mAppBounds, bounds, insets,
rotatedPosition.degree, rotatedPosition.positionX, rotatedPosition.positionY);
} else {
@ -291,22 +288,22 @@ public class SwipePipToHomeAnimator extends ValueAnimator {
// get the final leash operations but do not apply to the leash.
final SurfaceControl.Transaction tx =
PipSurfaceTransactionHelper.newSurfaceControlTransaction();
return onAnimationUpdate(tx, FRACTION_END);
return onAnimationUpdate(tx, new RectF(mDestinationBounds), END_PROGRESS);
}
private RotatedPosition getRotatedPosition(float fraction) {
private RotatedPosition getRotatedPosition(float progress) {
final float degree, positionX, positionY;
if (mFromRotation == Surface.ROTATION_90) {
degree = -90 * fraction;
positionX = fraction * (mDestinationBoundsTransformed.left - mStartBounds.left)
degree = -90 * progress;
positionX = progress * (mDestinationBoundsTransformed.left - mStartBounds.left)
+ mStartBounds.left;
positionY = fraction * (mDestinationBoundsTransformed.bottom - mStartBounds.top)
positionY = progress * (mDestinationBoundsTransformed.bottom - mStartBounds.top)
+ mStartBounds.top;
} else {
degree = 90 * fraction;
positionX = fraction * (mDestinationBoundsTransformed.right - mStartBounds.left)
degree = 90 * progress;
positionX = progress * (mDestinationBoundsTransformed.right - mStartBounds.left)
+ mStartBounds.left;
positionY = fraction * (mDestinationBoundsTransformed.top - mStartBounds.top)
positionY = progress * (mDestinationBoundsTransformed.top - mStartBounds.top)
+ mStartBounds.top;
}
return new RotatedPosition(degree, positionX, positionY);