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

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: Code 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 namespace {
20 const size_t kDefaultTouchTimeoutDelayMs = 10;
21 }
22
23 class GestureEventQueueTest : public testing::Test,
24 public GestureEventQueueClient {
25 public:
26 GestureEventQueueTest() : sent_gesture_count_(0) {}
27
28 virtual ~GestureEventQueueTest() {}
29
30 // testing::Test
31 virtual void SetUp() OVERRIDE {
32 queue_.reset(new GestureEventQueue(this));
33 }
34
35 virtual void TearDown() OVERRIDE {
36 queue_.reset();
37 }
38
39 // GestureEventQueueClient
40 virtual void ForwardGestureEvent(const WebGestureEvent& event) OVERRIDE {
41 ++sent_gesture_count_;
42 last_gesture_event_ = event;
43 }
44
45 protected:
46 typedef std::vector<WebGestureEvent> Gestures;
47
48 void SendTouchGestures() {
49 GestureEventPacket gesture_packet;
50 std::swap(gesture_packet, gesture_packet_);
51 SendTouchGestures(touch_event_, gesture_packet);
52 touch_event_.ResetPoints();
53 }
54
55 void SendTouchGestures(const WebTouchEvent& touch,
56 const GestureEventPacket& packet) {
57 GestureEventPacket touch_packet = GestureEventPacket::FromTouch(touch);
58 for (size_t i = 0; i < packet.gesture_count(); ++i)
59 touch_packet.Push(packet.gesture(i));
60 queue_->OnGestureEventPacket(touch_packet);
61 }
62
63 void SendGesture(GestureEventPacket::GestureSource source,
64 const WebGestureEvent& gesture) {
65 queue_->OnGestureEventPacket(
66 GestureEventPacket::FromGesture(source, gesture));
67 }
68
69 void SendTimeoutGesture(const WebGestureEvent& gesture) {
70 SendGesture(GestureEventPacket::TOUCH_TIMEOUT, gesture);
71 }
72
73 void SendSyntheticGesture(const WebGestureEvent& gesture) {
74 SendGesture(GestureEventPacket::SYNTHETIC, gesture);
75 }
76
77 void SendTouchEventACK(InputEventAckState ack_result) {
78 queue_->OnTouchEventAck(ack_result);
79 }
80
81 void PushGesture(const WebGestureEvent& gesture) {
82 gesture_packet_.Push(gesture);
83 }
84
85 void PushGesture(WebInputEvent::Type type) {
86 DCHECK(WebInputEvent::isGestureEventType(type));
87 PushGesture(CreateGesture(type));
88 }
89
90 void PressTouchPoint(int x, int y) {
91 touch_event_.PressPoint(x, y);
92 SendTouchGestures();
93 }
94
95 void MoveTouchPoint(int index, int x, int y) {
96 touch_event_.MovePoint(index, x, y);
97 SendTouchGestures();
98 }
99
100 void MoveTouchPoints(int index0, int x0, int y0, int index1, int x1, int y1) {
101 touch_event_.MovePoint(index0, x0, y0);
102 touch_event_.MovePoint(index1, x1, y1);
103 SendTouchGestures();
104 }
105
106 void ReleaseTouchPoint(int index) {
107 touch_event_.ReleasePoint(index);
108 SendTouchGestures();
109 }
110
111 void CancelTouchPoint(int index) {
112 touch_event_.CancelPoint(index);
113 SendTouchGestures();
114 }
115
116 size_t GetAndResetSentGestureCount() {
117 size_t count = sent_gesture_count_;
118 sent_gesture_count_ = 0;
119 return count;
120 }
121
122 const WebGestureEvent& sent_gesture() const {
123 return last_gesture_event_;
124 }
125
126 static WebGestureEvent CreateGesture(WebInputEvent::Type type) {
127 return SyntheticWebGestureEventBuilder::Build(
128 type, WebGestureEvent::Touchscreen);
129 }
130
131 private:
132
133 scoped_ptr<GestureEventQueue> queue_;
134 SyntheticWebTouchEvent touch_event_;
135 GestureEventPacket gesture_packet_;
136 size_t sent_gesture_count_;
137 WebTouchEvent last_touch_event_;
138 WebGestureEvent last_gesture_event_;
139 };
140
141 TEST_F(GestureEventQueueTest, BasicNoGestures) {
142 PressTouchPoint(1, 1);
143 EXPECT_EQ(0U, GetAndResetSentGestureCount());
144
145 // Touch events are always forwarded immediately.
146 MoveTouchPoint(0, 2, 2);
147 EXPECT_EQ(0U, GetAndResetSentGestureCount());
148
149 // No gestures should be dispatched by the ack, as none were queued.
150 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
151 EXPECT_EQ(0U, GetAndResetSentGestureCount());
152
153 // Release the touch gesture.
154 ReleaseTouchPoint(0);
155 EXPECT_EQ(0U, GetAndResetSentGestureCount());
156 }
157
158 TEST_F(GestureEventQueueTest, BasicGestures) {
159 // An unconsumed touch's gesture should be sent.
160 PushGesture(WebInputEvent::GestureScrollBegin);
161 PressTouchPoint(1, 1);
162 EXPECT_EQ(0U, GetAndResetSentGestureCount());
163 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
164 EXPECT_EQ(1U, GetAndResetSentGestureCount());
165 EXPECT_EQ(WebInputEvent::GestureScrollBegin, sent_gesture().type);
166
167 // Multiple gestures can be queued for a single event.
168 PushGesture(WebInputEvent::GestureFlingStart);
169 PushGesture(WebInputEvent::GestureFlingCancel);
170 MoveTouchPoint(0, 1, 1);
171 EXPECT_EQ(0U, GetAndResetSentGestureCount());
172 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
173 EXPECT_EQ(2U, GetAndResetSentGestureCount());
174 EXPECT_EQ(WebInputEvent::GestureFlingCancel, sent_gesture().type);
175
176 // A consumed touch's gesture should not be sent.
177 PushGesture(WebInputEvent::GestureFlingStart);
178 PushGesture(WebInputEvent::GestureFlingCancel);
179 ReleaseTouchPoint(0);
180 EXPECT_EQ(0U, GetAndResetSentGestureCount());
181 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
182 EXPECT_EQ(0U, GetAndResetSentGestureCount());
183 }
184
185 TEST_F(GestureEventQueueTest, ConsumedThenNotConsumed) {
186 // A consumed touch's gesture should not be sent.
187 PushGesture(WebInputEvent::GestureScrollBegin);
188 PressTouchPoint(1, 1);
189 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
190 EXPECT_EQ(0U, GetAndResetSentGestureCount());
191
192 // Event if the subsequent touch is not consumed, continue dropping gestures.
193 PushGesture(WebInputEvent::GestureScrollUpdate);
194 MoveTouchPoint(0, 2, 2);
195 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
196 EXPECT_EQ(0U, GetAndResetSentGestureCount());
197
198 // Event if the subsequent touch had no consumer, continue dropping gestures.
tdresser 2014/01/17 15:24:17 You mention touches having no consumer fairly freq
jdduke (slow) 2014/01/17 19:38:04 Yeah, I'll tighten up the verbiage here (though I
199 PushGesture(WebInputEvent::GestureFlingStart);
200 ReleaseTouchPoint(0);
201 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
202 EXPECT_EQ(0U, GetAndResetSentGestureCount());
203 }
204
205 TEST_F(GestureEventQueueTest, NotConsumedThenNoConsumer) {
206 // An unconsumed touch's gesture should be sent.
207 PushGesture(WebInputEvent::GestureScrollBegin);
208 PressTouchPoint(1, 1);
209 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
210 EXPECT_EQ(1U, GetAndResetSentGestureCount());
211
212 // If the subsequent touch has no consumer, send the gesture.
213 PushGesture(WebInputEvent::GestureScrollEnd);
214 MoveTouchPoint(0, 2, 2);
215 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
216 EXPECT_EQ(1U, GetAndResetSentGestureCount());
217
218 // Even if the subsequent touch was consumed, continue sending gestures.
219 PushGesture(WebInputEvent::GestureFlingStart);
220 PushGesture(WebInputEvent::GestureFlingCancel);
221 MoveTouchPoint(0, 2, 2);
222 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
tdresser 2014/01/17 15:24:17 Based on the comment, shouldn't this be INPUT_EVEN
jdduke (slow) 2014/01/17 19:38:04 Done.
223 EXPECT_EQ(2U, GetAndResetSentGestureCount());
224 }
225
226 TEST_F(GestureEventQueueTest, MultipleTouchSequences) {
227 // Queue two touch-to-gestures sequences.
228 PushGesture(WebInputEvent::GestureFlingStart);
229 PressTouchPoint(1, 1);
230 PushGesture(WebInputEvent::GestureFlingCancel);
231 ReleaseTouchPoint(0);
232 PushGesture(WebInputEvent::GestureFlingStart);
233 PressTouchPoint(1, 1);
234 PushGesture(WebInputEvent::GestureFlingCancel);
235 ReleaseTouchPoint(0);
236
237 // The first gesture sequence should not be allowed.
238 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
239 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
240 EXPECT_EQ(0U, GetAndResetSentGestureCount());
241
242 // The subsequent sequence should "reset" allowance.
243 // The first gesture sequence should not be allowed.
tdresser 2014/01/17 15:24:17 "The first gesture sequence should not be allowed.
jdduke (slow) 2014/01/17 19:38:04 Done.
244 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
245 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
246 EXPECT_EQ(2U, GetAndResetSentGestureCount());
247 }
248
249 TEST_F(GestureEventQueueTest, GestureFlingCancel) {}
250
251 TEST_F(GestureEventQueueTest, GestureTapCancel) {}
252
253 TEST_F(GestureEventQueueTest, TimeoutGestures) {
254 // If the sequence is allowed, and there are no preceding gestures, the
255 // timeout gestures should be forwarded immediately.
256 PressTouchPoint(1, 1);
257 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
258 EXPECT_EQ(0U, GetAndResetSentGestureCount());
259
260 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureShowPress));
261 EXPECT_EQ(1U, GetAndResetSentGestureCount());
262 EXPECT_EQ(WebInputEvent::GestureShowPress, sent_gesture().type);
263 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureLongPress));
264 EXPECT_EQ(1U, GetAndResetSentGestureCount());
265 EXPECT_EQ(WebInputEvent::GestureLongPress, sent_gesture().type);
266 ReleaseTouchPoint(0);
267 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
268
269 // If the sequence is disallowed, and there are no preceding gestures, the
270 // timeout gestures should be dropped immediately.
271 PressTouchPoint(1, 1);
272 SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
273 EXPECT_EQ(0U, GetAndResetSentGestureCount());
274
275 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureShowPress));
276 EXPECT_EQ(0U, GetAndResetSentGestureCount());
277 ReleaseTouchPoint(0);
278 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
279
280 // If the sequence has a pending ack, the timeout gestures should
281 // remain queued until the ack is received.
282 PressTouchPoint(1, 1);
283 EXPECT_EQ(0U, GetAndResetSentGestureCount());
284
285 SendTimeoutGesture(CreateGesture(WebInputEvent::GestureLongPress));
286 EXPECT_EQ(0U, GetAndResetSentGestureCount());
287
288 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
289 EXPECT_EQ(1U, GetAndResetSentGestureCount());
290 EXPECT_EQ(WebInputEvent::GestureLongPress, sent_gesture().type);
291 }
292
293 TEST_F(GestureEventQueueTest, SyntheticGestures) {
294 // Synthetic gestures without an associated touch event should be
295 // forwarded immediately if there are no preceding gestures.
296 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchBegin));
297 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchUpdate));
298 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchEnd));
299 EXPECT_EQ(3U, GetAndResetSentGestureCount());
300 EXPECT_EQ(WebInputEvent::GesturePinchEnd, sent_gesture().type);
301
302 // Queue a blocking touch gesture.
303 PushGesture(WebInputEvent::GestureFlingStart);
304 PressTouchPoint(1, 1);
305 ASSERT_EQ(0U, GetAndResetSentGestureCount());
306
307 // Subsequent synthetic events should only be forwarded after the
308 // touch-derived gesture has been dispatched.
309 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchBegin));
310 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchUpdate));
311 SendSyntheticGesture(CreateGesture(WebInputEvent::GesturePinchEnd));
312 EXPECT_EQ(0U, GetAndResetSentGestureCount());
313
314 // Dispatching the queued gesture should unblock the synthetic gestures.
315 SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
316 EXPECT_EQ(4U, GetAndResetSentGestureCount());
317 EXPECT_EQ(WebInputEvent::GesturePinchEnd, sent_gesture().type);
318 }
319
320 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698