Merge "Make Auto-scrolling base purely on edge offset, no longer on time." into nyc-andromeda-dev
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f8e7932..ce6f247 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -47,8 +47,6 @@
     <dimen name="drag_shadow_width">160dp</dimen>
     <dimen name="drag_shadow_height">48dp</dimen>
 
-    <dimen name="autoscroll_edge_height">32dp</dimen>
-
     <dimen name="doc_header_sort_icon_size">16dp</dimen>
     <dimen name="doc_header_height">60dp</dimen>
 
diff --git a/src/com/android/documentsui/dirlist/BandController.java b/src/com/android/documentsui/dirlist/BandController.java
index 91afa23..c938d93 100644
--- a/src/com/android/documentsui/dirlist/BandController.java
+++ b/src/com/android/documentsui/dirlist/BandController.java
@@ -56,7 +56,6 @@
 public class BandController extends OnScrollListener {
 
     private static final String TAG = "BandController";
-    private static final int AUTOSCROLL_EDGE_HEIGHT = 1;
 
     private final Runnable mModelBuilder;
     private final SelectionEnvironment mEnvironment;
@@ -92,7 +91,6 @@
 
         mEnvironment.addOnScrollListener(this);
         mViewScroller = new ViewAutoScroller(
-                AUTOSCROLL_EDGE_HEIGHT,
                 new ScrollDistanceDelegate() {
                     @Override
                     public Point getCurrentPosition() {
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 497cfa3..32ea333 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -215,9 +215,7 @@
         mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity()));
         mFileList = view.findViewById(R.id.file_list);
 
-        final int edgeHeight = (int) getResources().getDimension(R.dimen.autoscroll_edge_height);
-        mDragHoverListener = DragHoverListener.create(
-                edgeHeight, new DirectoryDragListener(this), mRecView);
+        mDragHoverListener = DragHoverListener.create(new DirectoryDragListener(this), mRecView);
 
         // Make the recycler and the empty views responsive to drop events.
         mRecView.setOnDragListener(mDragHoverListener);
@@ -300,9 +298,7 @@
         mModel.addUpdateListener(mAdapter.getModelUpdateListener());
         mModel.addUpdateListener(mModelUpdateListener);
 
-        final int edgeHeight = (int) getResources().getDimension(R.dimen.autoscroll_edge_height);
-        GestureSelector gestureSel = GestureSelector.create(
-                edgeHeight, mSelectionMgr, mRecView);
+        GestureSelector gestureSel = GestureSelector.create(mSelectionMgr, mRecView);
 
         final BaseActivity activity = getBaseActivity();
         mTuner = activity.getFragmentTuner(mModel, mConfig.mSearchMode);
diff --git a/src/com/android/documentsui/dirlist/DragHoverListener.java b/src/com/android/documentsui/dirlist/DragHoverListener.java
index 0382c21..ae13d97 100644
--- a/src/com/android/documentsui/dirlist/DragHoverListener.java
+++ b/src/com/android/documentsui/dirlist/DragHoverListener.java
@@ -43,7 +43,6 @@
     private final IntSupplier mHeight;
     private final BooleanSupplier mCanScrollUp;
     private final BooleanSupplier mCanScrollDown;
-    private final int mAutoScrollEdgeHeight;
     private final Runnable mDragScroller;
 
     /**
@@ -61,7 +60,6 @@
 
     @VisibleForTesting
     DragHoverListener(
-            int autoScrollEdgeHeight,
             ItemDragListener<? extends DragHost> dragHandler,
             IntSupplier heightSupplier,
             Predicate<View> isScrollView,
@@ -69,7 +67,6 @@
             BooleanSupplier scrollDownSupplier,
             ViewAutoScroller.ScrollActionDelegate actionDelegate) {
         mDragHandler = dragHandler;
-        mAutoScrollEdgeHeight = autoScrollEdgeHeight;
         mHeight = heightSupplier;
         mIsScrollView = isScrollView;
         mCanScrollUp = scrollUpSupplier;
@@ -92,12 +89,10 @@
             }
         };
 
-        mDragScroller = new ViewAutoScroller(
-                mAutoScrollEdgeHeight, distanceDelegate, actionDelegate);
+        mDragScroller = new ViewAutoScroller(distanceDelegate, actionDelegate);
     }
 
     static DragHoverListener create(
-            int autoScrollEdgeHeight,
             ItemDragListener<? extends DragHost> dragHandler,
             View scrollView) {
         ScrollActionDelegate actionDelegate = new ScrollActionDelegate() {
@@ -118,7 +113,6 @@
             }
         };
         DragHoverListener listener = new DragHoverListener(
-                autoScrollEdgeHeight,
                 dragHandler,
                 scrollView::getHeight,
                 (view) -> (scrollView == view),
@@ -179,9 +173,11 @@
             return false;
         }
 
-        boolean shouldScrollUp = mCurrentPosition.y < mAutoScrollEdgeHeight
+        float topBottomRegionHeight = mHeight.getAsInt()
+                * ViewAutoScroller.TOP_BOTTOM_THRESHOLD_RATIO;
+        boolean shouldScrollUp = mCurrentPosition.y < topBottomRegionHeight
                 && mCanScrollUp.getAsBoolean();
-        boolean shouldScrollDown = mCurrentPosition.y > mHeight.getAsInt() - mAutoScrollEdgeHeight
+        boolean shouldScrollDown = mCurrentPosition.y > mHeight.getAsInt() - topBottomRegionHeight
                 && mCanScrollDown.getAsBoolean();
         return shouldScrollUp || shouldScrollDown;
     }
diff --git a/src/com/android/documentsui/dirlist/GestureSelector.java b/src/com/android/documentsui/dirlist/GestureSelector.java
index c8799fb..d0b68ae 100644
--- a/src/com/android/documentsui/dirlist/GestureSelector.java
+++ b/src/com/android/documentsui/dirlist/GestureSelector.java
@@ -37,7 +37,6 @@
 
     private final MultiSelectManager mSelectionMgr;
     private final Runnable mDragScroller;
-    private final int mAutoScrollEdgeHeight;
     private final IntSupplier mHeight;
     private final ViewFinder mViewFinder;
     private int mLastStartedItemPos = -1;
@@ -45,12 +44,10 @@
     private Point mLastInterceptedPoint;
 
     GestureSelector(
-            int autoScrollEdgeHeight,
             MultiSelectManager selectionMgr,
             IntSupplier heightSupplier,
             ViewFinder viewFinder,
             ScrollActionDelegate actionDelegate) {
-        mAutoScrollEdgeHeight = autoScrollEdgeHeight;
         mSelectionMgr = selectionMgr;
         mHeight = heightSupplier;
         mViewFinder = viewFinder;
@@ -72,12 +69,10 @@
             }
         };
 
-        mDragScroller = new ViewAutoScroller(
-                mAutoScrollEdgeHeight, distanceDelegate, actionDelegate);
+        mDragScroller = new ViewAutoScroller(distanceDelegate, actionDelegate);
     }
 
     static GestureSelector create(
-            int autoScrollEdgeHeight,
             MultiSelectManager selectionMgr,
             RecyclerView scrollView) {
         ScrollActionDelegate actionDelegate = new ScrollActionDelegate() {
@@ -98,8 +93,10 @@
         };
         GestureSelector helper =
                 new GestureSelector(
-                        autoScrollEdgeHeight, selectionMgr, scrollView::getHeight,
-                        scrollView::findChildViewUnder, actionDelegate);
+                        selectionMgr,
+                        scrollView::getHeight,
+                        scrollView::findChildViewUnder,
+                        actionDelegate);
 
         return helper;
     }
@@ -205,9 +202,7 @@
         if (lastGlidedItemPos != RecyclerView.NO_POSITION) {
             doGestureMultiSelect(lastGlidedItemPos);
         }
-        if (insideDragZone(rv)) {
-            mDragScroller.run();
-        }
+        scrollIfNecessary();
     }
 
     // It's possible for events to go over the top/bottom of the RecyclerView.
@@ -243,16 +238,8 @@
         mSelectionMgr.snapProvisionalRangeSelection(endPos);
     }
 
-    private boolean insideDragZone(View scrollView) {
-        if (mLastInterceptedPoint == null) {
-            return false;
-        }
-
-        boolean shouldScrollUp = mLastInterceptedPoint.y < mAutoScrollEdgeHeight
-                && scrollView.canScrollVertically(-1);
-        boolean shouldScrollDown = mLastInterceptedPoint.y > scrollView.getHeight() -
-                mAutoScrollEdgeHeight && scrollView.canScrollVertically(1);
-        return shouldScrollUp || shouldScrollDown;
+    private void scrollIfNecessary() {
+        mDragScroller.run();
     }
 
     @FunctionalInterface
diff --git a/src/com/android/documentsui/dirlist/ViewAutoScroller.java b/src/com/android/documentsui/dirlist/ViewAutoScroller.java
index 761529c..b6e5f00 100644
--- a/src/com/android/documentsui/dirlist/ViewAutoScroller.java
+++ b/src/com/android/documentsui/dirlist/ViewAutoScroller.java
@@ -18,51 +18,28 @@
 package com.android.documentsui.dirlist;
 
 import android.graphics.Point;
-import android.support.annotation.VisibleForTesting;
-
-import java.util.function.LongSupplier;
 
 /**
  * Provides auto-scrolling upon request when user's interaction with the application
- * introduces a natural intent to scroll. Used by {@link BandController} and
- * {@link DragHoverListener} to allow auto scrolling when user either does band selection, or
- * attempting to drag and drop files to somewhere off the current screen.
+ * introduces a natural intent to scroll. Used by {@link BandController}, {@link GestureSelector}
+ * and {@link DragHoverListener} to allow auto scrolling when user either does band selection,
+ * attempting to drag and drop files to somewhere off the current screen, or trying to motion select
+ * past top/bottom of the screen.
  */
 public final class ViewAutoScroller implements Runnable {
     public static final int NOT_SET = -1;
-    /**
-     * The number of milliseconds of scrolling at which scroll speed continues to increase.
-     * At first, the scroll starts slowly; then, the rate of scrolling increases until it
-     * reaches its maximum value at after this many milliseconds.
-     */
-    private static final long SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
+    // ratio used to calculate the top/bottom hotspot region; used with view height
+    public static final float TOP_BOTTOM_THRESHOLD_RATIO = 0.125f;
+    public static final int MAX_SCROLL_STEP = 70;
 
     // Top and bottom inner buffer such that user's cursor does not have to be exactly off screen
     // for auto scrolling to begin
-    private final int mTopBottomThreshold;
     private final ScrollDistanceDelegate mCalcDelegate;
     private final ScrollActionDelegate mUiDelegate;
-    private final LongSupplier mCurrentTime;
 
-    private long mScrollStartTime = NOT_SET;
-
-    public ViewAutoScroller(
-            int topBottomThreshold,
-            ScrollDistanceDelegate calcDelegate,
-            ScrollActionDelegate uiDelegate) {
-        this(topBottomThreshold, calcDelegate, uiDelegate, System::currentTimeMillis);
-    }
-
-    @VisibleForTesting
-    ViewAutoScroller(
-            int topBottomThreshold,
-            ScrollDistanceDelegate calcDelegate,
-            ScrollActionDelegate uiDelegate,
-            LongSupplier clock) {
-        mTopBottomThreshold = topBottomThreshold;
+    public ViewAutoScroller(ScrollDistanceDelegate calcDelegate, ScrollActionDelegate uiDelegate) {
         mCalcDelegate = calcDelegate;
         mUiDelegate = uiDelegate;
-        mCurrentTime = clock;
     }
 
     /**
@@ -79,30 +56,29 @@
         // pointer are in these buffer pixels.
         int pixelsPastView = 0;
 
-        if (mCalcDelegate.getCurrentPosition().y <= mTopBottomThreshold) {
-            pixelsPastView = mCalcDelegate.getCurrentPosition().y - mTopBottomThreshold;
+        final int topBottomThreshold = (int) (mCalcDelegate.getViewHeight()
+                * TOP_BOTTOM_THRESHOLD_RATIO);
+
+        if (mCalcDelegate.getCurrentPosition().y <= topBottomThreshold) {
+            pixelsPastView = mCalcDelegate.getCurrentPosition().y - topBottomThreshold;
         } else if (mCalcDelegate.getCurrentPosition().y >= mCalcDelegate.getViewHeight()
-                - mTopBottomThreshold) {
+                - topBottomThreshold) {
             pixelsPastView = mCalcDelegate.getCurrentPosition().y - mCalcDelegate.getViewHeight()
-                    + mTopBottomThreshold;
+                    + topBottomThreshold;
         }
 
         if (!mCalcDelegate.isActive() || pixelsPastView == 0) {
             // If the operation that started the scrolling is no longer inactive, or if it is active
             // but not at the edge of the view, no scrolling is necessary.
-            mScrollStartTime = NOT_SET;
             return;
         }
 
-        if (mScrollStartTime == NOT_SET) {
-            // If the pointer was previously not at the edge of the view but now is, set the
-            // start time for the scroll.
-            mScrollStartTime = mCurrentTime.getAsLong();
+        if (pixelsPastView > topBottomThreshold) {
+            pixelsPastView = topBottomThreshold;
         }
 
         // Compute the number of pixels to scroll, and scroll that many pixels.
-        final int numPixels = computeScrollDistance(
-                pixelsPastView, mCurrentTime.getAsLong() - mScrollStartTime);
+        final int numPixels = computeScrollDistance(pixelsPastView);
         mUiDelegate.scrollBy(numPixels);
 
         // Remove callback to this, and then properly run at next frame again
@@ -112,63 +88,43 @@
 
     /**
      * Computes the number of pixels to scroll based on how far the pointer is past the end
-     * of the view and how long it has been there. Roughly based on ItemTouchHelper's
-     * algorithm for computing the number of pixels to scroll when an item is dragged to the
-     * end of a view.
-     * @param pixelsPastView
-     * @param scrollDuration
+     * of the region. Roughly based on ItemTouchHelper's algorithm for computing the number of
+     * pixels to scroll when an item is dragged to the end of a view.
      * @return
      */
-    public int computeScrollDistance(int pixelsPastView, long scrollDuration) {
-        final int maxScrollStep = mCalcDelegate.getViewHeight();
+    public int computeScrollDistance(int pixelsPastView) {
+        final int topBottomThreshold = (int) (mCalcDelegate.getViewHeight()
+                * TOP_BOTTOM_THRESHOLD_RATIO);
+
         final int direction = (int) Math.signum(pixelsPastView);
         final int absPastView = Math.abs(pixelsPastView);
 
         // Calculate the ratio of how far out of the view the pointer currently resides to
-        // the entire height of the view.
+        // the top/bottom scrolling hotspot of the view.
         final float outOfBoundsRatio = Math.min(
-                1.0f, (float) absPastView / mCalcDelegate.getViewHeight());
+                1.0f, (float) absPastView / topBottomThreshold);
         // Interpolate this ratio and use it to compute the maximum scroll that should be
         // possible for this step.
-        final float cappedScrollStep =
-                direction * maxScrollStep * smoothOutOfBoundsRatio(outOfBoundsRatio);
-
-        // Likewise, calculate the ratio of the time spent in the scroll to the limit.
-        final float timeRatio = Math.min(
-                1.0f, (float) scrollDuration / SCROLL_ACCELERATION_LIMIT_TIME_MS);
-        // Interpolate this ratio and use it to compute the final number of pixels to
-        // scroll.
-        final int numPixels = (int) (cappedScrollStep * smoothTimeRatio(timeRatio));
+        final int cappedScrollStep =
+                (int) (direction * MAX_SCROLL_STEP * smoothOutOfBoundsRatio(outOfBoundsRatio));
 
         // If the final number of pixels to scroll ends up being 0, the view should still
         // scroll at least one pixel.
-        return numPixels != 0 ? numPixels : direction;
+        return cappedScrollStep != 0 ? cappedScrollStep : direction;
     }
 
     /**
      * Interpolates the given out of bounds ratio on a curve which starts at (0,0) and ends
      * at (1,1) and quickly approaches 1 near the start of that interval. This ensures that
-     * drags that are at the edge or barely past the edge of the view still cause sufficient
-     * scrolling. The equation y=(x-1)^5+1 is used, but this could also be tweaked if
+     * drags that are at the edge or barely past the edge of the threshold does little to no
+     * scrolling, while drags that are near the edge of the view does a lot of
+     * scrolling. The equation y=x^10 is used, but this could also be tweaked if
      * needed.
      * @param ratio A ratio which is in the range [0, 1].
      * @return A "smoothed" value, also in the range [0, 1].
      */
     private float smoothOutOfBoundsRatio(float ratio) {
-        return (float) Math.pow(ratio - 1.0f, 5) + 1.0f;
-    }
-
-    /**
-     * Interpolates the given time ratio on a curve which starts at (0,0) and ends at (1,1)
-     * and stays close to 0 for most input values except those very close to 1. This ensures
-     * that scrolls start out very slowly but speed up drastically after the scroll has been
-     * in progress close to SCROLL_ACCELERATION_LIMIT_TIME_MS. The equation y=x^5 is used,
-     * but this could also be tweaked if needed.
-     * @param ratio A ratio which is in the range [0, 1].
-     * @return A "smoothed" value, also in the range [0, 1].
-     */
-    private float smoothTimeRatio(float ratio) {
-        return (float) Math.pow(ratio, 5);
+        return (float) Math.pow(ratio, 10);
     }
 
     /**
diff --git a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java b/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
index 824d246..46d9c67 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
@@ -40,7 +40,8 @@
 public class DragScrollListenerTest {
 
     private static final int VIEW_HEIGHT = 100;
-    private static final int EDGE_HEIGHT = 10;
+    private static final int TOP_Y_POINT = 0;
+    private static final int BOTTOM_Y_POINT = VIEW_HEIGHT;
 
     private View mTestView;
     private TestDragHost mTestDragHost;
@@ -58,7 +59,6 @@
         mTestDragHost = new TestDragHost();
         mDragHandler = new TestDragHandler(mTestDragHost, mTestTimer);
         mListener = new DragHoverListener(
-                EDGE_HEIGHT,
                 mDragHandler,
                 () -> VIEW_HEIGHT,
                 view -> (view == mTestView),
@@ -89,19 +89,19 @@
         triggerDragEvent(DragEvent.ACTION_DRAG_STARTED);
 
         // Not in hotspot
-        triggerDragLocationEvent(0, 50);
+        triggerDragLocationEvent(0, VIEW_HEIGHT / 2);
         assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION);
 
         // Can't scroll up
         mCanScrollUp = false;
         mCanScrollDown = true;
-        triggerDragLocationEvent(0, 5);
+        triggerDragLocationEvent(0, TOP_Y_POINT);
         assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION);
 
         // Can't scroll Down
         mCanScrollDown = false;
         mCanScrollUp = true;
-        triggerDragLocationEvent(0, 95);
+        triggerDragLocationEvent(0, BOTTOM_Y_POINT);
         assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION);
 
         triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
@@ -120,14 +120,14 @@
         // Can't scroll up
         mCanScrollUp = false;
         mCanScrollDown = true;
-        triggerDragLocationEvent(0, 5);
+        triggerDragLocationEvent(0, TOP_Y_POINT);
         triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
         assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_ENTERED);
 
         // Can't scroll Down
         mCanScrollDown = false;
         mCanScrollUp = true;
-        triggerDragLocationEvent(0, 95);
+        triggerDragLocationEvent(0, BOTTOM_Y_POINT);
         triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
         assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_ENTERED);
 
@@ -137,11 +137,11 @@
     // Make sure given correct location/enter events, DragScrollListener handle them itself
     @Test
     public void testDragScrollEvent_Handled() {
-        triggerDragLocationEvent(0, 5);
+        triggerDragLocationEvent(0, TOP_Y_POINT);
         triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
         assertTrue(mDragHandler.mLastDropEvent == null);
 
-        triggerDragLocationEvent(0, 95);
+        triggerDragLocationEvent(0, BOTTOM_Y_POINT);
         triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
         assertTrue(mDragHandler.mLastDropEvent == null);
     }
@@ -153,12 +153,12 @@
     public void testActualDragScrolldEvents() {
         triggerDragEvent(DragEvent.ACTION_DRAG_STARTED);
 
-        triggerDragLocationEvent(0, 5);
+        triggerDragLocationEvent(0, TOP_Y_POINT);
         triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
         assertTrue(mDragHandler.mLastDropEvent.getAction() == DragEvent.ACTION_DRAG_STARTED);
         mActionDelegate.assertScrollNegative();
 
-        triggerDragLocationEvent(0, 95);
+        triggerDragLocationEvent(0, BOTTOM_Y_POINT);
         triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
 
         triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
@@ -230,11 +230,11 @@
         }
 
         public void assertScrollPositive() {
-            assertTrue(mDy > 0);
+            assertTrue("actual: " + mDy, mDy > 0);
         }
 
         public void assertScrollNegative() {
-            assertTrue(mDy < 0);
+            assertTrue("actual: " + mDy, mDy < 0);
         }
     };
 }
diff --git a/tests/unit/com/android/documentsui/dirlist/ViewAutoScrollerTest.java b/tests/unit/com/android/documentsui/dirlist/ViewAutoScrollerTest.java
index e2aaa84..f7a148a 100644
--- a/tests/unit/com/android/documentsui/dirlist/ViewAutoScrollerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/ViewAutoScrollerTest.java
@@ -34,7 +34,12 @@
 public final class ViewAutoScrollerTest {
 
     private static final int VIEW_HEIGHT = 100;
-    private static final int EDGE_HEIGHT = 10;
+    private static final int TOP_Y_POINT = (int) (VIEW_HEIGHT
+            * ViewAutoScroller.TOP_BOTTOM_THRESHOLD_RATIO) - 1;
+    private static final int BOTTOM_Y_POINT = VIEW_HEIGHT
+            - (int) (VIEW_HEIGHT * ViewAutoScroller.TOP_BOTTOM_THRESHOLD_RATIO)
+            + 1;
+    private static final int EDGE_HEIGHT = 5;
 
     private ViewAutoScroller mAutoScroller;
     private Point mPoint;
@@ -77,8 +82,7 @@
             public void removeCallback(Runnable r) {
             }
         };
-        mAutoScroller = new ViewAutoScroller(
-                EDGE_HEIGHT, mDistanceDelegate, mActionDelegate, new TestClock()::getCurrentTime);
+        mAutoScroller = new ViewAutoScroller(mDistanceDelegate, mActionDelegate);
     }
 
     @Test
@@ -95,7 +99,7 @@
     @Test
     public void testCursorInScrollZone_notActive() {
         mActive = false;
-        mPoint = new Point(0, EDGE_HEIGHT - 1);
+        mPoint = new Point(0, TOP_Y_POINT);
         mScrollAssert = (int dy) -> {
             // Should not have called this method
             fail("Received unexpected scroll event");
@@ -107,8 +111,8 @@
     @Test
     public void testCursorInScrollZone_top() {
         mActive = true;
-        mPoint = new Point(0, EDGE_HEIGHT - 1);
-        int expectedScrollDistance = mAutoScroller.computeScrollDistance(-1, 1);
+        mPoint = new Point(0, TOP_Y_POINT);
+        int expectedScrollDistance = mAutoScroller.computeScrollDistance(-1);
         mScrollAssert = (int dy) -> {
             assertTrue(dy == expectedScrollDistance);
         };
@@ -118,19 +122,11 @@
     @Test
     public void testCursorInScrollZone_bottom() {
         mActive = true;
-        mPoint = new Point(0, VIEW_HEIGHT - EDGE_HEIGHT + 1);
-        int expectedScrollDistance = mAutoScroller.computeScrollDistance(1, 1);
+        mPoint = new Point(0, BOTTOM_Y_POINT);
+        int expectedScrollDistance = mAutoScroller.computeScrollDistance(1);
         mScrollAssert = (int dy) -> {
             assertTrue(dy == expectedScrollDistance);
         };
         mAutoScroller.run();
     }
-
-    class TestClock {
-        private int timesCalled = 0;
-
-        public long getCurrentTime() {
-            return ++timesCalled;
-        }
-    }
 }