From 0f640b6c1b1f600f4c8c39cb915f7a02603f311a Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 9 May 2018 16:00:14 -0700 Subject: Make fling thresholds consistent There are 3 places we can block a fling: - Swiping from home to all apps (through overview) - Swiping from an app to all apps (through overview) - Dismissing a task (in the same gesture that started by swiping down) In all of these cases, we block the fling when crossing the threshold to a new state (e.g. OVERVIEW), but unblock if the user pauses their drag. With this change, the logic is consistent: - Unblock the fling after pausing a short amount of time - If a fling was blocked, increase the settling duration based on velocity Bug: 78089840 Bug: 78658678 Change-Id: I5ef52b74229418b867b26c3c6d3db2cf6e48914b --- .../uioverrides/TaskViewTouchController.java | 39 ++++++++++------------ .../src/com/android/quickstep/LongSwipeHelper.java | 20 +++++++++-- 2 files changed, 36 insertions(+), 23 deletions(-) (limited to 'quickstep') diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java index dc3f79cc5..a40573500 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java @@ -21,16 +21,17 @@ import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelo import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; -import android.util.Log; import android.view.MotionEvent; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; +import com.android.launcher3.util.FlingBlockCheck; import com.android.launcher3.util.PendingAnimation; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; @@ -46,8 +47,6 @@ public abstract class TaskViewTouchController private static final String TAG = "OverviewSwipeController"; - private static final float ALLOWED_FLING_DIRECTION_CHANGE_PROGRESS = 0.1f; - // Progress after which the transition is assumed to be a success in case user does not fling private static final float SUCCESS_TRANSITION_PROGRESS = 0.5f; @@ -65,6 +64,7 @@ public abstract class TaskViewTouchController private float mDisplacementShift; private float mProgressMultiplier; private float mEndDisplacement; + private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck(); private TaskView mTaskBeingDragged; @@ -93,7 +93,6 @@ public abstract class TaskViewTouchController @Override public void onAnimationCancel(Animator animation) { if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) { - Log.e(TAG, "Who dare cancel the animation when I am in control", new Exception()); clearState(); } } @@ -158,16 +157,16 @@ public abstract class TaskViewTouchController return mDetector.onTouchEvent(ev); } - private boolean reInitAnimationController(boolean goingUp) { + private void reInitAnimationController(boolean goingUp) { if (mCurrentAnimation != null && mCurrentAnimationIsGoingUp == goingUp) { // No need to init - return false; + return; } int scrollDirections = mDetector.getScrollDirections(); if (goingUp && ((scrollDirections & SwipeDetector.DIRECTION_POSITIVE) == 0) || !goingUp && ((scrollDirections & SwipeDetector.DIRECTION_NEGATIVE) == 0)) { // Trying to re-init in an unsupported direction. - return false; + return; } if (mCurrentAnimation != null) { mCurrentAnimation.setPlayFraction(0); @@ -205,7 +204,6 @@ public abstract class TaskViewTouchController mCurrentAnimation.getTarget().addListener(this); mCurrentAnimation.dispatchOnStart(); mProgressMultiplier = 1 / mEndDisplacement; - return true; } @Override @@ -217,6 +215,7 @@ public abstract class TaskViewTouchController mDisplacementShift = mCurrentAnimation.getProgressFraction() / mProgressMultiplier; mCurrentAnimation.pause(); } + mFlingBlockCheck.unblockFling(); } @Override @@ -226,6 +225,9 @@ public abstract class TaskViewTouchController totalDisplacement == 0 ? mCurrentAnimationIsGoingUp : totalDisplacement < 0; if (isGoingUp != mCurrentAnimationIsGoingUp) { reInitAnimationController(isGoingUp); + mFlingBlockCheck.blockFling(); + } else { + mFlingBlockCheck.onEvent(); } mCurrentAnimation.setPlayFraction(totalDisplacement * mProgressMultiplier); return true; @@ -235,22 +237,14 @@ public abstract class TaskViewTouchController public void onDragEnd(float velocity, boolean fling) { final boolean goingToEnd; final int logAction; + boolean blockedFling = fling && mFlingBlockCheck.isBlocked(); + if (blockedFling) { + fling = false; + } if (fling) { logAction = Touch.FLING; boolean goingUp = velocity < 0; - if (goingUp != mCurrentAnimationIsGoingUp) { - // In case the fling is in opposite direction, make sure if is close enough - // from the start position - if (mCurrentAnimation.getProgressFraction() - >= ALLOWED_FLING_DIRECTION_CHANGE_PROGRESS) { - // Not allowed - goingToEnd = false; - } else { - goingToEnd = reInitAnimationController(goingUp); - } - } else { - goingToEnd = true; - } + goingToEnd = goingUp == mCurrentAnimationIsGoingUp; } else { logAction = Touch.SWIPE; goingToEnd = mCurrentAnimation.getProgressFraction() > SUCCESS_TRANSITION_PROGRESS; @@ -259,6 +253,9 @@ public abstract class TaskViewTouchController float progress = mCurrentAnimation.getProgressFraction(); long animationDuration = SwipeDetector.calculateDuration( velocity, goingToEnd ? (1 - progress) : progress); + if (blockedFling && !goingToEnd) { + animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity); + } float nextFrameProgress = Utilities.boundToRange( progress + velocity * SINGLE_FRAME_MS / Math.abs(mEndDisplacement), 0f, 1f); diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java index edc745739..fbcde8bba 100644 --- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java +++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static com.android.launcher3.LauncherAnimUtils.MIN_PROGRESS_TO_ALL_APPS; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.anim.Interpolators.DEACCEL; @@ -26,6 +27,7 @@ import android.animation.ValueAnimator; import android.view.Surface; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.R; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.DiscoveryBounce; @@ -33,7 +35,9 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.launcher3.util.FlingBlockCheck; import com.android.quickstep.util.RemoteAnimationTargetSet; +import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.TransactionCompat; @@ -44,7 +48,6 @@ import com.android.systemui.shared.system.TransactionCompat; */ public class LongSwipeHelper { - private static final float MIN_PROGRESS_TO_ALL_APPS = 0.35f; private static final float SWIPE_DURATION_MULTIPLIER = Math.min(1 / MIN_PROGRESS_TO_ALL_APPS, 1 / (1 - MIN_PROGRESS_TO_ALL_APPS)); @@ -53,6 +56,7 @@ public class LongSwipeHelper { private float mMaxSwipeDistance = 1; private AnimatorPlaybackController mAnimator; + private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck(); LongSwipeHelper(Launcher launcher, RemoteAnimationTargetSet targetSet) { mLauncher = launcher; @@ -62,6 +66,7 @@ public class LongSwipeHelper { private void init() { setTargetAlpha(0, true); + mFlingBlockCheck.blockFling(); // Init animations AllAppsTransitionController controller = mLauncher.getAllAppsController(); @@ -74,6 +79,7 @@ public class LongSwipeHelper { public void onMove(float displacement) { mAnimator.setPlayFraction(displacement / mMaxSwipeDistance); + mFlingBlockCheck.onEvent(); } public void destroy() { @@ -90,6 +96,11 @@ public class LongSwipeHelper { final boolean toAllApps; float endProgress; + boolean blockedFling = isFling && mFlingBlockCheck.isBlocked(); + if (blockedFling) { + isFling = false; + } + if (!isFling) { toAllApps = currentFraction > MIN_PROGRESS_TO_ALL_APPS; endProgress = toAllApps ? 1 : 0; @@ -114,7 +125,11 @@ public class LongSwipeHelper { } } - mAnimator.setEndAction(() -> onSwipeAnimationComplete(toAllApps, isFling, callback)); + if (blockedFling && !toAllApps) { + duration *= LauncherAnimUtils.blockedFlingDurationFactor(0); + } + final boolean finalIsFling = isFling; + mAnimator.setEndAction(() -> onSwipeAnimationComplete(toAllApps, finalIsFling, callback)); ValueAnimator animator = mAnimator.getAnimationPlayer(); animator.setDuration(duration).setInterpolator(DEACCEL); animator.setFloatValues(currentFraction, endProgress); @@ -150,6 +165,7 @@ public class LongSwipeHelper { mLauncher.getStateManager().goToState(toAllApps ? ALL_APPS : OVERVIEW, false); if (!toAllApps) { DiscoveryBounce.showForOverviewIfNeeded(mLauncher); + mLauncher.getOverviewPanel().setSwipeDownShouldLaunchApp(true); } mLauncher.getUserEventDispatcher().logStateChangeAction( -- cgit v1.2.3