Merge "Use RectFSpringAnim for auto-enter-pip" into sc-dev
This commit is contained in:
commit
e3bfeddd04
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue