summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurice Lam <yukl@google.com>2018-01-29 16:12:44 -0800
committerMaurice Lam <yukl@google.com>2018-01-29 18:51:36 -0800
commitf2c8c89ad6048dd304f36928f1cddacbe7dbd920 (patch)
treed186c470d57c0547bf205df3167e3df43f154d0a
parent78bc2e0c900935ed00e111a0c4b93b50d883e2b9 (diff)
downloadsetupwizard-f2c8c89ad6048dd304f36928f1cddacbe7dbd920.tar.gz
Add timeout to consecutive tap gesture
Test: ./gradlew test Bug: 72202690 Change-Id: Ia227cc38cfb54e4f33d34adfffdc6c38543060d5
-rw-r--r--library/main/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetector.java6
-rw-r--r--library/test/robotest/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetectorTest.java118
2 files changed, 123 insertions, 1 deletions
diff --git a/library/main/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetector.java b/library/main/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetector.java
index 8325232..f438691 100644
--- a/library/main/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetector.java
+++ b/library/main/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetector.java
@@ -39,6 +39,7 @@ public final class ConsecutiveTapsGestureDetector {
private final View mView;
private final OnConsecutiveTapsListener mListener;
private final int mConsecutiveTapTouchSlopSquare;
+ private final int mConsecutiveTapTimeout;
private int mConsecutiveTapsCounter = 0;
private MotionEvent mPreviousTapEvent;
@@ -54,6 +55,7 @@ public final class ConsecutiveTapsGestureDetector {
mView = view;
int doubleTapSlop = ViewConfiguration.get(mView.getContext()).getScaledDoubleTapSlop();
mConsecutiveTapTouchSlopSquare = doubleTapSlop * doubleTapSlop;
+ mConsecutiveTapTimeout = ViewConfiguration.getDoubleTapTimeout();
}
/**
@@ -109,6 +111,8 @@ public final class ConsecutiveTapsGestureDetector {
double deltaX = mPreviousTapEvent.getX() - currentTapEvent.getX();
double deltaY = mPreviousTapEvent.getY() - currentTapEvent.getY();
- return (deltaX * deltaX + deltaY * deltaY <= mConsecutiveTapTouchSlopSquare);
+ long deltaTime = currentTapEvent.getEventTime() - mPreviousTapEvent.getEventTime();
+ return (deltaX * deltaX + deltaY * deltaY <= mConsecutiveTapTouchSlopSquare)
+ && deltaTime < mConsecutiveTapTimeout;
}
}
diff --git a/library/test/robotest/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetectorTest.java b/library/test/robotest/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetectorTest.java
new file mode 100644
index 0000000..aa2cce3
--- /dev/null
+++ b/library/test/robotest/src/com/android/setupwizardlib/gesture/ConsecutiveTapsGestureDetectorTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.setupwizardlib.gesture;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.robolectric.RuntimeEnvironment.application;
+
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+import com.android.setupwizardlib.robolectric.SuwLibRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+@Config(sdk = { Config.OLDEST_SDK, Config.NEWEST_SDK })
+@RunWith(SuwLibRobolectricTestRunner.class)
+public class ConsecutiveTapsGestureDetectorTest {
+
+ @Mock
+ private ConsecutiveTapsGestureDetector.OnConsecutiveTapsListener mListener;
+
+ private ConsecutiveTapsGestureDetector mDetector;
+ private int mSlop;
+ private int mTapTimeout;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ View view = new View(application);
+ view.measure(500, 500);
+ view.layout(0, 0, 500, 500);
+ mDetector = new ConsecutiveTapsGestureDetector(mListener, view);
+
+ mSlop = ViewConfiguration.get(application).getScaledDoubleTapSlop();
+ mTapTimeout = ViewConfiguration.getDoubleTapTimeout();
+ }
+
+ @Test
+ public void onTouchEvent_shouldTriggerCallbackOnFourTaps() {
+ InOrder inOrder = inOrder(mListener);
+
+ tap(0, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(1));
+
+ tap(100, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(2));
+
+ tap(200, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(3));
+
+ tap(300, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(4));
+ }
+
+ @Test
+ public void onTouchEvent_tapOnDifferentLocation_shouldResetCounter() {
+ InOrder inOrder = inOrder(mListener);
+
+ tap(0, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(1));
+
+ tap(100, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(2));
+
+ tap(200, 25f + mSlop * 2, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(1));
+
+ tap(300, 25f + mSlop * 2, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(2));
+ }
+
+ @Test
+ public void onTouchEvent_tapAfterTimeout_shouldResetCounter() {
+ InOrder inOrder = inOrder(mListener);
+
+ tap(0, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(1));
+
+ tap(100, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(2));
+
+ tap(200 + mTapTimeout, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(1));
+
+ tap(300 + mTapTimeout, 25f, 25f);
+ inOrder.verify(mListener).onConsecutiveTaps(eq(2));
+ }
+
+ private void tap(int timeMillis, float x, float y) {
+ mDetector.onTouchEvent(
+ MotionEvent.obtain(timeMillis, timeMillis, MotionEvent.ACTION_DOWN, x, y, 0));
+ mDetector.onTouchEvent(
+ MotionEvent.obtain(timeMillis, timeMillis + 10, MotionEvent.ACTION_UP, x, y, 0));
+ }
+}