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

Commit 354a436f authored by Tony Wickham's avatar Tony Wickham
Browse files

Rewrite long swipe resistance ("pullback") logic

- Rename "pullback" to "resistance" to reduce confusion.
- Remove mDragLengthFactorStartPullback & mDragLengthFactorMaxPullback
- Add AnimatorControllerWithResistance, which has 2 controllers, one
  for the normal shift to overview, then one to apply the resistance
  when swiping beyond that.
- Don't hack animator interpolators/progress; insteaad, allow progress
  to go > 1 (which will run the separate resistance animator).
- Don't start launcher controller separately from window controller;
  instead, both are controlled by mCurrentShift in updateFinalShift().
- The resistance animation logic is shared by both the active window
  and launcher (RecentsView).

Bug: 149934536
Change-Id: Ib0f9da18e10cc9ddf1a2f82ed767f237c89d3a41
Merged-In: Ib0f9da18e10cc9ddf1a2f82ed767f237c89d3a41
parent d3544435
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -79,8 +79,8 @@ final class AppToOverviewAnimationProvider<T extends StatefulActivity<?>> extend
        BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI(
                mDeviceState,
                wasVisible, (controller) -> {
                    controller.dispatchOnStart();
                    controller.getAnimationPlayer().end();
                    controller.getNormalController().dispatchOnStart();
                    controller.getNormalController().getAnimationPlayer().end();
                });
        factory.createActivityInterface(RECENTS_LAUNCH_DURATION);
        factory.setRecentsAttachedToAppWindow(true, false);
+1 −2
Original line number Diff line number Diff line
@@ -365,8 +365,7 @@ public abstract class BaseSwipeUpHandler<T extends StatefulActivity<?>, Q extend
     */
    protected void applyWindowTransform() {
        if (mWindowTransitionController != null) {
            float progress = mCurrentShift.value / mDragLengthFactor;
            mWindowTransitionController.setPlayFraction(progress);
            mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
        }
        if (mRecentsAnimationTargets != null) {
            if (mRecentsViewScrollLinked) {
+11 −44
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
@@ -45,7 +44,6 @@ import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHO
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;

import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager;
@@ -67,7 +65,6 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.UserEventDispatcher;
@@ -80,6 +77,7 @@ import com.android.quickstep.BaseActivityInterface.AnimationFactory;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.ShelfPeekAnim;
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
@@ -181,8 +179,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
    private ThumbnailData mTaskSnapshot;

    // Used to control launcher components throughout the swipe gesture.
    private AnimatorPlaybackController mLauncherTransitionController;
    private boolean mHasLauncherTransitionControllerStarted;
    private AnimatorControllerWithResistance mLauncherTransitionController;

    private AnimationFactory mAnimationFactory = (t) -> { };

@@ -528,11 +525,11 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte

    /**
     * We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
     * (it has its own animation) or if we're already animating the current controller.
     * (it has its own animation).
     * @return Whether we can create the launcher controller or update its progress.
     */
    private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
        return mGestureState.getEndTarget() != HOME && !mHasLauncherTransitionControllerStarted;
        return mGestureState.getEndTarget() != HOME;
    }

    @Override
@@ -542,10 +539,9 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
        return result;
    }

    private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
    private void onAnimatorPlaybackControllerCreated(AnimatorControllerWithResistance anim) {
        mLauncherTransitionController = anim;
        mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor);
        mLauncherTransitionController.dispatchOnStart();
        mLauncherTransitionController.getNormalController().dispatchOnStart();
        updateLauncherTransitionProgress();
    }

@@ -582,10 +578,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
                || !canCreateNewOrUpdateExistingLauncherTransitionController()) {
            return;
        }
        // Normalize the progress to 0 to 1, as the animation controller will clamp it to that
        // anyway. The controller mimics the drag length factor by applying it to its interpolators.
        float progress = mCurrentShift.value / mDragLengthFactor;
        mLauncherTransitionController.setPlayFraction(progress);
        mLauncherTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
    }

    /**
@@ -1028,31 +1021,6 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
            windowAnim.start();
            mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
        }
        // Always play the entire launcher animation when going home, since it is separate from
        // the animation that has been controlled thus far.
        if (mGestureState.getEndTarget() == HOME) {
            start = 0;
        }

        // We want to use the same interpolator as the window, but need to adjust it to
        // interpolate over the remaining progress (end - start).
        TimeInterpolator adjustedInterpolator = Interpolators.mapToProgress(
                interpolator, start, end);
        if (mLauncherTransitionController == null) {
            return;
        }
        if (start == end || duration <= 0) {
            mLauncherTransitionController.dispatchSetInterpolator(t -> end);
        } else {
            mLauncherTransitionController.dispatchSetInterpolator(adjustedInterpolator);
        }
        mLauncherTransitionController.getAnimationPlayer().setDuration(Math.max(0, duration));

        if (UNSTABLE_SPRINGS.get()) {
            mLauncherTransitionController.dispatchOnStart();
        }
        mLauncherTransitionController.getAnimationPlayer().start();
        mHasLauncherTransitionControllerStarted = true;
    }

    private void computeRecentsScrollIfInvisible() {
@@ -1173,10 +1141,6 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
    private void cancelCurrentAnimation() {
        mCanceled = true;
        mCurrentShift.cancelAnimation();
        if (mLauncherTransitionController != null && mLauncherTransitionController
                .getAnimationPlayer().isStarted()) {
            mLauncherTransitionController.getAnimationPlayer().cancel();
        }
    }

    private void invalidateHandler() {
@@ -1202,7 +1166,10 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
    private void endLauncherTransitionController() {
        setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
        if (mLauncherTransitionController != null) {
            mLauncherTransitionController.getAnimationPlayer().end();
            // End the animation, but stay at the same visual progress.
            mLauncherTransitionController.getNormalController().dispatchSetInterpolator(
                    t -> Utilities.boundToRange(mCurrentShift.value, 0, 1));
            mLauncherTransitionController.getNormalController().getAnimationPlayer().end();
            mLauncherTransitionController = null;
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -27,11 +27,11 @@ import androidx.annotation.Nullable;

import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;

@@ -84,7 +84,7 @@ public final class FallbackActivityInterface extends
    /** 6 */
    @Override
    public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
            boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
            boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
        DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
        factory.initUI();
        return factory;
+2 −2
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import com.android.launcher3.LauncherInitListener;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.appprediction.PredictionUiStateManager;
import com.android.launcher3.statehandlers.DepthController;
@@ -50,6 +49,7 @@ import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
import com.android.quickstep.views.RecentsView;
@@ -119,7 +119,7 @@ public final class LauncherActivityInterface extends

    @Override
    public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
            boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
            boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
        notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
        DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
            @Override
Loading