Merge "Some cleanup for SwipeDetector." into ub-launcher3-qt-future-dev
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index 32410a6..717a7e9 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.notification;
 
+import static com.android.launcher3.touch.SwipeDetector.HORIZONTAL;
+
 import android.app.Notification;
 import android.content.Context;
 import android.graphics.Color;
@@ -33,8 +35,6 @@
 
 import java.util.List;
 
-import static com.android.launcher3.touch.SwipeDetector.HORIZONTAL;
-
 /**
  * Utility class to manage notification UI
  */
diff --git a/src/com/android/launcher3/touch/SwipeDetector.java b/src/com/android/launcher3/touch/SwipeDetector.java
index 3777a41..d0edfd8 100644
--- a/src/com/android/launcher3/touch/SwipeDetector.java
+++ b/src/com/android/launcher3/touch/SwipeDetector.java
@@ -24,12 +24,11 @@
 import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
 
-import com.android.launcher3.Utilities;
-import com.android.launcher3.testing.TestProtocol;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.launcher3.Utilities;
+
 /**
  * One dimensional scroll/drag/swipe gesture detector.
  *
@@ -41,47 +40,14 @@
 
     private static final boolean DBG = false;
     private static final String TAG = "SwipeDetector";
+    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 int mScrollConditions;
     public static final int DIRECTION_POSITIVE = 1 << 0;
     public static final int DIRECTION_NEGATIVE = 1 << 1;
     public static final int DIRECTION_BOTH = DIRECTION_NEGATIVE | DIRECTION_POSITIVE;
 
-    private static final float ANIMATION_DURATION = 1200;
-
-    protected int mActivePointerId = INVALID_POINTER_ID;
-
-    /**
-     * The minimum release velocity in pixels per millisecond that triggers fling..
-     */
-    public static final float RELEASE_VELOCITY_PX_MS = 1.0f;
-
-    /* Scroll state, this is set to true during dragging and animation. */
-    private ScrollState mState = ScrollState.IDLE;
-
-    enum ScrollState {
-        IDLE,
-        DRAGGING,      // onDragStart, onDrag
-        SETTLING       // onDragEnd
-    }
-
-    public static abstract class Direction {
-
-        abstract float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint,
-                boolean isRtl);
-
-        /**
-         * Distance in pixels a touch can wander before we think the user is scrolling.
-         */
-        abstract float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos);
-
-        abstract float getVelocity(VelocityTracker tracker, boolean isRtl);
-
-        abstract boolean isPositive(float displacement);
-
-        abstract boolean isNegative(float displacement);
-    }
-
     public static final Direction VERTICAL = new Direction() {
 
         @Override
@@ -150,35 +116,54 @@
         }
     };
 
-    //------------------- ScrollState transition diagram -----------------------------------
-    //
-    // IDLE ->      (mDisplacement > mTouchSlop) -> DRAGGING
-    // DRAGGING -> (MotionEvent#ACTION_UP, MotionEvent#ACTION_CANCEL) -> SETTLING
-    // SETTLING -> (MotionEvent#ACTION_DOWN) -> DRAGGING
-    // SETTLING -> (View settled) -> IDLE
+    private final PointF mDownPos = new PointF();
+    private final PointF mLastPos = new PointF();
+    private final Direction mDir;
+    private final boolean mIsRtl;
+    private final float mTouchSlop;
+    private final float mMaxVelocity;
+    /* Client of this gesture detector can register a callback. */
+    private final Listener mListener;
 
-    private void setState(ScrollState newState) {
-        if (DBG) {
-            Log.d(TAG, "setState:" + mState + "->" + newState);
-        }
-        // onDragStart and onDragEnd is reported ONLY on state transition
-        if (newState == ScrollState.DRAGGING) {
-            initializeDragging();
-            if (mState == ScrollState.IDLE) {
-                reportDragStart(false /* recatch */);
-            } else if (mState == ScrollState.SETTLING) {
-                reportDragStart(true /* recatch */);
-            }
-        }
-        if (newState == ScrollState.SETTLING) {
-            reportDragEnd();
-        }
+    private int mActivePointerId = INVALID_POINTER_ID;
+    private VelocityTracker mVelocityTracker;
+    private float mLastDisplacement;
+    private float mDisplacement;
+    private float mSubtractDisplacement;
+    private boolean mIgnoreSlopWhenSettling;
+    private int mScrollDirections;
+    private ScrollState mState = ScrollState.IDLE;
 
-        mState = newState;
+    private enum ScrollState {
+        IDLE,
+        DRAGGING,      // onDragStart, onDrag
+        SETTLING       // onDragEnd
     }
 
-    public boolean isDraggingOrSettling() {
-        return mState == ScrollState.DRAGGING || mState == ScrollState.SETTLING;
+    public SwipeDetector(@NonNull Context context, @NonNull Listener l, @NonNull Direction dir) {
+        this(ViewConfiguration.get(context), l, dir, Utilities.isRtl(context.getResources()));
+    }
+
+    @VisibleForTesting
+    protected SwipeDetector(@NonNull ViewConfiguration config, @NonNull Listener l,
+            @NonNull Direction dir, boolean isRtl) {
+        mListener = l;
+        mDir = dir;
+        mIsRtl = isRtl;
+        mTouchSlop = config.getScaledTouchSlop();
+        mMaxVelocity = config.getScaledMaximumFlingVelocity();
+    }
+
+    public static long calculateDuration(float velocity, float progressNeeded) {
+        // TODO: make these values constants after tuning.
+        float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity));
+        float travelDistance = Math.max(0.2f, progressNeeded);
+        long duration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance);
+        if (DBG) {
+            Log.d(TAG, String.format(
+                    "calculateDuration=%d, v=%f, d=%f", duration, velocity, progressNeeded));
+        }
+        return duration;
     }
 
     public int getDownX() {
@@ -203,73 +188,31 @@
         return mState == ScrollState.DRAGGING;
     }
 
-    private final PointF mDownPos = new PointF();
-    private final PointF mLastPos = new PointF();
-    private final Direction mDir;
-    private final boolean mIsRtl;
-
-    private final float mTouchSlop;
-    private final float mMaxVelocity;
-
-    /* Client of this gesture detector can register a callback. */
-    private final Listener mListener;
-
-    private VelocityTracker mVelocityTracker;
-
-    private float mLastDisplacement;
-    private float mDisplacement;
-
-    private float mSubtractDisplacement;
-    private boolean mIgnoreSlopWhenSettling;
-
-    public interface Listener {
-        void onDragStart(boolean start);
-
-        boolean onDrag(float displacement);
-
-        default boolean onDrag(float displacement, MotionEvent event) {
-            return onDrag(displacement);
-        }
-
-        void onDragEnd(float velocity, boolean fling);
-    }
-
-    public SwipeDetector(@NonNull Context context, @NonNull Listener l, @NonNull Direction dir) {
-        this(ViewConfiguration.get(context), l, dir, Utilities.isRtl(context.getResources()));
-    }
-
-    @VisibleForTesting
-    protected SwipeDetector(@NonNull ViewConfiguration config, @NonNull Listener l,
-            @NonNull Direction dir, boolean isRtl) {
-        mListener = l;
-        mDir = dir;
-        mIsRtl = isRtl;
-        mTouchSlop = config.getScaledTouchSlop();
-        mMaxVelocity = config.getScaledMaximumFlingVelocity();
+    public boolean isDraggingOrSettling() {
+        return mState == ScrollState.DRAGGING || mState == ScrollState.SETTLING;
     }
 
     public void setDetectableScrollConditions(int scrollDirectionFlags, boolean ignoreSlop) {
-        mScrollConditions = scrollDirectionFlags;
+        mScrollDirections = scrollDirectionFlags;
         mIgnoreSlopWhenSettling = ignoreSlop;
     }
 
     public int getScrollDirections() {
-        return mScrollConditions;
+        return mScrollDirections;
     }
 
-    private boolean shouldScrollStart(MotionEvent ev, int pointerIndex) {
-        // reject cases where the angle or slop condition is not met.
-        if (Math.max(mDir.getActiveTouchSlop(ev, pointerIndex, mDownPos), mTouchSlop)
-                > Math.abs(mDisplacement)) {
-            return false;
-        }
+    public void finishedScrolling() {
+        setState(ScrollState.IDLE);
+    }
 
-        // Check if the client is interested in scroll in current direction.
-        if (((mScrollConditions & DIRECTION_NEGATIVE) > 0 && mDir.isNegative(mDisplacement)) ||
-                ((mScrollConditions & DIRECTION_POSITIVE) > 0 && mDir.isPositive(mDisplacement))) {
-            return true;
-        }
-        return false;
+    /**
+     * Returns if the start drag was towards the positive direction or negative.
+     *
+     * @see #setDetectableScrollConditions(int, boolean)
+     * @see #DIRECTION_BOTH
+     */
+    public boolean wasInitialTouchPositive() {
+        return mDir.isPositive(mSubtractDisplacement);
     }
 
     public boolean onTouchEvent(MotionEvent ev) {
@@ -338,16 +281,50 @@
         return true;
     }
 
-    public void finishedScrolling() {
-        setState(ScrollState.IDLE);
+    //------------------- ScrollState transition diagram -----------------------------------
+    //
+    // IDLE -> (mDisplacement > mTouchSlop) -> DRAGGING
+    // DRAGGING -> (MotionEvent#ACTION_UP, MotionEvent#ACTION_CANCEL) -> SETTLING
+    // SETTLING -> (MotionEvent#ACTION_DOWN) -> DRAGGING
+    // SETTLING -> (View settled) -> IDLE
+
+    private void setState(ScrollState newState) {
+        if (DBG) {
+            Log.d(TAG, "setState:" + mState + "->" + newState);
+        }
+        // onDragStart and onDragEnd is reported ONLY on state transition
+        if (newState == ScrollState.DRAGGING) {
+            initializeDragging();
+            if (mState == ScrollState.IDLE) {
+                reportDragStart(false /* recatch */);
+            } else if (mState == ScrollState.SETTLING) {
+                reportDragStart(true /* recatch */);
+            }
+        }
+        if (newState == ScrollState.SETTLING) {
+            reportDragEnd();
+        }
+
+        mState = newState;
     }
 
-    private boolean reportDragStart(boolean recatch) {
+    private boolean shouldScrollStart(MotionEvent ev, int pointerIndex) {
+        // reject cases where the angle or slop condition is not met.
+        if (Math.max(mDir.getActiveTouchSlop(ev, pointerIndex, mDownPos), mTouchSlop)
+                > Math.abs(mDisplacement)) {
+            return false;
+        }
+
+        // Check if the client is interested in scroll in current direction.
+        return ((mScrollDirections & DIRECTION_NEGATIVE) > 0 && mDir.isNegative(mDisplacement))
+                || ((mScrollDirections & DIRECTION_POSITIVE) > 0 && mDir.isPositive(mDisplacement));
+    }
+
+    private void reportDragStart(boolean recatch) {
         mListener.onDragStart(!recatch);
         if (DBG) {
             Log.d(TAG, "onDragStart recatch:" + recatch);
         }
-        return true;
     }
 
     private void initializeDragging() {
@@ -361,26 +338,15 @@
         }
     }
 
-    /**
-     * Returns if the start drag was towards the positive direction or negative.
-     *
-     * @see #setDetectableScrollConditions(int, boolean)
-     * @see #DIRECTION_BOTH
-     */
-    public boolean wasInitialTouchPositive() {
-        return mDir.isPositive(mSubtractDisplacement);
-    }
-
-    private boolean reportDragging(MotionEvent event) {
+    private void reportDragging(MotionEvent event) {
         if (mDisplacement != mLastDisplacement) {
             if (DBG) {
                 Log.d(TAG, String.format("onDrag disp=%.1f", mDisplacement));
             }
 
             mLastDisplacement = mDisplacement;
-            return mListener.onDrag(mDisplacement - mSubtractDisplacement, event);
+            mListener.onDrag(mDisplacement - mSubtractDisplacement, event);
         }
-        return true;
     }
 
     private void reportDragEnd() {
@@ -394,14 +360,33 @@
         mListener.onDragEnd(velocity, Math.abs(velocity) > RELEASE_VELOCITY_PX_MS);
     }
 
-    public static long calculateDuration(float velocity, float progressNeeded) {
-        // TODO: make these values constants after tuning.
-        float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity));
-        float travelDistance = Math.max(0.2f, progressNeeded);
-        long duration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance);
-        if (DBG) {
-            Log.d(TAG, String.format("calculateDuration=%d, v=%f, d=%f", duration, velocity, progressNeeded));
+    /** Listener to receive updates on the swipe. */
+    public interface Listener {
+        void onDragStart(boolean start);
+
+        boolean onDrag(float displacement);
+
+        default boolean onDrag(float displacement, MotionEvent event) {
+            return onDrag(displacement);
         }
-        return duration;
+
+        void onDragEnd(float velocity, boolean fling);
+    }
+
+    public abstract static class Direction {
+
+        abstract float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint,
+                boolean isRtl);
+
+        /**
+         * Distance in pixels a touch can wander before we think the user is scrolling.
+         */
+        abstract float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos);
+
+        abstract float getVelocity(VelocityTracker tracker, boolean isRtl);
+
+        abstract boolean isPositive(float displacement);
+
+        abstract boolean isNegative(float displacement);
     }
 }
diff --git a/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java
index e042357..f209fae 100644
--- a/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java
+++ b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java
@@ -25,6 +25,10 @@
 import android.util.Log;
 import android.view.ViewConfiguration;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.launcher3.testcomponent.TouchEventGenerator;
 
 import org.junit.Before;
@@ -33,10 +37,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class SwipeDetectorTest {