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

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 testing Created 6 years, 10 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/memory/scoped_ptr.h"
7 #include "content/browser/renderer_host/input/gesture_event_queue.h"
8 #include "content/common/input/synthetic_web_input_event_builders.h"
9 #include "content/common/input/web_input_event_traits.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 sent_gestures_.push_back(event.type);
40 }
41
42 protected:
43 typedef std::vector<WebInputEvent::Type> GestureList;
44
45 ::testing::AssertionResult GesturesMatch(const GestureList& expected,
46 const GestureList& actual) {
47 if (expected.size() != actual.size()) {
48 return ::testing::AssertionFailure()
49 << "actual.size(" << actual.size()
50 << ") != expected.size(" << expected.size() << ")";
51 }
52
53 for (size_t i = 0; i < expected.size(); ++i) {
54 if (expected[i] != actual[i]) {
55 return ::testing::AssertionFailure()
56 << "actual[" << i << "] ("
57 << WebInputEventTraits::GetName(actual[i])
58 << ") != expected[" << i << "] ("
59 << WebInputEventTraits::GetName(expected[i]) << ")";
60 }
61 }
62
63 return ::testing::AssertionSuccess();
64 }
65
66 GestureList Gestures(WebInputEvent::Type type) {
67 return GestureList(1, type);
68 }
69
70 GestureList Gestures(WebInputEvent::Type type0, WebInputEvent::Type type1) {
71 GestureList gestures(2);
72 gestures[0] = type0;
73 gestures[1] = type1;
74 return gestures;
75 }
76
77 GestureList Gestures(WebInputEvent::Type type0,
78 WebInputEvent::Type type1,
79 WebInputEvent::Type type2) {
80 GestureList gestures(3);
81 gestures[0] = type0;
82 gestures[1] = type1;
83 gestures[2] = type2;
84 return gestures;
85 }
86
87 GestureList Gestures(WebInputEvent::Type type0,
88 WebInputEvent::Type type1,
89 WebInputEvent::Type type2,
90 WebInputEvent::Type type3) {
91 GestureList gestures(4);
92 gestures[0] = type0;
93 gestures[1] = type1;
94 gestures[2] = type2;
95 gestures[3] = type3;
96 return gestures;
97 }
98
99 void SendTouchGestures() {
100 GestureEventPacket gesture_packet;
101 std::swap(gesture_packet, pending_gesture_packet_);
102 SendTouchGestures(touch_event_, gesture_packet);
103 touch_event_.ResetPoints();
104 }
105
106 void SendTouchGestures(const WebTouchEvent& touch,
107 const GestureEventPacket& packet) {
108 GestureEventPacket touch_packet = GestureEventPacket::FromTouch(touch);
109 for (size_t i = 0; i < packet.gesture_count(); ++i)
110 touch_packet.Push(packet.gesture(i));
111 queue_->OnGestureEventPacket(touch_packet);
112 }
113
114 void SendTimeoutGesture(WebInputEvent::Type type) {
115 queue_->OnGestureEventPacket(
116 GestureEventPacket::FromTouchTimeout(CreateGesture(type)));
117 }
118
119 void SendTouchEventACK(InputEventAckState ack_result) {
120 queue_->OnTouchEventAck(ack_result);
121 }
122
123 void PushGesture(WebInputEvent::Type type) {
124 pending_gesture_packet_.Push(CreateGesture(type));
125 }
126
127 void PressTouchPoint(int x, int y) {
128 touch_event_.PressPoint(x, y);
129 SendTouchGestures();
130 }
131
132 void MoveTouchPoint(int index, int x, int y) {
133 touch_event_.MovePoint(index, x, y);
134 SendTouchGestures();
135 }
136
137 void ReleaseTouchPoint(int index) {
138 touch_event_.ReleasePoint(index);
139 SendTouchGestures();
140 }
141
142 void CancelTouchPoint(int index) {
143 touch_event_.CancelPoint(index);
144 SendTouchGestures();
145 }
146
147 bool GesturesSent() const {
148 return !sent_gestures_.empty();
149 }
150
151 GestureList GetAndResetSentGestures() {
152 GestureList sent_gestures;
153 sent_gestures.swap(sent_gestures_);
154 return sent_gestures;
155 }
156
157 static WebGestureEvent CreateGesture(WebInputEvent::Type type) {
158 return SyntheticWebGestureEventBuilder::Build(
159 type, WebGestureEvent::Touchscreen);
160 }
161
162 private:
163 scoped_ptr<GestureEventQueue> queue_;
164 SyntheticWebTouchEvent touch_event_;
165 GestureEventPacket pending_gesture_packet_;
166 size_t sent_gesture_count_;
167 GestureList sent_gestures_;
168 };
169
170 TEST_F(GestureEventQueueTest, BasicNoGestures) {
171 PressTouchPoint(1, 1);
172 EXPECT_FALSE(GesturesSent());
173
174 MoveTouchPoint(0, 2, 2);
175 EXPECT_FALSE(GesturesSent());
176
177 // No gestures should be dispatched by the ack, as the queued packets
178 // contained no gestures.
179 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
180 EXPECT_FALSE(GesturesSent());
181
182 // Release the touch gesture.
183 ReleaseTouchPoint(0);
184 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
185 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
186 EXPECT_FALSE(GesturesSent());
187 }
188
189 TEST_F(GestureEventQueueTest, BasicGestures) {
190 // An unconsumed touch's gesture should be sent.
191 PushGesture(WebInputEvent::GestureScrollBegin);
192 PressTouchPoint(1, 1);
193 EXPECT_FALSE(GesturesSent());
194 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
195 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureScrollBegin),
196 GetAndResetSentGestures()));
197
198 // Multiple gestures can be queued for a single event.
199 PushGesture(WebInputEvent::GestureFlingStart);
200 PushGesture(WebInputEvent::GestureFlingCancel);
201 MoveTouchPoint(0, 1, 1);
202 EXPECT_FALSE(GesturesSent());
203 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
204 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureFlingStart,
205 WebInputEvent::GestureFlingCancel),
206 GetAndResetSentGestures()));
207
208 // A consumed touch's gesture should not be sent.
209 PushGesture(WebInputEvent::GestureFlingStart);
210 PushGesture(WebInputEvent::GestureFlingCancel);
211 ReleaseTouchPoint(0);
212 EXPECT_FALSE(GesturesSent());
213 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
214 EXPECT_FALSE(GesturesSent());
215 }
216
217 TEST_F(GestureEventQueueTest, ConsumedThenNotConsumed) {
218 // A consumed touch's gesture should not be sent.
219 PushGesture(WebInputEvent::GestureScrollBegin);
220 PressTouchPoint(1, 1);
221 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
222 EXPECT_FALSE(GesturesSent());
223
224 // Even if the subsequent touch is not consumed, continue dropping gestures.
225 PushGesture(WebInputEvent::GestureScrollUpdate);
226 MoveTouchPoint(0, 2, 2);
227 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
228 EXPECT_FALSE(GesturesSent());
229
230 // Even if the subsequent touch had no consumer, continue dropping gestures.
231 PushGesture(WebInputEvent::GestureFlingStart);
232 ReleaseTouchPoint(0);
233 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
234 EXPECT_FALSE(GesturesSent());
235 }
236
237 TEST_F(GestureEventQueueTest, NotConsumedThenNoConsumer) {
238 // An unconsumed touch's gesture should be sent.
239 PushGesture(WebInputEvent::GestureScrollBegin);
240 PressTouchPoint(1, 1);
241 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
242 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureScrollBegin),
243 GetAndResetSentGestures()));
244
245 // If the subsequent touch has no consumer (e.g., a secondary pointer is
246 // pressed but not on a touch handling rect), send the gesture.
247 PushGesture(WebInputEvent::GesturePinchBegin);
248 PressTouchPoint(2, 2);
249 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
250 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GesturePinchBegin),
251 GetAndResetSentGestures()));
252
253 // If the subsequent touch is consumed, then the remaining gesture sequence
254 // should be dropped, regardless of subsequent touch ack disposition.
255 PushGesture(WebInputEvent::GestureScrollUpdate);
256 PushGesture(WebInputEvent::GesturePinchUpdate);
257 MoveTouchPoint(0, 2, 2);
258 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
259 EXPECT_FALSE(GesturesSent());
260
261 PushGesture(WebInputEvent::GesturePinchEnd);
262 ReleaseTouchPoint(1);
263 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
264 EXPECT_FALSE(GesturesSent());
265
266 PushGesture(WebInputEvent::GestureScrollEnd);
267 ReleaseTouchPoint(0);
268 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
269 EXPECT_FALSE(GesturesSent());
270 }
271
272 TEST_F(GestureEventQueueTest, MultipleTouchSequences) {
273 // Queue two touch-to-gestures sequences.
274 PushGesture(WebInputEvent::GestureFlingStart);
275 PressTouchPoint(1, 1);
276 PushGesture(WebInputEvent::GestureFlingCancel);
277 ReleaseTouchPoint(0);
278 PushGesture(WebInputEvent::GestureFlingStart);
279 PressTouchPoint(1, 1);
280 PushGesture(WebInputEvent::GestureFlingCancel);
281 ReleaseTouchPoint(0);
282
283 // The first gesture sequence should not be allowed.
284 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
285 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
286 EXPECT_FALSE(GesturesSent());
287
288 // The subsequent sequence should "reset" allowance.
289 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
290 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
291 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureFlingStart,
292 WebInputEvent::GestureFlingCancel),
293 GetAndResetSentGestures()));
294 }
295
296 TEST_F(GestureEventQueueTest, FlingCancelledOnNewTouchSequence) {
297 // Simulate a fling.
298 PressTouchPoint(1, 1);
299 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
300 PushGesture(WebInputEvent::GestureFlingStart);
301 ReleaseTouchPoint(0);
302 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
303 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureFlingStart),
304 GetAndResetSentGestures()));
305
306 // A new touch seqeuence should cancel the outstanding fling.
307 PressTouchPoint(1, 1);
308 ReleaseTouchPoint(0);
309 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
310 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureFlingCancel),
311 GetAndResetSentGestures()));
312 }
313
314 TEST_F(GestureEventQueueTest, FlingCancelledOnScrollBegin) {
315 // Simulate a fling sequence.
316 PushGesture(WebInputEvent::GestureScrollBegin);
317 PushGesture(WebInputEvent::GestureFlingStart);
318 PressTouchPoint(1, 1);
319 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
320 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureScrollBegin,
321 WebInputEvent::GestureFlingStart),
322 GetAndResetSentGestures()));
323
324 // The new fling should cancel the preceding one.
325 PushGesture(WebInputEvent::GestureScrollBegin);
326 PushGesture(WebInputEvent::GestureFlingStart);
327 ReleaseTouchPoint(0);
328 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
329 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureFlingCancel,
330 WebInputEvent::GestureScrollBegin,
331 WebInputEvent::GestureFlingStart),
332 GetAndResetSentGestures()));
333 }
334
335 TEST_F(GestureEventQueueTest, FlingNotCancelledIfGFCEventReceived) {
336 // Simulate a fling that is started then cancelled.
337 PushGesture(WebInputEvent::GestureFlingStart);
338 PressTouchPoint(1, 1);
339 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
340 PushGesture(WebInputEvent::GestureFlingCancel);
341 ReleaseTouchPoint(0);
342 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
343 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureFlingStart,
344 WebInputEvent::GestureFlingCancel),
345 GetAndResetSentGestures()));
346
347 // A new touch sequence will not inject a GestureFlingCancel, as the fling
348 // has already been cancelled.
349 PressTouchPoint(1, 1);
350 ReleaseTouchPoint(0);
351 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
352 EXPECT_FALSE(GesturesSent());
353 }
354
355 TEST_F(GestureEventQueueTest, TapCancelledWhenScrollBegins) {
356 PushGesture(WebInputEvent::GestureTapDown);
357 PressTouchPoint(1, 1);
358 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
359 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureTapDown),
360 GetAndResetSentGestures()));
361
362 // If the subsequent touch turns into a scroll, the tap should be cancelled.
363 PushGesture(WebInputEvent::GestureScrollBegin);
364 MoveTouchPoint(0, 2, 2);
365 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
366 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureTapCancel,
367 WebInputEvent::GestureScrollBegin),
368 GetAndResetSentGestures()));
369 }
370
371 TEST_F(GestureEventQueueTest, TapCancelledWhenTouchConsumed) {
372 PushGesture(WebInputEvent::GestureTapDown);
373 PressTouchPoint(1, 1);
374 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
375 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureTapDown),
376 GetAndResetSentGestures()));
377
378 // If the subsequent touch is consumed, the tap should be cancelled.
379 PushGesture(WebInputEvent::GestureScrollBegin);
380 MoveTouchPoint(0, 2, 2);
381 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
382 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureTapCancel),
383 GetAndResetSentGestures()));
384 }
385
386 TEST_F(GestureEventQueueTest, TapNotCancelledIfTapEndingEventReceived) {
387 PushGesture(WebInputEvent::GestureTapDown);
388 PressTouchPoint(1, 1);
389 PressTouchPoint(2, 2);
390 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
391 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
392 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureTapDown),
393 GetAndResetSentGestures()));
394
395 PushGesture(WebInputEvent::GestureTap);
396 ReleaseTouchPoint(1);
397 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
398 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureTap),
399 GetAndResetSentGestures()));
400
401 // The tap should not be cancelled as it was terminated by a |GestureTap|.
402 ReleaseTouchPoint(0);
403 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
404 EXPECT_FALSE(GesturesSent());
405 }
406
407 TEST_F(GestureEventQueueTest, TimeoutGestures) {
408 // If the sequence is allowed, and there are no preceding gestures, the
409 // timeout gestures should be forwarded immediately.
410 PressTouchPoint(1, 1);
411 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
412 EXPECT_FALSE(GesturesSent());
413
414 SendTimeoutGesture(WebInputEvent::GestureShowPress);
415 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureShowPress),
416 GetAndResetSentGestures()));
417
418 SendTimeoutGesture(WebInputEvent::GestureLongPress);
419 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureLongPress),
420 GetAndResetSentGestures()));
421
422 ReleaseTouchPoint(0);
423 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
424
425 // If the sequence is disallowed, and there are no preceding gestures, the
426 // timeout gestures should be dropped immediately.
427 PressTouchPoint(1, 1);
428 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
429 EXPECT_FALSE(GesturesSent());
430
431 SendTimeoutGesture(WebInputEvent::GestureShowPress);
432 EXPECT_FALSE(GesturesSent());
433 ReleaseTouchPoint(0);
434 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
435
436 // If the sequence has a pending ack, the timeout gestures should
437 // remain queued until the ack is received.
438 PressTouchPoint(1, 1);
439 EXPECT_FALSE(GesturesSent());
440
441 SendTimeoutGesture(WebInputEvent::GestureLongPress);
442 EXPECT_FALSE(GesturesSent());
443
444 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
445 EXPECT_TRUE(GesturesMatch(Gestures(WebInputEvent::GestureLongPress),
446 GetAndResetSentGestures()));
447 }
448
449 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/input/gesture_event_queue.cc ('k') | content/browser/renderer_host/render_widget_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698