OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chromoting; | 5 package org.chromium.chromoting; |
6 | 6 |
| 7 import android.content.Context; |
7 import android.os.SystemClock; | 8 import android.os.SystemClock; |
8 import android.test.InstrumentationTestCase; | 9 import android.test.InstrumentationTestCase; |
9 import android.test.suitebuilder.annotation.SmallTest; | 10 import android.test.suitebuilder.annotation.SmallTest; |
10 import android.view.InputDevice; | 11 import android.view.InputDevice; |
11 import android.view.MotionEvent; | 12 import android.view.MotionEvent; |
| 13 import android.view.ViewConfiguration; |
12 | 14 |
13 import org.chromium.base.test.util.Feature; | 15 import org.chromium.base.test.util.Feature; |
14 | 16 |
15 /** Tests for {@link SwipePinchDetector}. */ | 17 /** Tests for {@link SwipePinchDetector}. */ |
16 public class SwipePinchDetectorTest extends InstrumentationTestCase { | 18 public class SwipePinchDetectorTest extends InstrumentationTestCase { |
17 private SwipePinchDetector mDetector; | 19 private SwipePinchDetector mDetector; |
| 20 private float mTouchSlop; |
18 private MotionEvent.PointerProperties[] mPointers; | 21 private MotionEvent.PointerProperties[] mPointers; |
19 | 22 |
| 23 // Stores the current finger positions, for convenience in writing tests. Th
ese values are |
| 24 // initialized during setUp(). |
| 25 private MotionEvent.PointerCoords[] mCurrentPositions; |
| 26 |
20 @Override | 27 @Override |
21 public void setUp() { | 28 public void setUp() { |
22 mDetector = new SwipePinchDetector(getInstrumentation().getTargetContext
()); | 29 Context context = getInstrumentation().getTargetContext(); |
| 30 mDetector = new SwipePinchDetector(context); |
| 31 mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); |
23 MotionEvent.PointerProperties pointer0 = new MotionEvent.PointerProperti
es(); | 32 MotionEvent.PointerProperties pointer0 = new MotionEvent.PointerProperti
es(); |
24 pointer0.id = 0; | 33 pointer0.id = 0; |
25 MotionEvent.PointerProperties pointer1 = new MotionEvent.PointerProperti
es(); | 34 MotionEvent.PointerProperties pointer1 = new MotionEvent.PointerProperti
es(); |
26 pointer1.id = 1; | 35 pointer1.id = 1; |
27 mPointers = new MotionEvent.PointerProperties[] {pointer0, pointer1}; | 36 mPointers = new MotionEvent.PointerProperties[] {pointer0, pointer1}; |
28 } | 37 |
29 | 38 MotionEvent.PointerCoords position0 = new MotionEvent.PointerCoords(); |
30 /** Verify that a simple swipe gesture is recognized as a swipe. */ | 39 MotionEvent.PointerCoords position1 = new MotionEvent.PointerCoords(); |
| 40 mCurrentPositions = new MotionEvent.PointerCoords[] {position0, position
1}; |
| 41 |
| 42 // The starting points are arbitrary, but non-zero to ensure that the te
sts detect relative, |
| 43 // not absolute, motion. |
| 44 mCurrentPositions[0].x = 100; |
| 45 mCurrentPositions[0].y = 200; |
| 46 mCurrentPositions[1].x = 300; |
| 47 mCurrentPositions[1].y = 400; |
| 48 } |
| 49 |
| 50 /** |
| 51 * Simulates a 2-finger event. The action parameter should be MotionEvent.AC
TION_POINTER_DOWN, |
| 52 * MotionEvent.ACTION_MOVE or MotionEvent.ACTION_POINTER_UP. |
| 53 */ |
| 54 private void injectEvent(int action) { |
| 55 final long eventTime = SystemClock.uptimeMillis(); |
| 56 MotionEvent event = MotionEvent.obtain(eventTime, eventTime, action, 2,
mPointers, |
| 57 mCurrentPositions, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCR
EEN, 0); |
| 58 mDetector.onTouchEvent(event); |
| 59 } |
| 60 |
| 61 /** Verifies that a simple swipe gesture is recognized as a swipe. */ |
31 @SmallTest | 62 @SmallTest |
32 @Feature({"Chromoting"}) | 63 @Feature({"Chromoting"}) |
33 public void testSwipeRecognition() throws Exception { | 64 public void testSwipeRecognition() throws Exception { |
34 final long eventTime = SystemClock.uptimeMillis(); | 65 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
35 MotionEvent.PointerCoords p0 = new MotionEvent.PointerCoords(); | |
36 MotionEvent.PointerCoords p1 = new MotionEvent.PointerCoords(); | |
37 p1.x = 50; | |
38 p1.y = 0; | |
39 MotionEvent.PointerCoords[] pointerCoords = {p0, p1}; | |
40 MotionEvent event = MotionEvent.obtain(eventTime, eventTime, | |
41 MotionEvent.ACTION_POINTER_DOWN, 2, mPointers, pointerCoords, 0,
0, 1, 1, 0, 0, | |
42 InputDevice.SOURCE_TOUCHSCREEN , 0); | |
43 mDetector.onTouchEvent(event); | |
44 assertFalse(mDetector.isSwiping()); | 66 assertFalse(mDetector.isSwiping()); |
45 assertFalse(mDetector.isPinching()); | 67 assertFalse(mDetector.isPinching()); |
46 | 68 |
47 // Any distance greater than the touch-slop threshold should work. | 69 // Any distance greater than the touch-slop threshold should work. |
48 p0.y += 100; | 70 mCurrentPositions[0].y += mTouchSlop * 2; |
49 p1.y += 100; | 71 mCurrentPositions[1].y += mTouchSlop * 2; |
50 | 72 injectEvent(MotionEvent.ACTION_MOVE); |
51 event = MotionEvent.obtain(eventTime, eventTime, MotionEvent.ACTION_MOVE
, 2, mPointers, | |
52 pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN
, 0); | |
53 mDetector.onTouchEvent(event); | |
54 assertTrue(mDetector.isSwiping()); | 73 assertTrue(mDetector.isSwiping()); |
55 assertFalse(mDetector.isPinching()); | 74 assertFalse(mDetector.isPinching()); |
56 } | 75 } |
| 76 |
| 77 /** Verifies that a simple pinch gesture is recognized. */ |
| 78 @SmallTest |
| 79 @Feature({"Chromoting"}) |
| 80 public void testPinchRecognition() throws Exception { |
| 81 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 82 assertFalse(mDetector.isSwiping()); |
| 83 assertFalse(mDetector.isPinching()); |
| 84 |
| 85 // Any distance greater than the touch-slop threshold should work. |
| 86 mCurrentPositions[0].x -= mTouchSlop * 2; |
| 87 mCurrentPositions[1].x += mTouchSlop * 2; |
| 88 injectEvent(MotionEvent.ACTION_MOVE); |
| 89 assertFalse(mDetector.isSwiping()); |
| 90 assertTrue(mDetector.isPinching()); |
| 91 } |
| 92 |
| 93 /** Verifies that motion less than touch-slop does not trigger anything. */ |
| 94 @SmallTest |
| 95 @Feature({"Chromoting"}) |
| 96 public void testNoMotion() throws Exception { |
| 97 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 98 mCurrentPositions[0].x += mTouchSlop / 2; |
| 99 mCurrentPositions[0].y += mTouchSlop / 2; |
| 100 mCurrentPositions[1].x -= mTouchSlop / 2; |
| 101 mCurrentPositions[1].y -= mTouchSlop / 2; |
| 102 injectEvent(MotionEvent.ACTION_MOVE); |
| 103 assertFalse(mDetector.isSwiping()); |
| 104 assertFalse(mDetector.isPinching()); |
| 105 } |
| 106 |
| 107 /** Verifies that a pinch with one finger stationary is detected. */ |
| 108 @SmallTest |
| 109 @Feature({"Chromoting"}) |
| 110 public void testOneFingerStationary() throws Exception { |
| 111 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 112 |
| 113 // The triggering threshold in this case (one finger stationary) is mTou
chSlop * 2; |
| 114 mCurrentPositions[1].x += mTouchSlop * 3; |
| 115 injectEvent(MotionEvent.ACTION_MOVE); |
| 116 assertFalse(mDetector.isSwiping()); |
| 117 assertTrue(mDetector.isPinching()); |
| 118 |
| 119 // Do the same test for the other finger. |
| 120 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 121 mCurrentPositions[0].x += mTouchSlop * 3; |
| 122 injectEvent(MotionEvent.ACTION_MOVE); |
| 123 assertFalse(mDetector.isSwiping()); |
| 124 assertTrue(mDetector.isPinching()); |
| 125 } |
| 126 |
| 127 /** |
| 128 * Verifies that a pinch is recognized, when the fingers cross the motion th
reshold at |
| 129 * different times. |
| 130 */ |
| 131 @SmallTest |
| 132 @Feature({"Chromoting"}) |
| 133 public void testUnevenPinch() throws Exception { |
| 134 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 135 for (int i = 0; i < 50; i++) { |
| 136 mCurrentPositions[0].x -= 2; |
| 137 mCurrentPositions[1].x += 3; |
| 138 injectEvent(MotionEvent.ACTION_MOVE); |
| 139 } |
| 140 |
| 141 assertFalse(mDetector.isSwiping()); |
| 142 assertTrue(mDetector.isPinching()); |
| 143 } |
| 144 |
| 145 /** Same test as testUnevenPinch() except the slow/fast fingers are reversed
. */ |
| 146 @SmallTest |
| 147 @Feature({"Chromoting"}) |
| 148 public void testUnevenPinch2() throws Exception { |
| 149 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 150 for (int i = 0; i < 50; i++) { |
| 151 mCurrentPositions[0].x -= 3; |
| 152 mCurrentPositions[1].x += 2; |
| 153 injectEvent(MotionEvent.ACTION_MOVE); |
| 154 } |
| 155 |
| 156 assertFalse(mDetector.isSwiping()); |
| 157 assertTrue(mDetector.isPinching()); |
| 158 } |
| 159 |
| 160 /** Verifies that a swipe is recognized, even if the fingers move at differe
nt rates. */ |
| 161 @SmallTest |
| 162 @Feature({"Chromoting"}) |
| 163 public void testUnevenSwipe() throws Exception { |
| 164 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 165 for (int i = 0; i < 50; i++) { |
| 166 // The fingers need to move similarly enough so that one finger move
s a distance of |
| 167 // 2 * mTouchSlop after the other finger moves a distance of mTouchS
lop. |
| 168 // Otherwise the gesture would be mis-detected as a one-finger-stati
onary pinch. |
| 169 mCurrentPositions[0].y += 2; |
| 170 mCurrentPositions[1].y += 3; |
| 171 injectEvent(MotionEvent.ACTION_MOVE); |
| 172 } |
| 173 |
| 174 assertTrue(mDetector.isSwiping()); |
| 175 assertFalse(mDetector.isPinching()); |
| 176 } |
| 177 |
| 178 /** Same test as testUnevenSwipe() except the slow/fast fingers are reversed
. */ |
| 179 @SmallTest |
| 180 @Feature({"Chromoting"}) |
| 181 public void testUnevenSwipe2() throws Exception { |
| 182 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 183 for (int i = 0; i < 50; i++) { |
| 184 // The fingers need to move similarly enough so that one finger move
s a distance of |
| 185 // 2 * mTouchSlop after the other finger moves a distance of mTouchS
lop. |
| 186 // Otherwise the gesture would be mis-detected as a one-finger-stati
onary pinch. |
| 187 mCurrentPositions[0].y += 3; |
| 188 mCurrentPositions[1].y += 2; |
| 189 injectEvent(MotionEvent.ACTION_MOVE); |
| 190 } |
| 191 |
| 192 assertTrue(mDetector.isSwiping()); |
| 193 assertFalse(mDetector.isPinching()); |
| 194 } |
| 195 |
| 196 /** Verifies that the detector is reset when a gesture terminates or a new g
esture begins. */ |
| 197 @SmallTest |
| 198 @Feature({"Chromoting"}) |
| 199 public void testDetectorReset() throws Exception { |
| 200 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 201 mCurrentPositions[0].x += mTouchSlop * 3; |
| 202 injectEvent(MotionEvent.ACTION_MOVE); |
| 203 assertTrue(mDetector.isPinching()); |
| 204 |
| 205 // ACTION_POINTER_UP should terminate the gesture. |
| 206 injectEvent(MotionEvent.ACTION_POINTER_UP); |
| 207 assertFalse(mDetector.isPinching()); |
| 208 |
| 209 // Repeat the same test, but use ACTION_POINTER_DOWN to start a new gest
ure, which should |
| 210 // terminate the current one. |
| 211 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 212 mCurrentPositions[0].x += mTouchSlop * 3; |
| 213 injectEvent(MotionEvent.ACTION_MOVE); |
| 214 assertTrue(mDetector.isPinching()); |
| 215 injectEvent(MotionEvent.ACTION_POINTER_DOWN); |
| 216 assertFalse(mDetector.isPinching()); |
| 217 } |
57 } | 218 } |
OLD | NEW |