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

Commit b0e96db7 authored by Johannes Gallmann's avatar Johannes Gallmann
Browse files

Play predictive animation when quickly restarting back gesture after cancel

Bug: 327579977
Flag: ACONFIG com.android.systemui.predictive_back_system_anims TRUNKFOOD50
Test: atest BackProgressAnimatorTest
Test: atest BackAnimationControllerTest
Test: Manual, i.e. extensively testing all three system animations with quick swipes in succession
Change-Id: Ia8815088240084ce22246baa6d3562812462ab19
parent a9338897
Loading
Loading
Loading
Loading
+15 −46
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.window.BackEvent;
@@ -84,7 +83,6 @@ import java.lang.ref.WeakReference;
 *
 */
public class LauncherBackAnimationController {
    private static final int CANCEL_TRANSITION_DURATION = 233;
    private static final int SCRIM_FADE_DURATION = 233;
    private static final float MIN_WINDOW_SCALE = 0.85f;
    private static final float MAX_SCRIM_ALPHA_DARK = 0.8f;
@@ -95,15 +93,12 @@ public class LauncherBackAnimationController {
    private final Matrix mTransformMatrix = new Matrix();
    /** The window position at the beginning of the back animation. */
    private final Rect mStartRect = new Rect();
    /** The window position when the back gesture is cancelled. */
    private final RectF mCancelRect = new RectF();
    /** The current window position. */
    private final RectF mCurrentRect = new RectF();
    private final QuickstepLauncher mLauncher;
    private final int mWindowScaleMarginX;
    private float mWindowScaleEndCornerRadius;
    private float mWindowScaleStartCornerRadius;
    private final Interpolator mCancelInterpolator;
    private final Interpolator mProgressInterpolator = Interpolators.STANDARD_DECELERATE;
    private final Interpolator mVerticalMoveInterpolator = new DecelerateInterpolator();
    private final PointF mInitialTouchPos = new PointF();
@@ -142,8 +137,6 @@ public class LauncherBackAnimationController {
        loadCornerRadius();
        mWindowScaleMarginX = mLauncher.getResources().getDimensionPixelSize(
                R.dimen.swipe_back_window_scale_x_margin);
        mCancelInterpolator =
                AnimationUtils.loadInterpolator(mLauncher, R.interpolator.standard_interpolator);
    }

    /**
@@ -181,8 +174,7 @@ public class LauncherBackAnimationController {
            mHandler.post(() -> {
                LauncherBackAnimationController controller = mControllerRef.get();
                if (controller != null) {
                    mProgressAnimator.onBackCancelled(
                            controller::resetPositionAnimated);
                    mProgressAnimator.onBackCancelled(controller::onCancelFinished);
                }
            });
        }
@@ -262,25 +254,10 @@ public class LauncherBackAnimationController {
        public void onAnimationCancelled() {}
    }

    private void resetPositionAnimated() {
        ValueAnimator cancelAnimator = ValueAnimator.ofFloat(0, 1);
        mCancelRect.set(mCurrentRect);
        cancelAnimator.setDuration(CANCEL_TRANSITION_DURATION);
        cancelAnimator.setInterpolator(mCancelInterpolator);
        cancelAnimator.addUpdateListener(
                animation -> {
                    updateCancelProgress((float) animation.getAnimatedValue());
                });
        cancelAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // Refresh the status bar appearance to the original one.
    private void onCancelFinished() {
        customizeStatusBarAppearance(false);
        finishAnimation();
    }
        });
        cancelAnimator.start();
    }

    /** Unregisters the back to launcher callback in shell. */
    public void unregisterBackCallbacks() {
@@ -292,6 +269,14 @@ public class LauncherBackAnimationController {
    }

    private void startBack(BackMotionEvent backEvent) {
        // in case we're still animating an onBackCancelled event, let's remove the finish-
        // callback from the progress animator to prevent calling finishAnimation() before
        // restarting a new animation
        // Side note: startBack is never called during the post-commit phase if the back gesture
        // was committed (not cancelled). BackAnimationController prevents that. Therefore we
        // don't have to handle that case.
        mProgressAnimator.removeOnBackCancelledFinishCallback();

        mBackInProgress = true;
        RemoteAnimationTarget appTarget = backEvent.getDepartingAnimationTarget();

@@ -314,7 +299,9 @@ public class LauncherBackAnimationController {
                new RemoteAnimationTarget[]{ mBackTarget });
        setLauncherTargetViewVisible(false);
        mCurrentRect.set(mStartRect);
        if (mScrimLayer == null) {
            addScrimLayer();
        }
        mTransaction.apply();
    }

@@ -397,23 +384,6 @@ public class LauncherBackAnimationController {
        customizeStatusBarAppearance(progress > UPDATE_SYSUI_FLAGS_THRESHOLD);
    }

    private void updateCancelProgress(float progress) {
        if (mBackTarget == null) {
            return;
        }
        mCurrentRect.set(
                Utilities.mapRange(progress, mCancelRect.left, mStartRect.left),
                Utilities.mapRange(progress, mCancelRect.top, mStartRect.top),
                Utilities.mapRange(progress, mCancelRect.right, mStartRect.right),
                Utilities.mapRange(progress, mCancelRect.bottom, mStartRect.bottom));

        float endCornerRadius = Utilities.mapRange(
                mBackProgress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius);
        float cornerRadius = Utilities.mapRange(
                progress, endCornerRadius, mWindowScaleStartCornerRadius);
        applyTransform(mCurrentRect, cornerRadius);
    }

    /** Transform the target window to match the target rect. */
    private void applyTransform(RectF targetRect, float cornerRadius) {
        final float scale = targetRect.width() / mStartRect.width();
@@ -484,7 +454,6 @@ public class LauncherBackAnimationController {
        mBackInProgress = false;
        mBackProgress = 0;
        mTransformMatrix.reset();
        mCancelRect.setEmpty();
        mCurrentRect.setEmpty();
        mStartRect.setEmpty();
        mInitialTouchPos.set(0, 0);