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

Commit 2152ba0a authored by Tony Wickham's avatar Tony Wickham Committed by Android (Google) Code Review
Browse files

Merge changes Ib0fae780,I6d14f106 into ub-launcher3-master

* changes:
  Standardize quickstep velocities
  Don't detach recents from app window after motion pause
parents 406895cd 01e40708
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -35,16 +35,13 @@
             loading full resolution screenshots. -->
    <dimen name="recents_fast_fling_velocity">600dp</dimen>

    <!-- These velocities are in dp / s -->
    <dimen name="quickstep_fling_threshold_velocity">500dp</dimen>
    <dimen name="quickstep_fling_min_velocity">250dp</dimen>

    <!-- These speeds are in dp / ms -->
    <dimen name="motion_pause_detector_speed_very_slow">0.0285dp</dimen>
    <dimen name="motion_pause_detector_speed_slow">0.15dp</dimen>
    <dimen name="motion_pause_detector_speed_somewhat_fast">0.285dp</dimen>
    <dimen name="motion_pause_detector_speed_fast">1.4dp</dimen>
    <dimen name="motion_pause_detector_min_displacement_from_app">36dp</dimen>
    <dimen name="quickstep_fling_threshold_speed">0.5dp</dimen>

    <!-- Launcher app transition -->
    <dimen name="content_trans_y">50dp</dimen>
+10 −10
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
    private final float mMotionPauseMinDisplacement;

    private boolean mDidTouchStartInNavBar;
    private boolean mStartedOverview;
    private boolean mReachedOverview;
    // The last recorded displacement before we reached overview.
    private PointF mStartDisplacement = new PointF();
@@ -128,7 +129,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
        mMotionPauseDetector.clear();

        if (handlingOverviewAnim()) {
            mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged);
            mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected);
        }

        if (mFromState == NORMAL && mToState == HINT_STATE) {
@@ -138,6 +139,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
                    mFromState.getOverviewScrimAlpha(mLauncher),
                    mToState.getOverviewScrimAlpha(mLauncher));
        }
        mStartedOverview = false;
        mReachedOverview = false;
        mOverviewResistYAnim = null;
    }
@@ -152,7 +154,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch

    @Override
    public void onDragEnd(float velocity) {
        if (mMotionPauseDetector.isPaused() && handlingOverviewAnim()) {
        if (mStartedOverview) {
            goToOverviewOrHomeOnDragEnd(velocity);
        } else {
            super.onDragEnd(velocity);
@@ -185,7 +187,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
        }
    }

    private void onMotionPauseChanged(boolean isPaused) {
    private void onMotionPauseDetected() {
        if (mCurrentAnimation == null) {
            return;
        }
@@ -199,6 +201,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
                maybeSwipeInteractionToOverviewComplete();
            });
        });
        mStartedOverview = true;
        VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
    }

@@ -219,7 +222,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
        if (TestProtocol.sDebugTracing) {
            Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NoButtonNavbarToOverviewTouchController");
        }
        if (mMotionPauseDetector.isPaused()) {
        if (mStartedOverview) {
            if (!mReachedOverview) {
                mStartDisplacement.set(xDisplacement, yDisplacement);
                mStartY = event.getY();
@@ -234,8 +237,6 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
                            * OVERVIEW_MOVEMENT_FACTOR);
                }
            }
            // Stay in Overview.
            return true;
        }

        float upDisplacement = -yDisplacement;
@@ -243,13 +244,12 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
                || upDisplacement < mMotionPauseMinDisplacement);
        mMotionPauseDetector.addPosition(event);

        return super.onDrag(yDisplacement, xDisplacement, event);
        // Stay in Overview.
        return mStartedOverview || super.onDrag(yDisplacement, xDisplacement, event);
    }

    private void goToOverviewOrHomeOnDragEnd(float velocity) {
        float velocityDp = dpiFromPx(velocity);
        boolean isFling = Math.abs(velocityDp) > 1;
        boolean goToHomeInsteadOfOverview = isFling;
        boolean goToHomeInsteadOfOverview = !mMotionPauseDetector.isPaused();
        if (goToHomeInsteadOfOverview) {
            new OverviewToHomeAnim(mLauncher, ()-> onSwipeInteractionCompleted(NORMAL, Touch.FLING))
                    .animateWithVelocity(velocity);
+3 −4
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ import com.android.quickstep.views.LauncherRecentsView;
 * the user as possible, also handles swipe up and hold to go to overview and swiping back home.
 */
public class NoButtonQuickSwitchTouchController implements TouchController,
        BothAxesSwipeDetector.Listener, MotionPauseDetector.OnMotionPauseListener {
        BothAxesSwipeDetector.Listener {

    /** The minimum progress of the scale/translationY animation until drag end. */
    private static final float Y_ANIM_MIN_PROGRESS = 0.25f;
@@ -167,7 +167,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
        if (start) {
            mStartState = mLauncher.getStateManager().getState();

            mMotionPauseDetector.setOnMotionPauseListener(this);
            mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected);

            // We have detected horizontal drag start, now allow swipe up as well.
            mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT | DIRECTION_UP,
@@ -177,8 +177,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
        }
    }

    @Override
    public void onMotionPauseChanged(boolean isPaused) {
    private void onMotionPauseDetected() {
        VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
    }

+26 −19
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.InputConsumerProxy;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TransformParams;
@@ -201,6 +202,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
    // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
    private RunningWindowAnim mRunningWindowAnim;
    private boolean mIsMotionPaused;
    private boolean mHasMotionEverBeenPaused;

    private boolean mContinuingLastGesture;

@@ -482,15 +484,22 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
                .getHighResLoadingState().setVisible(true);
    }

    /**
     * Called when motion pause is detected
     */
    public void onMotionPauseChanged(boolean isPaused) {
        mIsMotionPaused = isPaused;
    public MotionPauseDetector.OnMotionPauseListener getMotionPauseListener() {
        return new MotionPauseDetector.OnMotionPauseListener() {
            @Override
            public void onMotionPauseDetected() {
                mHasMotionEverBeenPaused = true;
                maybeUpdateRecentsAttachedState();
                performHapticFeedback();
            }

            @Override
            public void onMotionPauseChanged(boolean isPaused) {
                mIsMotionPaused = isPaused;
            }
        };
    }

    public void maybeUpdateRecentsAttachedState() {
        maybeUpdateRecentsAttachedState(true /* animate */);
    }
@@ -519,7 +528,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
            // The window is going away so make sure recents is always visible in this case.
            recentsAttachedToAppWindow = true;
        } else {
            recentsAttachedToAppWindow = mIsMotionPaused || mIsLikelyToStartNewTask;
            recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask;
        }
        mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);

@@ -742,8 +751,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
    @UiThread
    public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) {
        float flingThreshold = mContext.getResources()
                .getDimension(R.dimen.quickstep_fling_threshold_velocity);
        boolean isFling = mGestureStarted && Math.abs(endVelocity) > flingThreshold;
                .getDimension(R.dimen.quickstep_fling_threshold_speed);
        boolean isFling = mGestureStarted && !mIsMotionPaused
                && Math.abs(endVelocity) > flingThreshold;
        mStateCallback.setStateOnUiThread(STATE_GESTURE_COMPLETED);

        mLogAction = isFling ? Touch.FLING : Touch.SWIPE;
@@ -858,7 +868,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends

            if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp && !willGoToNewTaskOnSwipeUp) {
                endTarget = HOME;
            } else if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp && !mIsMotionPaused) {
            } else if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp) {
                // If swiping at a diagonal, base end target on the faster velocity.
                endTarget = NEW_TASK;
            } else if (isSwipeUp) {
@@ -878,7 +888,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
    @UiThread
    private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity,
            boolean isCancel) {
        PointF velocityPxPerMs = new PointF(velocity.x / 1000, velocity.y / 1000);
        long duration = MAX_SWIPE_DURATION;
        float currentShift = mCurrentShift.value;
        final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
@@ -893,14 +902,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
            startShift = currentShift;
            interpolator = endTarget == RECENTS ? OVERSHOOT_1_2 : DEACCEL;
        } else {
            startShift = Utilities.boundToRange(currentShift - velocityPxPerMs.y
            startShift = Utilities.boundToRange(currentShift - velocity.y
                    * getSingleFrameMs(mContext) / mTransitionDragLength, 0, mDragLengthFactor);
            float minFlingVelocity = mContext.getResources()
                    .getDimension(R.dimen.quickstep_fling_min_velocity);
            if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) {
            if (mTransitionDragLength > 0) {
                if (endTarget == RECENTS && !mDeviceState.isFullyGesturalNavMode()) {
                    Interpolators.OvershootParams overshoot = new Interpolators.OvershootParams(
                            startShift, endShift, endShift, endVelocity / 1000,
                            startShift, endShift, endShift, endVelocity,
                            mTransitionDragLength, mContext);
                    endShift = overshoot.end;
                    interpolator = overshoot.interpolator;
@@ -912,7 +919,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
                    // we want the page's snap velocity to approximately match the velocity at
                    // which the user flings, so we scale the duration by a value near to the
                    // derivative of the scroll interpolator at zero, ie. 2.
                    long baseDuration = Math.round(Math.abs(distanceToTravel / velocityPxPerMs.y));
                    long baseDuration = Math.round(Math.abs(distanceToTravel / velocity.y));
                    duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration);

                    if (endTarget == RECENTS) {
@@ -952,7 +959,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
            mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED);
        }

        animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocityPxPerMs);
        animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocity);
    }

    private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
+3 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.view.MotionEvent.ACTION_UP;

import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
import static com.android.launcher3.util.VelocityUtils.PX_PER_MS;
import static com.android.quickstep.AbsSwipeUpHandler.MIN_PROGRESS_FOR_OVERVIEW;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
@@ -35,7 +36,6 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;

import com.android.launcher3.R;
import com.android.launcher3.anim.Interpolators;
@@ -180,12 +180,11 @@ public class DeviceLockedInputConsumer implements InputConsumer,
     */
    private void finishTouchTracking(MotionEvent ev) {
        if (mThresholdCrossed && ev.getAction() == ACTION_UP) {
            mVelocityTracker.computeCurrentVelocity(1000,
                    ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity());
            mVelocityTracker.computeCurrentVelocity(PX_PER_MS);

            float velocityY = mVelocityTracker.getYVelocity();
            float flingThreshold = mContext.getResources()
                    .getDimension(R.dimen.quickstep_fling_threshold_velocity);
                    .getDimension(R.dimen.quickstep_fling_threshold_speed);

            boolean dismissTask;
            if (Math.abs(velocityY) > flingThreshold) {
Loading