Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: content/browser/renderer_host/input/gesture_event_queue_unittest.cc

Issue 120513005: [Android] Perform eager gesture recognition on MotionEvents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More cleanup Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/logging.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "content/browser/renderer_host/input/gesture_event_queue.h"
9 #include "content/common/input/synthetic_web_input_event_builders.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/WebKit/public/web/WebInputEvent.h"
12
13 using blink::WebGestureEvent;
14 using blink::WebInputEvent;
15 using blink::WebTouchEvent;
16 using blink::WebTouchPoint;
17
18 namespace content {
19
20 class GestureEventQueueTest : public testing::Test,
21 public GestureEventQueueClient {
22 public:
23 GestureEventQueueTest() : sent_gesture_count_(0) {}
24
25 virtual ~GestureEventQueueTest() {}
26
27 // testing::Test
28 virtual void SetUp() OVERRIDE {
29 queue_.reset(new GestureEventQueue(this));
30 }
31
32 virtual void TearDown() OVERRIDE {
33 queue_.reset();
34 }
35
36 // GestureEventQueueClient
37 virtual void ForwardGestureEvent(const WebGestureEvent& event) OVERRIDE {
38 ++sent_gesture_count_;
39 last_gesture_event_ = event;
40 }
41
42 protected:
43 typedef std::vector<WebGestureEvent> Gestures;
44
45 void SendTouchGestures() {
46 GestureEventPacket gesture_packet;
47 std::swap(gesture_packet, gesture_packet_);
48 SendTouchGestures(touch_event_, gesture_packet);
49 touch_event_.ResetPoints();
50 }
51
52 void SendTouchGestures(const WebTouchEvent& touch,
53 const GestureEventPacket& packet) {
54 GestureEventPacket touch_packet = GestureEventPacket::FromTouch(touch);
55 for (size_t i = 0; i < packet.gesture_count(); ++i)
56 touch_packet.Push(packet.gesture(i));
57 queue_->OnGestureEventPacket(touch_packet);
58 }
59
60 void SendGesture(GestureEventPacket::GestureSource source,
61 const WebGestureEvent& gesture) {
62 queue_->OnGestureEventPacket(
63 GestureEventPacket::FromGesture(source, gesture));
64 }
65
66 void SendTimeoutGesture(const WebGestureEvent& gesture) {
67 SendGesture(GestureEventPacket::TOUCH_TIMEOUT, gesture);
68 }
69
70 void SendSyntheticGesture(const WebGestureEvent& gesture) {
71 SendGesture(GestureEventPacket::SYNTHETIC, gesture);
72 }
73
74 void SendTouchEventACK(InputEventAckState ack_result) {
75 queue_->OnTouchEventAck(ack_result);
76 }
77
78 void PushGesture(const WebGestureEvent& gesture) {
79 gesture_packet_.Push(gesture);
80 }
81
82 void PushGesture(WebInputEvent::Type type) {
83 DCHECK(WebInputEvent::isGestureEventType(type));
84 PushGesture(CreateGesture(type));
85 }
86
87 void PressTouchPoint(int x, int y) {
88 touch_event_.PressPoint(x, y);
89 SendTouchGestures();
90 }
91
92 void MoveTouchPoint(int index, int x, int y) {
93 touch_event_.MovePoint(index, x, y);
94 SendTouchGestures();
95 }
96
97 void MoveTouchPoints(int index0, int x0, int y0, int index1, int x1, int y1) {
98 touch_event_.MovePoint(index0, x0, y0);
99 touch_event_.MovePoint(index1, x1, y1);
100 SendTouchGestures();
101 }
102
103 void ReleaseTouchPoint(int index) {
104 touch_event_.ReleasePoint(index);
105 SendTouchGestures();
106 }
107
108 void CancelTouchPoint(int index) {
109 touch_event_.CancelPoint(index);
110 SendTouchGestures();
111 }
112
113 size_t GetAndResetSentGestureCount() {
114 size_t count = sent_gesture_count_;
115 sent_gesture_count_ = 0;
116 return count;
117 }
118
119 const WebGestureEvent& sent_gesture() const {
120 return last_gesture_event_;
121 }
122
123 static WebGestureEvent CreateGesture(WebInputEvent::Type type) {
124 return SyntheticWebGestureEventBuilder::Build(
125 type, WebGestureEvent::Touchscreen);
126 }
127
128 private:
129
130 scoped_ptr<GestureEventQueue> queue_;
131 SyntheticWebTouchEvent touch_event_;
132 GestureEventPacket gesture_packet_;
133 size_t sent_gesture_count_;
134 WebTouchEvent last_touch_event_;
135 WebGestureEvent last_gesture_event_;
136 };
137
138 TEST_F(GestureEventQueueTest, BasicNoGestures) {
139 PressTouchPoint(1, 1);
140 EXPECT_EQ(0U, GetAndResetSentGestureCount());
141
142 MoveTouchPoint(0, 2, 2);
143 EXPECT_EQ(0U, GetAndResetSentGestureCount());
144
145 // No gestures should be dispatched by the ack, as the queued packets
146 // contained no gestures.
147 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
148 EXPECT_EQ(0U, GetAndResetSentGestureCount());
149
150 // Release the touch gesture.
151 ReleaseTouchPoint(0);
152 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
153 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
154 EXPECT_EQ(0U, GetAndResetSentGestureCount());
155 }
156
157 TEST_F(GestureEventQueueTest, BasicGestures) {
158 // An unconsumed touch's gesture should be sent.
159 PushGesture(WebInputEvent::GestureScrollBegin);
160 PressTouchPoint(1, 1);
161 EXPECT_EQ(0U, GetAndResetSentGestureCount());
162 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
163 EXPECT_EQ(1U, GetAndResetSentGestureCount());
164 EXPECT_EQ(WebInputEvent::GestureScrollBegin, sent_gesture().type);
165
166 // Multiple gestures can be queued for a single event.
167 PushGesture(WebInputEvent::GestureFlingStart);
168 PushGesture(WebInputEvent::GestureFlingCancel);
169 MoveTouchPoint(0, 1, 1);
170 EXPECT_EQ(0U, GetAndResetSentGestureCount());
171 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
172 EXPECT_EQ(2U, GetAndResetSentGestureCount());
173 EXPECT_EQ(WebInputEvent::GestureFlingCancel, sent_gesture().type);
174
175 // A consumed touch's gesture should not be sent.
176 PushGesture(WebInputEvent::GestureFlingStart);
177 PushGesture(WebInputEvent::GestureFlingCancel);
178 ReleaseTouchPoint(0);
179 EXPECT_EQ(0U, GetAndResetSentGestureCount());
180 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
181 EXPECT_EQ(0U, GetAndResetSentGestureCount());
182 }
183
184 TEST_F(GestureEventQueueTest, ConsumedThenNotConsumed) {
185 // A consumed touch's gesture should not be sent.
186 PushGesture(WebInputEvent::GestureScrollBegin);
187 PressTouchPoint(1, 1);
188 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
189 EXPECT_EQ(0U, GetAndResetSentGestureCount());
190
191 // Event if the subsequent touch is not consumed, continue dropping gestures.
192 PushGesture(WebInputEvent::GestureScrollUpdate);
193 MoveTouchPoint(0, 2, 2);
194 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
195 EXPECT_EQ(0U, GetAndResetSentGestureCount());
196
197 // Event if the subsequent touch had no consumer, continue dropping gestures.
198 PushGesture(WebInputEvent::GestureFlingStart);
199 ReleaseTouchPoint(0);
200 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
201 EXPECT_EQ(0U, GetAndResetSentGestureCount());
202 }
203
204 TEST_F(GestureEventQueueTest, NotConsumedThenNoConsumer) {
205 // An unconsumed touch's gesture should be sent.
206 PushGesture(WebInputEvent::GestureScrollBegin);
207 PressTouchPoint(1, 1);
208 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
209 EXPECT_EQ(1U, GetAndResetSentGestureCount());
210
211 // If the subsequent touch has no consumer (e.g., a secondary pointer is
212 // pressed but not on a touch handling rect), send the gesture.
213 PushGesture(WebInputEvent::GesturePinchBegin);
214 PressTouchPoint(2, 2);
215 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
216 EXPECT_EQ(1U, GetAndResetSentGestureCount());
217
218 // If the subsequent touch is consumed, then the remaining gesture sequence
219 // should be dropped, regardless of subsequent touch ack disposition.
220 PushGesture(WebInputEvent::GestureScrollUpdate);
221 PushGesture(WebInputEvent::GesturePinchUpdate);
222 MoveTouchPoint(0, 2, 2);
223 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
224 EXPECT_EQ(0U, GetAndResetSentGestureCount());
225
226 PushGesture(WebInputEvent::GesturePinchEnd);
227 ReleaseTouchPoint(1);
228 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
229 EXPECT_EQ(0U, GetAndResetSentGestureCount());
230
231 PushGesture(WebInputEvent::GestureScrollEnd);
232 ReleaseTouchPoint(0);
233 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
234 EXPECT_EQ(0U, GetAndResetSentGestureCount());
235 }
236
237 TEST_F(GestureEventQueueTest, MultipleTouchSequences) {
238 // Queue two touch-to-gestures sequences.
239 PushGesture(WebInputEvent::GestureFlingStart);
240 PressTouchPoint(1, 1);
241 PushGesture(WebInputEvent::GestureFlingCancel);
242 ReleaseTouchPoint(0);
243 PushGesture(WebInputEvent::GestureFlingStart);
244 PressTouchPoint(1, 1);
245 PushGesture(WebInputEvent::GestureFlingCancel);
246 ReleaseTouchPoint(0);
247
248 // The first gesture sequence should not be allowed.
249 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
250 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
251 EXPECT_EQ(0U, GetAndResetSentGestureCount());
252
253 // The subsequent sequence should "reset" allowance.
254 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
255 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
256 EXPECT_EQ(2U, GetAndResetSentGestureCount());
257 }
258
259 TEST_F(GestureEventQueueTest, FlingCancelledOnNewTouchSequence) {
260 // Simulate a fling start that is sent.
261 PressTouchPoint(1, 1);
262 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
263 PushGesture(WebInputEvent::GestureFlingStart);
264 ReleaseTouchPoint(0);
265 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
266 EXPECT_EQ(1U, GetAndResetSentGestureCount());
267 EXPECT_EQ(WebInputEvent::GestureFlingStart, sent_gesture().type);
268
269 // A new touch seqeuence should cancel the outstanding fling.
270 PressTouchPoint(1, 1);
271 ReleaseTouchPoint(0);
272 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
273 EXPECT_EQ(1U, GetAndResetSentGestureCount());
274 EXPECT_EQ(WebInputEvent::GestureFlingCancel, sent_gesture().type);
275 }
276
277 TEST_F(GestureEventQueueTest, FlingNotCancelledIfGFCEventReceived) {
278 // Simulate a fling that is started then cancelled.
279 PushGesture(WebInputEvent::GestureFlingStart);
280 PressTouchPoint(1, 1);
281 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
282 PushGesture(WebInputEvent::GestureFlingCancel);
283 ReleaseTouchPoint(0);
284 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
285 EXPECT_EQ(2U, GetAndResetSentGestureCount());
286 EXPECT_EQ(WebInputEvent::GestureFlingCancel, sent_gesture().type);
287
288 // A new touch sequence will not inject a GestureFlingCancel, as the fling
289 // has already been cancelled.
290 PressTouchPoint(1, 1);
291 ReleaseTouchPoint(0);
292 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
293 EXPECT_EQ(0U, GetAndResetSentGestureCount());
294 }
295
296 TEST_F(GestureEventQueueTest, TapCancelledWhenScrollBegins) {
297 PushGesture(WebInputEvent::GestureTapDown);
298 PressTouchPoint(1, 1);
299 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
300 EXPECT_EQ(1U, GetAndResetSentGestureCount());
301 EXPECT_EQ(WebInputEvent::GestureTapDown, sent_gesture().type);
302
303 // If the subsequent touch turns into a scroll, the tap should be cancelled.
304 PushGesture(WebInputEvent::GestureScrollBegin);
305 MoveTouchPoint(0, 2, 2);
306 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
307 EXPECT_EQ(2U, GetAndResetSentGestureCount());
308 EXPECT_EQ(WebInputEvent::GestureScrollBegin, sent_gesture().type);
Rick Byers 2014/01/23 20:45:29 The other expected gesture is a TapCancel, but tha
tdresser 2014/01/23 21:42:18 Since gmock isn't widely accepted in chromium, I t
jdduke (slow) 2014/01/24 05:34:40 Yeah, I should do this right. Good catch.
Rick Byers 2014/01/25 14:00:41 Thanks for putting the extra time into this, I lik
309 }
310
311 TEST_F(GestureEventQueueTest, TapCancelledWhenTouchConsumed) {
312 PushGesture(WebInputEvent::GestureTapDown);
313 PressTouchPoint(1, 1);
314 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
315 EXPECT_EQ(1U, GetAndResetSentGestureCount());
316 EXPECT_EQ(WebInputEvent::GestureTapDown, sent_gesture().type);
317
318 // If the subsequent touch is consumed, the tap should be cancelled.
319 PushGesture(WebInputEvent::GestureScrollBegin);
320 MoveTouchPoint(0, 2, 2);
321 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
322 EXPECT_EQ(1U, GetAndResetSentGestureCount());
323 EXPECT_EQ(WebInputEvent::GestureTapCancel, sent_gesture().type);
324 }
325
326 TEST_F(GestureEventQueueTest, TapNotCancelledIfTapEndingEventReceived) {
327 PushGesture(WebInputEvent::GestureTapDown);
328 PressTouchPoint(1, 1);
329 PressTouchPoint(2, 2);
330 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
331 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
332 EXPECT_EQ(1U, GetAndResetSentGestureCount());
333 EXPECT_EQ(WebInputEvent::GestureTapDown, sent_gesture().type);
334
335 PushGesture(WebInputEvent::GestureTap);
336 ReleaseTouchPoint(1);
337 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
338 EXPECT_EQ(1U, GetAndResetSentGestureCount());
339 EXPECT_EQ(WebInputEvent::GestureTap, sent_gesture().type);
340
341 // The tap should not be cancelled as it was terminated by a |GestureTap|.
342 ReleaseTouchPoint(0);
343 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
344 EXPECT_EQ(0U, GetAndResetSentGestureCount());
345 }
346
347 TEST_F(GestureEventQueueTest, TimeoutGestures) {
348 // If the sequence is allowed, and there are no preceding gestures, the
349 // timeout gestures should be forwarded immediately.
350 PressTouchPoint(1, 1);
351 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
352 EXPECT_EQ(0U, GetAndResetSentGestureCount());
353
354 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureShowPress));
355 EXPECT_EQ(1U, GetAndResetSentGestureCount());
356 EXPECT_EQ(WebInputEvent::GestureShowPress, sent_gesture().type);
357 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureLongPress));
358 EXPECT_EQ(1U, GetAndResetSentGestureCount());
359 EXPECT_EQ(WebInputEvent::GestureLongPress, sent_gesture().type);
360 ReleaseTouchPoint(0);
361 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
362
363 // If the sequence is disallowed, and there are no preceding gestures, the
364 // timeout gestures should be dropped immediately.
365 PressTouchPoint(1, 1);
366 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
367 EXPECT_EQ(0U, GetAndResetSentGestureCount());
368
369 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureShowPress));
370 EXPECT_EQ(0U, GetAndResetSentGestureCount());
371 ReleaseTouchPoint(0);
372 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
373
374 // If the sequence has a pending ack, the timeout gestures should
375 // remain queued until the ack is received.
376 PressTouchPoint(1, 1);
377 EXPECT_EQ(0U, GetAndResetSentGestureCount());
378
379 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureLongPress));
380 EXPECT_EQ(0U, GetAndResetSentGestureCount());
381
382 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
383 EXPECT_EQ(1U, GetAndResetSentGestureCount());
384 EXPECT_EQ(WebInputEvent::GestureLongPress, sent_gesture().type);
385 }
386
387 TEST_F(GestureEventQueueTest, SyntheticGestures) {
388 // Synthetic gestures without an associated touch event should be
389 // forwarded immediately if there are no preceding gestures.
390 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchBegin));
391 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchUpdate));
392 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchEnd));
393 EXPECT_EQ(3U, GetAndResetSentGestureCount());
394 EXPECT_EQ(WebInputEvent::GesturePinchEnd, sent_gesture().type);
395
396 // Queue a blocking touch gesture.
397 PushGesture(WebInputEvent::GestureFlingStart);
398 PressTouchPoint(1, 1);
399 ASSERT_EQ(0U, GetAndResetSentGestureCount());
400
401 // Subsequent synthetic events should only be forwarded after the
402 // touch-derived gesture has been dispatched.
403 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchBegin));
404 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchUpdate));
405 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchEnd));
406 EXPECT_EQ(0U, GetAndResetSentGestureCount());
407
408 // Dispatching the queued gesture should unblock the synthetic gestures.
409 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
410 EXPECT_EQ(4U, GetAndResetSentGestureCount());
411 EXPECT_EQ(WebInputEvent::GesturePinchEnd, sent_gesture().type);
412 }
413
414 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698