Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3bfeddd authored by Hongwei Wang's avatar Hongwei Wang Committed by Android (Google) Code Review
Browse files

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

parents 640fc8b8 9d3e31e6
Loading
Loading
Loading
Loading
+10 −17
Original line number Diff line number Diff line
@@ -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);
            }
            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) {
+38 −41
Original line number Diff line number Diff line
@@ -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);