Add swipe up resistance to quick switch from home
Bug: 149934536
Change-Id: I1b355a16d972f94d541231449ef323a41861a3e6
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 821ada4..5c9fd47 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
-import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_5;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
@@ -47,6 +46,7 @@
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
+import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import android.animation.Animator;
@@ -74,7 +74,9 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.VibratorWrapper;
+import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.ShelfPeekAnim;
@@ -90,16 +92,17 @@
BothAxesSwipeDetector.Listener, MotionPauseDetector.OnMotionPauseListener {
/** The minimum progress of the scale/translationY animation until drag end. */
- private static final float Y_ANIM_MIN_PROGRESS = 0.15f;
+ private static final float Y_ANIM_MIN_PROGRESS = 0.25f;
private static final Interpolator FADE_OUT_INTERPOLATOR = DEACCEL_5;
private static final Interpolator TRANSLATE_OUT_INTERPOLATOR = ACCEL_0_75;
- private static final Interpolator SCALE_DOWN_INTERPOLATOR = DEACCEL;
+ private static final Interpolator SCALE_DOWN_INTERPOLATOR = LINEAR;
private final BaseQuickstepLauncher mLauncher;
private final BothAxesSwipeDetector mSwipeDetector;
private final ShelfPeekAnim mShelfPeekAnim;
private final float mXRange;
private final float mYRange;
+ private final float mMaxYProgress;
private final MotionPauseDetector mMotionPauseDetector;
private final float mMotionPauseMinDisplacement;
private final LauncherRecentsView mRecentsView;
@@ -113,7 +116,7 @@
// and the other two to set overview properties based on x and y progress.
private AnimatorPlaybackController mNonOverviewAnim;
private AnimatorPlaybackController mXOverviewAnim;
- private AnimatorPlaybackController mYOverviewAnim;
+ private AnimatedFloat mYOverviewAnim;
public NoButtonQuickSwitchTouchController(BaseQuickstepLauncher launcher) {
mLauncher = launcher;
@@ -123,6 +126,7 @@
mXRange = mLauncher.getDeviceProfile().widthPx / 2f;
mYRange = LayoutUtils.getShelfTrackingDistance(
mLauncher, mLauncher.getDeviceProfile(), mRecentsView.getPagedOrientationHandler());
+ mMaxYProgress = mLauncher.getDeviceProfile().heightPx / mYRange;
mMotionPauseDetector = new MotionPauseDetector(mLauncher);
mMotionPauseMinDisplacement = mLauncher.getResources().getDimension(
R.dimen.motion_pause_detector_min_displacement_from_app);
@@ -270,8 +274,18 @@
SCALE_DOWN_INTERPOLATOR);
yAnim.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
toState.getOverviewFullscreenProgress(), SCALE_DOWN_INTERPOLATOR);
- mYOverviewAnim = yAnim.createPlaybackController();
- mYOverviewAnim.dispatchOnStart();
+ AnimatorPlaybackController yNormalController = yAnim.createPlaybackController();
+ AnimatorControllerWithResistance yAnimWithResistance = AnimatorControllerWithResistance
+ .createForRecents(yNormalController, mLauncher,
+ mRecentsView.getPagedViewOrientedState(), mLauncher.getDeviceProfile(),
+ mRecentsView, RECENTS_SCALE_PROPERTY, mRecentsView,
+ TASK_SECONDARY_TRANSLATION);
+ mYOverviewAnim = new AnimatedFloat(() -> {
+ if (mYOverviewAnim != null) {
+ yAnimWithResistance.setProgress(mYOverviewAnim.value, mMaxYProgress);
+ }
+ });
+ yNormalController.dispatchOnStart();
}
@Override
@@ -307,7 +321,7 @@
mXOverviewAnim.setPlayFraction(xProgress);
}
if (mYOverviewAnim != null) {
- mYOverviewAnim.setPlayFraction(yProgress);
+ mYOverviewAnim.updateValue(yProgress);
}
return true;
}
@@ -354,9 +368,11 @@
} else if (verticalFling) {
targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
} else {
- // If user isn't flinging, just snap to the closest state based on x progress.
+ // If user isn't flinging, just snap to the closest state.
boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
- targetState = passedHorizontalThreshold ? QUICK_SWITCH : NORMAL;
+ boolean passedVerticalThreshold = mYOverviewAnim.value > 1f;
+ targetState = passedHorizontalThreshold && !passedVerticalThreshold
+ ? QUICK_SWITCH : NORMAL;
}
// Animate the various components to the target state.
@@ -375,9 +391,9 @@
boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
- float yProgress = mYOverviewAnim.getProgressFraction();
+ float yProgress = mYOverviewAnim.value;
float startYProgress = Utilities.boundToRange(yProgress
- - velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, 1f);
+ - velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, mMaxYProgress);
final float endYProgress;
if (flingUpToNormal) {
endYProgress = 1;
@@ -387,12 +403,11 @@
} else {
endYProgress = 0;
}
- long yDuration = BaseSwipeDetector.calculateDuration(velocity.y,
- Math.abs(endYProgress - startYProgress));
- ValueAnimator yOverviewAnim = mYOverviewAnim.getAnimationPlayer();
- yOverviewAnim.setFloatValues(startYProgress, endYProgress);
+ float yDistanceToCover = Math.abs(endYProgress - startYProgress) * mYRange;
+ long yDuration = (long) (yDistanceToCover / Math.max(1f, Math.abs(velocity.y)));
+ ValueAnimator yOverviewAnim = mYOverviewAnim.animateToValue(startYProgress, endYProgress);
yOverviewAnim.setDuration(yDuration);
- mYOverviewAnim.dispatchOnStart();
+ mYOverviewAnim.updateValue(startYProgress);
ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
if (flingUpToNormal && !mIsHomeScreenVisible) {
@@ -457,7 +472,7 @@
mXOverviewAnim.getAnimationPlayer().cancel();
}
if (mYOverviewAnim != null) {
- mYOverviewAnim.getAnimationPlayer().cancel();
+ mYOverviewAnim.cancelAnimation();
}
mShelfPeekAnim.setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
mMotionPauseDetector.clear();