OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 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 "content/renderer/gpu/input_handler_client_impl.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "content/renderer/gpu/input_handler_client_impl_client.h" | |
10 #include "testing/gmock/include/gmock/gmock.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" | |
13 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatSize.h" | |
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebGestureCurve.h" | |
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebInputHandler.h" | |
16 #include "third_party/WebKit/Source/Platform/chromium/public/WebPoint.h" | |
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | |
18 | |
19 using WebKit::WebActiveWheelFlingParameters; | |
20 using WebKit::WebFloatPoint; | |
21 using WebKit::WebFloatSize; | |
22 using WebKit::WebGestureEvent; | |
23 using WebKit::WebInputEvent; | |
24 using WebKit::WebPoint; | |
25 using WebKit::WebSize; | |
26 | |
27 namespace { | |
28 | |
29 class MockInputHandler : public cc::InputHandler { | |
30 public: | |
31 MockInputHandler() {} | |
32 virtual ~MockInputHandler() {} | |
33 | |
34 MOCK_METHOD0(PinchGestureBegin, void()); | |
35 MOCK_METHOD2(PinchGestureUpdate, | |
36 void(float magnify_delta, gfx::Point anchor)); | |
37 MOCK_METHOD0(PinchGestureEnd, void()); | |
38 | |
39 MOCK_METHOD0(ScheduleAnimation, void()); | |
40 | |
41 MOCK_METHOD2(ScrollBegin, | |
42 ScrollStatus(gfx::Point viewport_point, | |
43 cc::InputHandler::ScrollInputType type)); | |
44 MOCK_METHOD0(FlingScrollBegin, cc::InputHandler::ScrollStatus()); | |
45 MOCK_METHOD2(ScrollBy, bool(gfx::Point viewport_point, | |
46 gfx::Vector2dF scroll_delta)); | |
47 MOCK_METHOD2(ScrollVerticallyByPage, | |
48 bool(gfx::Point viewport_point, | |
49 WebKit::WebScrollbar::ScrollDirection direction)); | |
50 MOCK_METHOD0(ScrollEnd, void()); | |
51 | |
52 MOCK_METHOD1(DidReceiveLastInputEventForVSync, void(base::TimeTicks time)); | |
53 | |
54 virtual void BindToClient(cc::InputHandlerClient* clent) OVERRIDE {} | |
danakj
2013/05/01 19:20:43
should this be MOCK and verify it is called when y
| |
55 | |
56 virtual void StartPageScaleAnimation(gfx::Vector2d target_offset, | |
57 bool anchor_point, | |
58 float page_scale, | |
59 base::TimeTicks start_time, | |
60 base::TimeDelta duration) OVERRIDE {} | |
61 | |
62 virtual void NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) OVERRIDE {} | |
63 | |
64 virtual bool HaveTouchEventHandlersAt(gfx::Point point) OVERRIDE { | |
65 return false; | |
66 } | |
67 | |
68 DISALLOW_COPY_AND_ASSIGN(MockInputHandler); | |
69 }; | |
70 | |
71 // A simple WebGestureCurve implementation that flings at a constant velocity | |
72 // indefinitely. | |
73 class FakeWebGestureCurve : public WebKit::WebGestureCurve { | |
74 public: | |
75 FakeWebGestureCurve(const WebKit::WebFloatPoint& velocity, | |
76 const WebKit::WebSize& cumulative_scroll) | |
77 : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {} | |
78 | |
79 virtual ~FakeWebGestureCurve() {} | |
80 | |
81 // Returns false if curve has finished and can no longer be applied. | |
82 virtual bool apply(double time, WebKit::WebGestureCurveTarget* target) { | |
83 WebKit::WebSize displacement(velocity_.x * time, velocity_.y * time); | |
84 WebKit::WebFloatSize increment( | |
85 displacement.width - cumulative_scroll_.width, | |
86 displacement.height - cumulative_scroll_.height); | |
87 cumulative_scroll_ = displacement; | |
88 // scrollBy() could delete this curve if the animation is over, so don't | |
89 // touch any member variables after making that call. | |
90 target->scrollBy(increment); | |
91 return true; | |
92 } | |
93 | |
94 private: | |
95 WebKit::WebFloatPoint velocity_; | |
96 WebKit::WebSize cumulative_scroll_; | |
97 | |
98 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve); | |
99 }; | |
100 | |
101 class MockInputHandlerClientImplClient | |
102 : public content::InputHandlerClientImplClient { | |
103 public: | |
104 MockInputHandlerClientImplClient() {} | |
105 virtual ~MockInputHandlerClientImplClient() {} | |
106 | |
107 MOCK_METHOD0(willShutdown, void()); | |
108 MOCK_METHOD0(didHandleInputEvent, void()); | |
109 MOCK_METHOD1(didNotHandleInputEvent, void(bool send_to_widget)); | |
110 | |
111 MOCK_METHOD1(transferActiveWheelFlingAnimation, | |
112 void(const WebActiveWheelFlingParameters&)); | |
113 | |
114 virtual WebKit::WebGestureCurve* createFlingAnimationCurve( | |
115 int deviceSource, | |
116 const WebFloatPoint& velocity, | |
117 const WebSize& cumulative_scroll) OVERRIDE { | |
118 return new FakeWebGestureCurve(velocity, cumulative_scroll); | |
119 } | |
120 | |
121 private: | |
122 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerClientImplClient); | |
123 }; | |
124 | |
125 class InputHandlerClientImplTest : public testing::Test { | |
126 public: | |
127 InputHandlerClientImplTest() : expected_disposition_(DidHandle) { | |
128 input_handler_.reset( | |
129 new content::InputHandlerClientImpl(&mock_input_handler_)); | |
130 input_handler_->SetClient(&mock_client_); | |
131 } | |
132 | |
133 ~InputHandlerClientImplTest() { | |
134 input_handler_->SetClient(NULL); | |
135 input_handler_.reset(); | |
136 } | |
137 | |
138 // This is defined as a macro because when an expectation is not satisfied the | |
139 // only output you get | |
140 // out of gmock is the line number that set the expectation. | |
141 #define VERIFY_AND_RESET_MOCKS() \ | |
142 do { \ | |
143 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \ | |
144 testing::Mock::VerifyAndClearExpectations(&mock_client_); \ | |
145 switch (expected_disposition_) { \ | |
146 case DidHandle: \ | |
147 /* If we expect to handle events, we shouldn't get any */ \ | |
148 /* didNotHandleInputEvent() calls with any parameter. */ \ | |
149 EXPECT_CALL(mock_client_, didNotHandleInputEvent(::testing::_)) \ | |
150 .Times(0); \ | |
151 EXPECT_CALL(mock_client_, didHandleInputEvent()); \ | |
152 break; \ | |
153 case DidNotHandle: \ | |
154 /* If we aren't expecting to handle events, we shouldn't call */ \ | |
155 /* didHandleInputEvent(). */ \ | |
156 EXPECT_CALL(mock_client_, didHandleInputEvent()).Times(0); \ | |
157 EXPECT_CALL(mock_client_, didNotHandleInputEvent(false)).Times(0); \ | |
158 EXPECT_CALL(mock_client_, didNotHandleInputEvent(true)); \ | |
159 break; \ | |
160 case DropEvent: \ | |
161 /* If we're expecting to drop, we shouldn't get any didHandle..() */ \ | |
162 /* or didNotHandleInputEvent(true) calls. */ \ | |
163 EXPECT_CALL(mock_client_, didHandleInputEvent()).Times(0); \ | |
164 EXPECT_CALL(mock_client_, didNotHandleInputEvent(true)).Times(0); \ | |
165 EXPECT_CALL(mock_client_, didNotHandleInputEvent(false)); \ | |
166 break; \ | |
167 } \ | |
168 } while (0) | |
danakj
2013/05/01 19:20:43
s/0/false/
| |
169 | |
170 protected: | |
171 testing::StrictMock<MockInputHandler> mock_input_handler_; | |
172 scoped_ptr<content::InputHandlerClientImpl> input_handler_; | |
173 testing::StrictMock<MockInputHandlerClientImplClient> mock_client_; | |
174 WebGestureEvent gesture; | |
danakj
2013/05/01 19:20:43
gesture_
| |
175 | |
176 enum ExpectedDisposition { | |
177 DidHandle, | |
178 DidNotHandle, | |
179 DropEvent | |
180 }; | |
181 ExpectedDisposition expected_disposition_; | |
182 }; | |
183 | |
184 TEST_F(InputHandlerClientImplTest, GestureScrollStarted) { | |
185 // We shouldn't send any events to the widget for this gesture. | |
186 expected_disposition_ = DidHandle; | |
187 VERIFY_AND_RESET_MOCKS(); | |
188 | |
189 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
190 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
191 | |
192 gesture.type = WebInputEvent::GestureScrollBegin; | |
193 input_handler_->HandleInputEvent(gesture); | |
194 | |
195 // The event should not be marked as handled if scrolling is not possible. | |
196 expected_disposition_ = DropEvent; | |
197 VERIFY_AND_RESET_MOCKS(); | |
198 | |
199 gesture.type = WebInputEvent::GestureScrollUpdate; | |
200 gesture.data.scrollUpdate.deltaY = | |
201 -40; // -Y means scroll down - i.e. in the +Y direction. | |
202 EXPECT_CALL(mock_input_handler_, | |
203 ScrollBy(testing::_, | |
204 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
205 .WillOnce(testing::Return(false)); | |
206 input_handler_->HandleInputEvent(gesture); | |
207 | |
208 // Mark the event as handled if scroll happens. | |
209 expected_disposition_ = DidHandle; | |
210 VERIFY_AND_RESET_MOCKS(); | |
211 | |
212 gesture.type = WebInputEvent::GestureScrollUpdate; | |
213 gesture.data.scrollUpdate.deltaY = | |
214 -40; // -Y means scroll down - i.e. in the +Y direction. | |
215 EXPECT_CALL(mock_input_handler_, | |
216 ScrollBy(testing::_, | |
217 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
218 .WillOnce(testing::Return(true)); | |
219 input_handler_->HandleInputEvent(gesture); | |
220 | |
221 VERIFY_AND_RESET_MOCKS(); | |
222 | |
223 gesture.type = WebInputEvent::GestureScrollEnd; | |
224 gesture.data.scrollUpdate.deltaY = 0; | |
225 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
226 input_handler_->HandleInputEvent(gesture); | |
227 } | |
228 | |
229 TEST_F(InputHandlerClientImplTest, GestureScrollOnMainThread) { | |
230 // We should send all events to the widget for this gesture. | |
231 expected_disposition_ = DidNotHandle; | |
232 VERIFY_AND_RESET_MOCKS(); | |
233 | |
234 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) | |
235 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); | |
236 | |
237 gesture.type = WebInputEvent::GestureScrollBegin; | |
238 input_handler_->HandleInputEvent(gesture); | |
239 | |
240 VERIFY_AND_RESET_MOCKS(); | |
241 | |
242 gesture.type = WebInputEvent::GestureScrollUpdate; | |
243 gesture.data.scrollUpdate.deltaY = 40; | |
244 input_handler_->HandleInputEvent(gesture); | |
245 | |
246 VERIFY_AND_RESET_MOCKS(); | |
247 | |
248 gesture.type = WebInputEvent::GestureScrollEnd; | |
249 gesture.data.scrollUpdate.deltaY = 0; | |
250 input_handler_->HandleInputEvent(gesture); | |
251 } | |
252 | |
253 TEST_F(InputHandlerClientImplTest, GestureScrollIgnored) { | |
254 // We shouldn't handle the GestureScrollBegin. | |
255 // Instead, we should get one didNotHandleInputEvent(false) call per | |
256 // HandleInputEvent(), | |
257 // indicating that we could determine that there's nothing that could scroll | |
258 // or otherwise | |
259 // react to this gesture sequence and thus we should drop the whole gesture | |
260 // sequence on the floor. | |
261 expected_disposition_ = DropEvent; | |
262 VERIFY_AND_RESET_MOCKS(); | |
263 | |
264 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
265 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); | |
266 | |
267 gesture.type = WebInputEvent::GestureScrollBegin; | |
268 input_handler_->HandleInputEvent(gesture); | |
269 } | |
270 | |
271 TEST_F(InputHandlerClientImplTest, GesturePinch) { | |
272 // We shouldn't send any events to the widget for this gesture. | |
273 expected_disposition_ = DidHandle; | |
274 VERIFY_AND_RESET_MOCKS(); | |
275 | |
276 gesture.type = WebInputEvent::GesturePinchBegin; | |
277 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); | |
278 input_handler_->HandleInputEvent(gesture); | |
279 | |
280 VERIFY_AND_RESET_MOCKS(); | |
281 | |
282 gesture.type = WebInputEvent::GesturePinchUpdate; | |
283 gesture.data.pinchUpdate.scale = 1.5; | |
284 gesture.x = 7; | |
285 gesture.y = 13; | |
286 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); | |
287 input_handler_->HandleInputEvent(gesture); | |
288 | |
289 VERIFY_AND_RESET_MOCKS(); | |
290 | |
291 gesture.type = WebInputEvent::GesturePinchUpdate; | |
292 gesture.data.pinchUpdate.scale = 0.5; | |
293 gesture.x = 9; | |
294 gesture.y = 6; | |
295 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); | |
296 input_handler_->HandleInputEvent(gesture); | |
297 | |
298 VERIFY_AND_RESET_MOCKS(); | |
299 | |
300 gesture.type = WebInputEvent::GesturePinchEnd; | |
301 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); | |
302 input_handler_->HandleInputEvent(gesture); | |
303 } | |
304 | |
305 TEST_F(InputHandlerClientImplTest, GesturePinchAfterScrollOnMainThread) { | |
306 // Scrolls will start by being sent to the main thread. | |
307 expected_disposition_ = DidNotHandle; | |
308 VERIFY_AND_RESET_MOCKS(); | |
309 | |
310 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) | |
311 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); | |
312 | |
313 gesture.type = WebInputEvent::GestureScrollBegin; | |
314 input_handler_->HandleInputEvent(gesture); | |
315 | |
316 VERIFY_AND_RESET_MOCKS(); | |
317 | |
318 gesture.type = WebInputEvent::GestureScrollUpdate; | |
319 gesture.data.scrollUpdate.deltaY = 40; | |
320 input_handler_->HandleInputEvent(gesture); | |
321 | |
322 // However, after the pinch gesture starts, they should go to the impl | |
323 // thread. | |
324 expected_disposition_ = DidHandle; | |
325 VERIFY_AND_RESET_MOCKS(); | |
326 | |
327 gesture.type = WebInputEvent::GesturePinchBegin; | |
328 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); | |
329 input_handler_->HandleInputEvent(gesture); | |
330 | |
331 VERIFY_AND_RESET_MOCKS(); | |
332 | |
333 gesture.type = WebInputEvent::GesturePinchUpdate; | |
334 gesture.data.pinchUpdate.scale = 1.5; | |
335 gesture.x = 7; | |
336 gesture.y = 13; | |
337 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); | |
338 input_handler_->HandleInputEvent(gesture); | |
339 | |
340 VERIFY_AND_RESET_MOCKS(); | |
341 | |
342 gesture.type = WebInputEvent::GestureScrollUpdate; | |
343 gesture.data.scrollUpdate.deltaY = | |
344 -40; // -Y means scroll down - i.e. in the +Y direction. | |
345 EXPECT_CALL(mock_input_handler_, | |
346 ScrollBy(testing::_, | |
347 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
348 .WillOnce(testing::Return(true)); | |
349 input_handler_->HandleInputEvent(gesture); | |
350 | |
351 VERIFY_AND_RESET_MOCKS(); | |
352 | |
353 gesture.type = WebInputEvent::GesturePinchUpdate; | |
354 gesture.data.pinchUpdate.scale = 0.5; | |
355 gesture.x = 9; | |
356 gesture.y = 6; | |
357 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); | |
358 input_handler_->HandleInputEvent(gesture); | |
359 | |
360 VERIFY_AND_RESET_MOCKS(); | |
361 | |
362 gesture.type = WebInputEvent::GesturePinchEnd; | |
363 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); | |
364 input_handler_->HandleInputEvent(gesture); | |
365 | |
366 // After the pinch gesture ends, they should go to back to the main | |
367 // thread. | |
368 expected_disposition_ = DidNotHandle; | |
369 VERIFY_AND_RESET_MOCKS(); | |
370 | |
371 gesture.type = WebInputEvent::GestureScrollEnd; | |
372 gesture.data.scrollUpdate.deltaY = 0; | |
373 input_handler_->HandleInputEvent(gesture); | |
374 } | |
375 | |
376 TEST_F(InputHandlerClientImplTest, GestureFlingStartedTouchpad) { | |
377 // We shouldn't send any events to the widget for this gesture. | |
378 expected_disposition_ = DidHandle; | |
379 VERIFY_AND_RESET_MOCKS(); | |
380 | |
381 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
382 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
383 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
384 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
385 | |
386 gesture.type = WebInputEvent::GestureFlingStart; | |
387 gesture.data.flingStart.velocityX = 10; | |
388 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
389 input_handler_->HandleInputEvent(gesture); | |
390 | |
391 VERIFY_AND_RESET_MOCKS(); | |
392 | |
393 // Verify that a GestureFlingCancel during an animation cancels it. | |
394 gesture.type = WebInputEvent::GestureFlingCancel; | |
395 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
396 input_handler_->HandleInputEvent(gesture); | |
397 } | |
398 | |
399 TEST_F(InputHandlerClientImplTest, GestureFlingOnMainThreadTouchpad) { | |
400 // We should send all events to the widget for this gesture. | |
401 expected_disposition_ = DidNotHandle; | |
402 VERIFY_AND_RESET_MOCKS(); | |
403 | |
404 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
405 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); | |
406 | |
407 gesture.type = WebInputEvent::GestureFlingStart; | |
408 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
409 input_handler_->HandleInputEvent(gesture); | |
410 | |
411 VERIFY_AND_RESET_MOCKS(); | |
412 | |
413 // Even if we didn't start a fling ourselves, we still need to send the cancel | |
414 // event to the widget. | |
415 gesture.type = WebInputEvent::GestureFlingCancel; | |
416 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
417 input_handler_->HandleInputEvent(gesture); | |
418 } | |
419 | |
420 TEST_F(InputHandlerClientImplTest, GestureFlingIgnoredTouchpad) { | |
421 expected_disposition_ = DidNotHandle; | |
422 VERIFY_AND_RESET_MOCKS(); | |
423 | |
424 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
425 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); | |
426 | |
427 gesture.type = WebInputEvent::GestureFlingStart; | |
428 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
429 input_handler_->HandleInputEvent(gesture); | |
430 | |
431 expected_disposition_ = DropEvent; | |
432 VERIFY_AND_RESET_MOCKS(); | |
433 | |
434 // Since the previous fling was ignored, we should also be dropping the next | |
435 // fling_cancel. | |
436 gesture.type = WebInputEvent::GestureFlingCancel; | |
437 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
438 input_handler_->HandleInputEvent(gesture); | |
439 } | |
440 | |
441 TEST_F(InputHandlerClientImplTest, GestureFlingAnimatesTouchpad) { | |
442 // We shouldn't send any events to the widget for this gesture. | |
443 expected_disposition_ = DidHandle; | |
444 VERIFY_AND_RESET_MOCKS(); | |
445 | |
446 // On the fling start, we should schedule an animation but not actually start | |
447 // scrolling. | |
448 gesture.type = WebInputEvent::GestureFlingStart; | |
449 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
450 WebPoint fling_point = WebPoint(7, 13); | |
451 WebPoint fling_global_point = WebPoint(17, 23); | |
452 int modifiers = 7; | |
453 gesture.data.flingStart.velocityX = fling_delta.x; | |
454 gesture.data.flingStart.velocityY = fling_delta.y; | |
455 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
456 gesture.x = fling_point.x; | |
457 gesture.y = fling_point.y; | |
458 gesture.globalX = fling_global_point.x; | |
459 gesture.globalY = fling_global_point.y; | |
460 gesture.modifiers = modifiers; | |
461 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
462 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
463 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
464 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
465 input_handler_->HandleInputEvent(gesture); | |
466 | |
467 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
468 // The first animate call should let us pick up an animation start time, but | |
469 // we shouldn't actually move anywhere just yet. The first frame after the | |
470 // fling start will typically include the last scroll from the gesture that | |
471 // lead to the scroll (either wheel or gesture scroll), so there should be no | |
472 // visible hitch. | |
473 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
474 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
475 .Times(0); | |
476 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
477 input_handler_->Animate(time); | |
478 | |
479 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
480 | |
481 // The second call should start scrolling in the -X direction. | |
482 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
483 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
484 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
485 EXPECT_CALL(mock_input_handler_, | |
486 ScrollBy(testing::_, | |
487 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
488 .WillOnce(testing::Return(true)); | |
489 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
490 time += base::TimeDelta::FromMilliseconds(100); | |
491 input_handler_->Animate(time); | |
492 | |
493 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
494 | |
495 // Let's say on the third call we hit a non-scrollable region. We should abort | |
496 // the fling and not scroll. | |
497 // We also should pass the current fling parameters out to the client so the | |
498 // rest of the fling can be | |
499 // transferred to the main thread. | |
500 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
501 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
502 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); | |
503 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); | |
504 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); | |
505 // Expected wheel fling animation parameters: | |
506 // *) fling_delta and fling_point should match the original GestureFlingStart | |
507 // event | |
508 // *) startTime should be 10 to match the time parameter of the first | |
509 // Animate() call after the GestureFlingStart | |
510 // *) cumulativeScroll depends on the curve, but since we've animated in the | |
511 // -X direction the X value should be < 0 | |
512 EXPECT_CALL( | |
513 mock_client_, | |
514 transferActiveWheelFlingAnimation(testing::AllOf( | |
515 testing::Field(&WebActiveWheelFlingParameters::delta, | |
516 testing::Eq(fling_delta)), | |
517 testing::Field(&WebActiveWheelFlingParameters::point, | |
518 testing::Eq(fling_point)), | |
519 testing::Field(&WebActiveWheelFlingParameters::globalPoint, | |
520 testing::Eq(fling_global_point)), | |
521 testing::Field(&WebActiveWheelFlingParameters::modifiers, | |
522 testing::Eq(modifiers)), | |
523 testing::Field(&WebActiveWheelFlingParameters::startTime, | |
524 testing::Eq(10)), | |
525 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, | |
526 testing::Field(&WebSize::width, testing::Gt(0)))))); | |
527 time += base::TimeDelta::FromMilliseconds(100); | |
528 input_handler_->Animate(time); | |
529 | |
530 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
531 testing::Mock::VerifyAndClearExpectations(&mock_client_); | |
532 | |
533 // Since we've aborted the fling, the next animation should be a no-op and | |
534 // should not result in another | |
535 // frame being requested. | |
536 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0); | |
537 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
538 .Times(0); | |
539 time += base::TimeDelta::FromMilliseconds(100); | |
540 input_handler_->Animate(time); | |
541 | |
542 // Since we've transferred the fling to the main thread, we need to pass the | |
543 // next GestureFlingCancel to the main | |
544 // thread as well. | |
545 EXPECT_CALL(mock_client_, didNotHandleInputEvent(true)); | |
546 gesture.type = WebInputEvent::GestureFlingCancel; | |
547 input_handler_->HandleInputEvent(gesture); | |
548 } | |
549 | |
550 TEST_F(InputHandlerClientImplTest, GestureFlingTransferResetsTouchpad) { | |
551 // We shouldn't send any events to the widget for this gesture. | |
552 expected_disposition_ = DidHandle; | |
553 VERIFY_AND_RESET_MOCKS(); | |
554 | |
555 // Start a gesture fling in the -X direction with zero Y movement. | |
556 gesture.type = WebInputEvent::GestureFlingStart; | |
557 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
558 WebPoint fling_point = WebPoint(7, 13); | |
559 WebPoint fling_global_point = WebPoint(17, 23); | |
560 int modifiers = 1; | |
561 gesture.data.flingStart.velocityX = fling_delta.x; | |
562 gesture.data.flingStart.velocityY = fling_delta.y; | |
563 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
564 gesture.x = fling_point.x; | |
565 gesture.y = fling_point.y; | |
566 gesture.globalX = fling_global_point.x; | |
567 gesture.globalY = fling_global_point.y; | |
568 gesture.modifiers = modifiers; | |
569 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
570 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
571 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
572 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
573 input_handler_->HandleInputEvent(gesture); | |
574 | |
575 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
576 | |
577 // Start the fling animation at time 10. This shouldn't actually scroll, just | |
578 // establish a start time. | |
579 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
580 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
581 .Times(0); | |
582 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
583 input_handler_->Animate(time); | |
584 | |
585 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
586 | |
587 // The second call should start scrolling in the -X direction. | |
588 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
589 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
590 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
591 EXPECT_CALL(mock_input_handler_, | |
592 ScrollBy(testing::_, | |
593 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
594 .WillOnce(testing::Return(true)); | |
595 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
596 time += base::TimeDelta::FromMilliseconds(100); | |
597 input_handler_->Animate(time); | |
598 | |
599 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
600 | |
601 // Let's say on the third call we hit a non-scrollable region. We should abort | |
602 // the fling and not scroll. | |
603 // We also should pass the current fling parameters out to the client so the | |
604 // rest of the fling can be | |
605 // transferred to the main thread. | |
606 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
607 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
608 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); | |
609 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); | |
610 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); | |
611 | |
612 // Expected wheel fling animation parameters: | |
613 // *) fling_delta and fling_point should match the original GestureFlingStart | |
614 // event | |
615 // *) startTime should be 10 to match the time parameter of the first | |
616 // Animate() call after the GestureFlingStart | |
617 // *) cumulativeScroll depends on the curve, but since we've animated in the | |
618 // -X direction the X value should be < 0 | |
619 EXPECT_CALL( | |
620 mock_client_, | |
621 transferActiveWheelFlingAnimation(testing::AllOf( | |
622 testing::Field(&WebActiveWheelFlingParameters::delta, | |
623 testing::Eq(fling_delta)), | |
624 testing::Field(&WebActiveWheelFlingParameters::point, | |
625 testing::Eq(fling_point)), | |
626 testing::Field(&WebActiveWheelFlingParameters::globalPoint, | |
627 testing::Eq(fling_global_point)), | |
628 testing::Field(&WebActiveWheelFlingParameters::modifiers, | |
629 testing::Eq(modifiers)), | |
630 testing::Field(&WebActiveWheelFlingParameters::startTime, | |
631 testing::Eq(10)), | |
632 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, | |
633 testing::Field(&WebSize::width, testing::Gt(0)))))); | |
634 time += base::TimeDelta::FromMilliseconds(100); | |
635 input_handler_->Animate(time); | |
636 | |
637 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
638 testing::Mock::VerifyAndClearExpectations(&mock_client_); | |
639 | |
640 // Since we've aborted the fling, the next animation should be a no-op and | |
641 // should not result in another | |
642 // frame being requested. | |
643 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0); | |
644 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
645 .Times(0); | |
646 time += base::TimeDelta::FromMilliseconds(100); | |
647 input_handler_->Animate(time); | |
648 | |
649 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
650 | |
651 // Since we've transferred the fling to the main thread, we need to pass the | |
652 // next GestureFlingCancel to the main | |
653 // thread as well. | |
654 EXPECT_CALL(mock_client_, didNotHandleInputEvent(true)); | |
655 gesture.type = WebInputEvent::GestureFlingCancel; | |
656 input_handler_->HandleInputEvent(gesture); | |
657 | |
658 VERIFY_AND_RESET_MOCKS(); | |
659 input_handler_->MainThreadHasStoppedFlinging(); | |
660 | |
661 // Start a second gesture fling, this time in the +Y direction with no X. | |
662 gesture.type = WebInputEvent::GestureFlingStart; | |
663 fling_delta = WebFloatPoint(0, -1000); | |
664 fling_point = WebPoint(95, 87); | |
665 fling_global_point = WebPoint(32, 71); | |
666 modifiers = 2; | |
667 gesture.data.flingStart.velocityX = fling_delta.x; | |
668 gesture.data.flingStart.velocityY = fling_delta.y; | |
669 gesture.sourceDevice = WebGestureEvent::Touchpad; | |
670 gesture.x = fling_point.x; | |
671 gesture.y = fling_point.y; | |
672 gesture.globalX = fling_global_point.x; | |
673 gesture.globalY = fling_global_point.y; | |
674 gesture.modifiers = modifiers; | |
675 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
676 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
677 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
678 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
679 input_handler_->HandleInputEvent(gesture); | |
680 | |
681 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
682 | |
683 // Start the second fling animation at time 30. | |
684 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
685 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
686 .Times(0); | |
687 time = base::TimeTicks() + base::TimeDelta::FromSeconds(30); | |
688 input_handler_->Animate(time); | |
689 | |
690 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
691 | |
692 // Tick the second fling once normally. | |
693 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
694 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
695 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
696 EXPECT_CALL(mock_input_handler_, | |
697 ScrollBy(testing::_, | |
698 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
699 .WillOnce(testing::Return(true)); | |
700 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
701 time += base::TimeDelta::FromMilliseconds(100); | |
702 input_handler_->Animate(time); | |
703 | |
704 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
705 | |
706 // Then abort the second fling. | |
707 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
708 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
709 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); | |
710 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); | |
711 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); | |
712 | |
713 // We should get parameters from the second fling, nothing from the first | |
714 // fling should "leak". | |
715 EXPECT_CALL( | |
716 mock_client_, | |
717 transferActiveWheelFlingAnimation(testing::AllOf( | |
718 testing::Field(&WebActiveWheelFlingParameters::delta, | |
719 testing::Eq(fling_delta)), | |
720 testing::Field(&WebActiveWheelFlingParameters::point, | |
721 testing::Eq(fling_point)), | |
722 testing::Field(&WebActiveWheelFlingParameters::globalPoint, | |
723 testing::Eq(fling_global_point)), | |
724 testing::Field(&WebActiveWheelFlingParameters::modifiers, | |
725 testing::Eq(modifiers)), | |
726 testing::Field(&WebActiveWheelFlingParameters::startTime, | |
727 testing::Eq(30)), | |
728 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, | |
729 testing::Field(&WebSize::height, testing::Lt(0)))))); | |
730 time += base::TimeDelta::FromMilliseconds(100); | |
731 input_handler_->Animate(time); | |
732 } | |
733 | |
734 TEST_F(InputHandlerClientImplTest, GestureFlingStartedTouchscreen) { | |
735 // We shouldn't send any events to the widget for this gesture. | |
736 expected_disposition_ = DidHandle; | |
737 VERIFY_AND_RESET_MOCKS(); | |
738 | |
739 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
740 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
741 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
742 | |
743 gesture.type = WebInputEvent::GestureFlingStart; | |
744 gesture.data.flingStart.velocityX = 10; | |
745 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
746 input_handler_->HandleInputEvent(gesture); | |
747 | |
748 VERIFY_AND_RESET_MOCKS(); | |
749 | |
750 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
751 | |
752 // Verify that a GestureFlingCancel during an animation cancels it. | |
753 gesture.type = WebInputEvent::GestureFlingCancel; | |
754 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
755 input_handler_->HandleInputEvent(gesture); | |
756 } | |
757 | |
758 TEST_F(InputHandlerClientImplTest, GestureFlingOnMainThreadTouchscreen) { | |
759 // We should send all events to the widget for this gesture. | |
760 expected_disposition_ = DidNotHandle; | |
761 VERIFY_AND_RESET_MOCKS(); | |
762 | |
763 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
764 .WillOnce(testing::Return(cc::InputHandler::ScrollOnMainThread)); | |
765 | |
766 gesture.type = WebInputEvent::GestureFlingStart; | |
767 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
768 input_handler_->HandleInputEvent(gesture); | |
769 | |
770 VERIFY_AND_RESET_MOCKS(); | |
771 | |
772 // Even if we didn't start a fling ourselves, we still need to send the cancel | |
773 // event to the widget. | |
774 gesture.type = WebInputEvent::GestureFlingCancel; | |
775 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
776 input_handler_->HandleInputEvent(gesture); | |
777 } | |
778 | |
779 TEST_F(InputHandlerClientImplTest, GestureFlingIgnoredTouchscreen) { | |
780 expected_disposition_ = DropEvent; | |
781 VERIFY_AND_RESET_MOCKS(); | |
782 | |
783 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
784 .WillOnce(testing::Return(cc::InputHandler::ScrollIgnored)); | |
785 | |
786 gesture.type = WebInputEvent::GestureFlingStart; | |
787 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
788 input_handler_->HandleInputEvent(gesture); | |
789 | |
790 VERIFY_AND_RESET_MOCKS(); | |
791 | |
792 // Even if we didn't start a fling ourselves, we still need to send the cancel | |
793 // event to the widget. | |
794 gesture.type = WebInputEvent::GestureFlingCancel; | |
795 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
796 input_handler_->HandleInputEvent(gesture); | |
797 } | |
798 | |
799 TEST_F(InputHandlerClientImplTest, GestureFlingAnimatesTouchscreen) { | |
800 // We shouldn't send any events to the widget for this gesture. | |
801 expected_disposition_ = DidHandle; | |
802 VERIFY_AND_RESET_MOCKS(); | |
803 | |
804 // On the fling start, we should schedule an animation but not actually start | |
805 // scrolling. | |
806 gesture.type = WebInputEvent::GestureFlingStart; | |
807 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
808 WebPoint fling_point = WebPoint(7, 13); | |
809 WebPoint fling_global_point = WebPoint(17, 23); | |
810 int modifiers = 7; | |
811 gesture.data.flingStart.velocityX = fling_delta.x; | |
812 gesture.data.flingStart.velocityY = fling_delta.y; | |
813 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
814 gesture.x = fling_point.x; | |
815 gesture.y = fling_point.y; | |
816 gesture.globalX = fling_global_point.x; | |
817 gesture.globalY = fling_global_point.y; | |
818 gesture.modifiers = modifiers; | |
819 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
820 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
821 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
822 input_handler_->HandleInputEvent(gesture); | |
823 | |
824 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
825 // The first animate call should let us pick up an animation start time, but | |
826 // we | |
827 // shouldn't actually move anywhere just yet. The first frame after the fling | |
828 // start | |
829 // will typically include the last scroll from the gesture that lead to the | |
830 // scroll | |
831 // (either wheel or gesture scroll), so there should be no visible hitch. | |
832 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
833 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
834 input_handler_->Animate(time); | |
835 | |
836 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
837 | |
838 // The second call should start scrolling in the -X direction. | |
839 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
840 EXPECT_CALL(mock_input_handler_, | |
841 ScrollBy(testing::_, | |
842 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
843 .WillOnce(testing::Return(true)); | |
844 time += base::TimeDelta::FromMilliseconds(100); | |
845 input_handler_->Animate(time); | |
846 | |
847 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
848 | |
849 EXPECT_CALL(mock_client_, didHandleInputEvent()); | |
850 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
851 gesture.type = WebInputEvent::GestureFlingCancel; | |
852 input_handler_->HandleInputEvent(gesture); | |
853 } | |
854 | |
855 TEST_F(InputHandlerClientImplTest, | |
856 GestureScrollOnImplThreadFlagClearedAfterFling) { | |
857 // We shouldn't send any events to the widget for this gesture. | |
858 expected_disposition_ = DidHandle; | |
859 VERIFY_AND_RESET_MOCKS(); | |
860 | |
861 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
862 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
863 | |
864 gesture.type = WebInputEvent::GestureScrollBegin; | |
865 input_handler_->HandleInputEvent(gesture); | |
866 | |
867 // After sending a GestureScrollBegin, the member variable | |
868 // |gesture_scroll_on_impl_thread_| should be true. | |
869 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread()); | |
870 | |
871 expected_disposition_ = DidHandle; | |
872 VERIFY_AND_RESET_MOCKS(); | |
873 | |
874 // On the fling start, we should schedule an animation but not actually start | |
875 // scrolling. | |
876 gesture.type = WebInputEvent::GestureFlingStart; | |
877 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
878 WebPoint fling_point = WebPoint(7, 13); | |
879 WebPoint fling_global_point = WebPoint(17, 23); | |
880 int modifiers = 7; | |
881 gesture.data.flingStart.velocityX = fling_delta.x; | |
882 gesture.data.flingStart.velocityY = fling_delta.y; | |
883 gesture.sourceDevice = WebGestureEvent::Touchscreen; | |
884 gesture.x = fling_point.x; | |
885 gesture.y = fling_point.y; | |
886 gesture.globalX = fling_global_point.x; | |
887 gesture.globalY = fling_global_point.y; | |
888 gesture.modifiers = modifiers; | |
889 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
890 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
891 .WillOnce(testing::Return(cc::InputHandler::ScrollStarted)); | |
892 input_handler_->HandleInputEvent(gesture); | |
893 | |
894 // |gesture_scroll_on_impl_thread_| should still be true after | |
895 // a GestureFlingStart is sent. | |
896 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread()); | |
897 | |
898 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
899 // The first animate call should let us pick up an animation start time, but | |
900 // we | |
901 // shouldn't actually move anywhere just yet. The first frame after the fling | |
902 // start | |
903 // will typically include the last scroll from the gesture that lead to the | |
904 // scroll | |
905 // (either wheel or gesture scroll), so there should be no visible hitch. | |
906 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
907 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
908 input_handler_->Animate(time); | |
909 | |
910 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
911 | |
912 // The second call should start scrolling in the -X direction. | |
913 EXPECT_CALL(mock_input_handler_, ScheduleAnimation()); | |
914 EXPECT_CALL(mock_input_handler_, | |
915 ScrollBy(testing::_, | |
916 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
917 .WillOnce(testing::Return(true)); | |
918 time += base::TimeDelta::FromMilliseconds(100); | |
919 input_handler_->Animate(time); | |
920 | |
921 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); | |
922 | |
923 EXPECT_CALL(mock_client_, didHandleInputEvent()); | |
924 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
925 gesture.type = WebInputEvent::GestureFlingCancel; | |
926 input_handler_->HandleInputEvent(gesture); | |
927 | |
928 // |gesture_scroll_on_impl_thread_| should be false once | |
929 // the fling has finished (note no GestureScrollEnd has been sent). | |
930 EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread()); | |
931 } | |
932 | |
933 TEST_F(InputHandlerClientImplTest, LastInputEventForVSync) { | |
934 expected_disposition_ = DropEvent; | |
935 VERIFY_AND_RESET_MOCKS(); | |
936 | |
937 gesture.type = WebInputEvent::GestureFlingCancel; | |
938 gesture.timeStampSeconds = 1234; | |
939 base::TimeTicks time = base::TimeTicks() + | |
940 base::TimeDelta::FromSeconds(gesture.timeStampSeconds); | |
941 gesture.modifiers |= WebInputEvent::IsLastInputEventForCurrentVSync; | |
942 EXPECT_CALL(mock_input_handler_, DidReceiveLastInputEventForVSync(time)); | |
943 input_handler_->HandleInputEvent(gesture); | |
944 } | |
945 | |
946 } // namespace | |
OLD | NEW |