From 3b86202a95e4d34fd3f9247ba530d317c68aa18f Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Mon, 1 Nov 2021 20:02:50 -0600 Subject: [PATCH] Fling to close tasks in the GestureNav can be too small. The problem is that the velocity threshold to activate the fling was set using pixels per second, so a better aproach would is to use dp/s. So now there is a variable set in the dimes.xml file called base_swift_detector_fling_release_velocity. Test: Manually tested Fix: 201252634 Change-Id: Ief14f25de136dead74f03cb24d2120b67900239e --- res/values/dimens.xml | 3 +++ .../launcher3/touch/BaseSwipeDetector.java | 17 ++++++++---- .../touch/BothAxesSwipeDetector.java | 9 +------ .../touch/SingleAxisSwipeDetector.java | 10 ++++--- .../touch/SingleAxisSwipeDetectorTest.java | 27 ++++++++++++------- 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 2cf929f6dd..3c91c7abe3 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -320,6 +320,9 @@ 16dp + + 1dp + 0dp 0dp diff --git a/src/com/android/launcher3/touch/BaseSwipeDetector.java b/src/com/android/launcher3/touch/BaseSwipeDetector.java index 1276ece7e2..52c358143a 100644 --- a/src/com/android/launcher3/touch/BaseSwipeDetector.java +++ b/src/com/android/launcher3/touch/BaseSwipeDetector.java @@ -17,6 +17,7 @@ package com.android.launcher3.touch; import static android.view.MotionEvent.INVALID_POINTER_ID; +import android.content.Context; import android.graphics.PointF; import android.util.Log; import android.view.MotionEvent; @@ -26,6 +27,8 @@ import android.view.ViewConfiguration; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import com.android.launcher3.R; + import java.util.LinkedList; import java.util.Queue; @@ -44,10 +47,9 @@ public abstract class BaseSwipeDetector { private static final boolean DBG = false; private static final String TAG = "BaseSwipeDetector"; private static final float ANIMATION_DURATION = 1200; - /** The minimum release velocity in pixels per millisecond that triggers fling.*/ - private static final float RELEASE_VELOCITY_PX_MS = 1.0f; private static final PointF sTempPoint = new PointF(); + private final float mReleaseVelocity; private final PointF mDownPos = new PointF(); private final PointF mLastPos = new PointF(); protected final boolean mIsRtl; @@ -64,6 +66,7 @@ public abstract class BaseSwipeDetector { private boolean mIsSettingState; protected boolean mIgnoreSlopWhenSettling; + protected Context mContext; private enum ScrollState { IDLE, @@ -71,10 +74,14 @@ public abstract class BaseSwipeDetector { SETTLING // onDragEnd } - protected BaseSwipeDetector(@NonNull ViewConfiguration config, boolean isRtl) { + protected BaseSwipeDetector(@NonNull Context context, @NonNull ViewConfiguration config, + boolean isRtl) { mTouchSlop = config.getScaledTouchSlop(); mMaxVelocity = config.getScaledMaximumFlingVelocity(); mIsRtl = isRtl; + mContext = context; + mReleaseVelocity = mContext.getResources() + .getDimensionPixelSize(R.dimen.base_swift_detector_fling_release_velocity); } public static long calculateDuration(float velocity, float progressNeeded) { @@ -120,7 +127,7 @@ public abstract class BaseSwipeDetector { } public boolean isFling(float velocity) { - return Math.abs(velocity) > RELEASE_VELOCITY_PX_MS; + return Math.abs(velocity) > mReleaseVelocity; } public boolean onTouchEvent(MotionEvent ev) { @@ -236,7 +243,7 @@ public abstract class BaseSwipeDetector { } else { mSubtractDisplacement.x = mDisplacement.x > 0 ? mTouchSlop : -mTouchSlop; mSubtractDisplacement.y = mDisplacement.y > 0 ? mTouchSlop : -mTouchSlop; - } + } } protected abstract boolean shouldScrollStart(PointF displacement); diff --git a/src/com/android/launcher3/touch/BothAxesSwipeDetector.java b/src/com/android/launcher3/touch/BothAxesSwipeDetector.java index 944391e9b4..6e2f0d86c4 100644 --- a/src/com/android/launcher3/touch/BothAxesSwipeDetector.java +++ b/src/com/android/launcher3/touch/BothAxesSwipeDetector.java @@ -21,7 +21,6 @@ import android.view.MotionEvent; import android.view.ViewConfiguration; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import com.android.launcher3.Utilities; @@ -43,13 +42,7 @@ public class BothAxesSwipeDetector extends BaseSwipeDetector { private int mScrollDirections; public BothAxesSwipeDetector(@NonNull Context context, @NonNull Listener l) { - this(ViewConfiguration.get(context), l, Utilities.isRtl(context.getResources())); - } - - @VisibleForTesting - protected BothAxesSwipeDetector(@NonNull ViewConfiguration config, @NonNull Listener l, - boolean isRtl) { - super(config, isRtl); + super(context, ViewConfiguration.get(context), Utilities.isRtl(context.getResources())); mListener = l; } diff --git a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java index f751b7d505..5c599c06bf 100644 --- a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java +++ b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java @@ -106,13 +106,15 @@ public class SingleAxisSwipeDetector extends BaseSwipeDetector { public SingleAxisSwipeDetector(@NonNull Context context, @NonNull Listener l, @NonNull Direction dir) { - this(ViewConfiguration.get(context), l, dir, Utilities.isRtl(context.getResources())); + super(context, ViewConfiguration.get(context), Utilities.isRtl(context.getResources())); + mListener = l; + mDir = dir; } @VisibleForTesting - protected SingleAxisSwipeDetector(@NonNull ViewConfiguration config, @NonNull Listener l, - @NonNull Direction dir, boolean isRtl) { - super(config, isRtl); + protected SingleAxisSwipeDetector(@NonNull Context context, @NonNull ViewConfiguration config, + @NonNull Listener l, @NonNull Direction dir, boolean isRtl) { + super(context, config, isRtl); mListener = l; mDir = dir; } diff --git a/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java b/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java index 472e1a1c91..260f5568e0 100644 --- a/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java +++ b/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import android.content.Context; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -58,6 +59,7 @@ public class SingleAxisSwipeDetectorTest { private TouchEventGenerator mGenerator; private SingleAxisSwipeDetector mDetector; private int mTouchSlop; + Context mContext; @Mock private SingleAxisSwipeDetector.Listener mMockListener; @@ -69,12 +71,13 @@ public class SingleAxisSwipeDetectorTest { public void setup() { MockitoAnnotations.initMocks(this); mGenerator = new TouchEventGenerator((ev) -> mDetector.onTouchEvent(ev)); - ViewConfiguration orgConfig = ViewConfiguration - .get(InstrumentationRegistry.getTargetContext()); + mContext = InstrumentationRegistry.getTargetContext(); + ViewConfiguration orgConfig = ViewConfiguration.get(mContext); doReturn(orgConfig.getScaledMaximumFlingVelocity()).when(mMockConfig) .getScaledMaximumFlingVelocity(); - mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, VERTICAL, false); + mDetector = new SingleAxisSwipeDetector(mContext, + mMockConfig, mMockListener, VERTICAL, false); mDetector.setDetectableScrollConditions(DIRECTION_BOTH, false); mTouchSlop = orgConfig.getScaledTouchSlop(); doReturn(mTouchSlop).when(mMockConfig).getScaledTouchSlop(); @@ -84,7 +87,8 @@ public class SingleAxisSwipeDetectorTest { @Test public void testDragStart_verticalPositive() { - mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, VERTICAL, false); + mDetector = new SingleAxisSwipeDetector(mContext, + mMockConfig, mMockListener, VERTICAL, false); mDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false); mGenerator.put(0, 100, 100); mGenerator.move(0, 100, 100 - mTouchSlop); @@ -94,7 +98,8 @@ public class SingleAxisSwipeDetectorTest { @Test public void testDragStart_verticalNegative() { - mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, VERTICAL, false); + mDetector = new SingleAxisSwipeDetector(mContext, + mMockConfig, mMockListener, VERTICAL, false); mDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false); mGenerator.put(0, 100, 100); mGenerator.move(0, 100, 100 + mTouchSlop); @@ -112,7 +117,8 @@ public class SingleAxisSwipeDetectorTest { @Test public void testDragStart_horizontalPositive() { - mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, false); + mDetector = new SingleAxisSwipeDetector(mContext, + mMockConfig, mMockListener, HORIZONTAL, false); mDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false); mGenerator.put(0, 100, 100); @@ -123,7 +129,8 @@ public class SingleAxisSwipeDetectorTest { @Test public void testDragStart_horizontalNegative() { - mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, false); + mDetector = new SingleAxisSwipeDetector(mContext, + mMockConfig, mMockListener, HORIZONTAL, false); mDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false); mGenerator.put(0, 100, 100); @@ -134,7 +141,8 @@ public class SingleAxisSwipeDetectorTest { @Test public void testDragStart_horizontalRtlPositive() { - mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, true); + mDetector = new SingleAxisSwipeDetector(mContext, + mMockConfig, mMockListener, HORIZONTAL, true); mDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false); mGenerator.put(0, 100, 100); @@ -145,7 +153,8 @@ public class SingleAxisSwipeDetectorTest { @Test public void testDragStart_horizontalRtlNegative() { - mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, true); + mDetector = new SingleAxisSwipeDetector(mContext, + mMockConfig, mMockListener, HORIZONTAL, true); mDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false); mGenerator.put(0, 100, 100);