summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Wickham <awickham@google.com>2019-10-01 13:52:22 -0700
committerAndy Wickham <awickham@google.com>2019-10-01 14:38:56 -0700
commit769c795edfe77fe2a3f6472a5b60fd1a73618a13 (patch)
tree6b01c2bd66848758cc5a00e627f7e0e68f277215
parent4c420047cf268f20daf245be53f16f54b518f246 (diff)
downloadandroid_packages_apps_Trebuchet-769c795edfe77fe2a3f6472a5b60fd1a73618a13.tar.gz
android_packages_apps_Trebuchet-769c795edfe77fe2a3f6472a5b60fd1a73618a13.tar.bz2
android_packages_apps_Trebuchet-769c795edfe77fe2a3f6472a5b60fd1a73618a13.zip
Some cleanup for SwipeDetector.
It is now organized as follows: - private constants - public constants - private final fields - private variable fields - constructors - public methods - private methods - public interface/abstract class This is intended to be a functional no-op. Bug: 141939911 Change-Id: Iad5a9b3b73b35641f8a4f1d52ada6adef3825c47 Tested: Built and sanity checked manually.
-rw-r--r--src/com/android/launcher3/notification/NotificationItemView.java4
-rw-r--r--src/com/android/launcher3/touch/SwipeDetector.java275
-rw-r--r--tests/src/com/android/launcher3/touch/SwipeDetectorTest.java8
3 files changed, 136 insertions, 151 deletions
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index 32410a64b..717a7e93d 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 com.android.launcher3.util.Themes;
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 3777a41ad..d0edfd87d 100644
--- a/src/com/android/launcher3/touch/SwipeDetector.java
+++ b/src/com/android/launcher3/touch/SwipeDetector.java
@@ -24,12 +24,11 @@ import android.view.MotionEvent;
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 @@ public class SwipeDetector {
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,88 +116,28 @@ public class SwipeDetector {
}
};
- //------------------- 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;
- }
-
- public boolean isDraggingOrSettling() {
- return mState == ScrollState.DRAGGING || mState == ScrollState.SETTLING;
- }
-
- public int getDownX() {
- return (int) mDownPos.x;
- }
-
- public int getDownY() {
- return (int) mDownPos.y;
- }
- /**
- * There's no touch and there's no animation.
- */
- public boolean isIdleState() {
- return mState == ScrollState.IDLE;
- }
-
- public boolean isSettlingState() {
- return mState == ScrollState.SETTLING;
- }
-
- public boolean isDraggingState() {
- 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 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;
- 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);
+ private enum ScrollState {
+ IDLE,
+ DRAGGING, // onDragStart, onDrag
+ SETTLING // onDragEnd
}
public SwipeDetector(@NonNull Context context, @NonNull Listener l, @NonNull Direction dir) {
@@ -248,28 +154,65 @@ public class SwipeDetector {
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() {
+ return (int) mDownPos.x;
+ }
+
+ public int getDownY() {
+ return (int) mDownPos.y;
+ }
+ /**
+ * There's no touch and there's no animation.
+ */
+ public boolean isIdleState() {
+ return mState == ScrollState.IDLE;
+ }
+
+ public boolean isSettlingState() {
+ return mState == ScrollState.SETTLING;
+ }
+
+ public boolean isDraggingState() {
+ return mState == ScrollState.DRAGGING;
+ }
+
+ 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 @@ public class SwipeDetector {
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 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 boolean reportDragStart(boolean recatch) {
+ 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 @@ public class SwipeDetector {
}
}
- /**
- * 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 @@ public class SwipeDetector {
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 e04235708..f209fae97 100644
--- a/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java
+++ b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java
@@ -25,6 +25,10 @@ import static org.mockito.Mockito.verify;
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.junit.runner.RunWith;
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 {