OLD | NEW |
| (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 "content/renderer/input/input_handler_proxy.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "cc/trees/swap_promise_monitor.h" | |
10 #include "content/common/input/did_overscroll_params.h" | |
11 #include "content/renderer/input/input_handler_proxy_client.h" | |
12 #include "testing/gmock/include/gmock/gmock.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 #include "third_party/WebKit/public/platform/WebFloatPoint.h" | |
15 #include "third_party/WebKit/public/platform/WebFloatSize.h" | |
16 #include "third_party/WebKit/public/platform/WebGestureCurve.h" | |
17 #include "third_party/WebKit/public/platform/WebPoint.h" | |
18 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
19 #include "ui/events/latency_info.h" | |
20 #include "ui/gfx/geometry/scroll_offset.h" | |
21 #include "ui/gfx/geometry/size_f.h" | |
22 | |
23 using blink::WebActiveWheelFlingParameters; | |
24 using blink::WebFloatPoint; | |
25 using blink::WebFloatSize; | |
26 using blink::WebGestureDevice; | |
27 using blink::WebGestureEvent; | |
28 using blink::WebInputEvent; | |
29 using blink::WebKeyboardEvent; | |
30 using blink::WebMouseWheelEvent; | |
31 using blink::WebPoint; | |
32 using blink::WebSize; | |
33 using blink::WebTouchEvent; | |
34 using blink::WebTouchPoint; | |
35 using testing::Field; | |
36 | |
37 namespace content { | |
38 namespace test { | |
39 | |
40 namespace { | |
41 | |
42 enum InputHandlerProxyTestType { | |
43 ROOT_SCROLL_NORMAL_HANDLER, | |
44 ROOT_SCROLL_SYNCHRONOUS_HANDLER, | |
45 CHILD_SCROLL_NORMAL_HANDLER, | |
46 CHILD_SCROLL_SYNCHRONOUS_HANDLER, | |
47 }; | |
48 static const InputHandlerProxyTestType test_types[] = { | |
49 ROOT_SCROLL_NORMAL_HANDLER, ROOT_SCROLL_SYNCHRONOUS_HANDLER, | |
50 CHILD_SCROLL_NORMAL_HANDLER, CHILD_SCROLL_SYNCHRONOUS_HANDLER}; | |
51 | |
52 double InSecondsF(const base::TimeTicks& time) { | |
53 return (time - base::TimeTicks()).InSecondsF(); | |
54 } | |
55 | |
56 WebGestureEvent CreateFling(base::TimeTicks timestamp, | |
57 WebGestureDevice source_device, | |
58 WebFloatPoint velocity, | |
59 WebPoint point, | |
60 WebPoint global_point, | |
61 int modifiers) { | |
62 WebGestureEvent fling; | |
63 fling.type = WebInputEvent::GestureFlingStart; | |
64 fling.sourceDevice = source_device; | |
65 fling.timeStampSeconds = (timestamp - base::TimeTicks()).InSecondsF(); | |
66 fling.data.flingStart.velocityX = velocity.x; | |
67 fling.data.flingStart.velocityY = velocity.y; | |
68 fling.x = point.x; | |
69 fling.y = point.y; | |
70 fling.globalX = global_point.x; | |
71 fling.globalY = global_point.y; | |
72 fling.modifiers = modifiers; | |
73 return fling; | |
74 } | |
75 | |
76 WebGestureEvent CreateFling(WebGestureDevice source_device, | |
77 WebFloatPoint velocity, | |
78 WebPoint point, | |
79 WebPoint global_point, | |
80 int modifiers) { | |
81 return CreateFling(base::TimeTicks(), | |
82 source_device, | |
83 velocity, | |
84 point, | |
85 global_point, | |
86 modifiers); | |
87 } | |
88 | |
89 class MockInputHandler : public cc::InputHandler { | |
90 public: | |
91 MockInputHandler() {} | |
92 ~MockInputHandler() override {} | |
93 | |
94 MOCK_METHOD0(PinchGestureBegin, void()); | |
95 MOCK_METHOD2(PinchGestureUpdate, | |
96 void(float magnify_delta, const gfx::Point& anchor)); | |
97 MOCK_METHOD0(PinchGestureEnd, void()); | |
98 | |
99 MOCK_METHOD0(SetNeedsAnimateInput, void()); | |
100 | |
101 MOCK_METHOD2(ScrollBegin, | |
102 ScrollStatus(const gfx::Point& viewport_point, | |
103 cc::InputHandler::ScrollInputType type)); | |
104 MOCK_METHOD1(RootScrollBegin, | |
105 ScrollStatus(cc::InputHandler::ScrollInputType type)); | |
106 MOCK_METHOD2(ScrollAnimated, | |
107 ScrollStatus(const gfx::Point& viewport_point, | |
108 const gfx::Vector2dF& scroll_delta)); | |
109 MOCK_METHOD2(ScrollBy, | |
110 cc::InputHandlerScrollResult( | |
111 const gfx::Point& viewport_point, | |
112 const gfx::Vector2dF& scroll_delta)); | |
113 MOCK_METHOD2(ScrollVerticallyByPage, | |
114 bool(const gfx::Point& viewport_point, | |
115 cc::ScrollDirection direction)); | |
116 MOCK_METHOD0(ScrollEnd, void()); | |
117 MOCK_METHOD0(FlingScrollBegin, cc::InputHandler::ScrollStatus()); | |
118 | |
119 scoped_ptr<cc::SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( | |
120 ui::LatencyInfo* latency) override { | |
121 return scoped_ptr<cc::SwapPromiseMonitor>(); | |
122 } | |
123 | |
124 cc::ScrollElasticityHelper* CreateScrollElasticityHelper() override { | |
125 return NULL; | |
126 } | |
127 | |
128 void BindToClient(cc::InputHandlerClient* client) override {} | |
129 | |
130 void MouseMoveAt(const gfx::Point& mouse_position) override {} | |
131 | |
132 MOCK_CONST_METHOD2(IsCurrentlyScrollingLayerAt, | |
133 bool(const gfx::Point& point, | |
134 cc::InputHandler::ScrollInputType type)); | |
135 | |
136 MOCK_METHOD1(HaveWheelEventHandlersAt, bool(const gfx::Point& point)); | |
137 MOCK_METHOD1(DoTouchEventsBlockScrollAt, bool(const gfx::Point& point)); | |
138 | |
139 MOCK_METHOD0(RequestUpdateForSynchronousInputHandler, void()); | |
140 MOCK_METHOD1(SetSynchronousInputHandlerRootScrollOffset, | |
141 void(const gfx::ScrollOffset& root_offset)); | |
142 | |
143 bool IsCurrentlyScrollingInnerViewport() const override { | |
144 return is_scrolling_root_; | |
145 } | |
146 void set_is_scrolling_root(bool is) { is_scrolling_root_ = is; } | |
147 | |
148 private: | |
149 bool is_scrolling_root_ = true; | |
150 DISALLOW_COPY_AND_ASSIGN(MockInputHandler); | |
151 }; | |
152 | |
153 class MockSynchronousInputHandler : public content::SynchronousInputHandler { | |
154 public: | |
155 MOCK_METHOD0(SetNeedsSynchronousAnimateInput, void()); | |
156 MOCK_METHOD6(UpdateRootLayerState, | |
157 void(const gfx::ScrollOffset& total_scroll_offset, | |
158 const gfx::ScrollOffset& max_scroll_offset, | |
159 const gfx::SizeF& scrollable_size, | |
160 float page_scale_factor, | |
161 float min_page_scale_factor, | |
162 float max_page_scale_factor)); | |
163 }; | |
164 | |
165 // A simple WebGestureCurve implementation that flings at a constant velocity | |
166 // indefinitely. | |
167 class FakeWebGestureCurve : public blink::WebGestureCurve { | |
168 public: | |
169 FakeWebGestureCurve(const blink::WebFloatSize& velocity, | |
170 const blink::WebFloatSize& cumulative_scroll) | |
171 : velocity_(velocity), cumulative_scroll_(cumulative_scroll) {} | |
172 | |
173 ~FakeWebGestureCurve() override {} | |
174 | |
175 // Returns false if curve has finished and can no longer be applied. | |
176 bool apply(double time, blink::WebGestureCurveTarget* target) override { | |
177 blink::WebFloatSize displacement(velocity_.width * time, | |
178 velocity_.height * time); | |
179 blink::WebFloatSize increment( | |
180 displacement.width - cumulative_scroll_.width, | |
181 displacement.height - cumulative_scroll_.height); | |
182 cumulative_scroll_ = displacement; | |
183 // scrollBy() could delete this curve if the animation is over, so don't | |
184 // touch any member variables after making that call. | |
185 return target->scrollBy(increment, velocity_); | |
186 } | |
187 | |
188 private: | |
189 blink::WebFloatSize velocity_; | |
190 blink::WebFloatSize cumulative_scroll_; | |
191 | |
192 DISALLOW_COPY_AND_ASSIGN(FakeWebGestureCurve); | |
193 }; | |
194 | |
195 class MockInputHandlerProxyClient | |
196 : public content::InputHandlerProxyClient { | |
197 public: | |
198 MockInputHandlerProxyClient() {} | |
199 ~MockInputHandlerProxyClient() override {} | |
200 | |
201 void WillShutdown() override {} | |
202 | |
203 MOCK_METHOD1(TransferActiveWheelFlingAnimation, | |
204 void(const WebActiveWheelFlingParameters&)); | |
205 | |
206 blink::WebGestureCurve* CreateFlingAnimationCurve( | |
207 WebGestureDevice deviceSource, | |
208 const WebFloatPoint& velocity, | |
209 const WebSize& cumulative_scroll) override { | |
210 return new FakeWebGestureCurve( | |
211 blink::WebFloatSize(velocity.x, velocity.y), | |
212 blink::WebFloatSize(cumulative_scroll.width, cumulative_scroll.height)); | |
213 } | |
214 | |
215 MOCK_METHOD1(DidOverscroll, void(const DidOverscrollParams&)); | |
216 void DidStopFlinging() override {} | |
217 void DidAnimateForInput() override {} | |
218 | |
219 private: | |
220 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClient); | |
221 }; | |
222 | |
223 class MockInputHandlerProxyClientWithDidAnimateForInput | |
224 : public MockInputHandlerProxyClient { | |
225 public: | |
226 MockInputHandlerProxyClientWithDidAnimateForInput() {} | |
227 ~MockInputHandlerProxyClientWithDidAnimateForInput() override {} | |
228 | |
229 MOCK_METHOD0(DidAnimateForInput, void()); | |
230 | |
231 private: | |
232 DISALLOW_COPY_AND_ASSIGN(MockInputHandlerProxyClientWithDidAnimateForInput); | |
233 }; | |
234 | |
235 WebTouchPoint CreateWebTouchPoint(WebTouchPoint::State state, float x, | |
236 float y) { | |
237 WebTouchPoint point; | |
238 point.state = state; | |
239 point.screenPosition = WebFloatPoint(x, y); | |
240 point.position = WebFloatPoint(x, y); | |
241 return point; | |
242 } | |
243 | |
244 } // namespace | |
245 | |
246 class InputHandlerProxyTest | |
247 : public testing::Test, | |
248 public testing::WithParamInterface<InputHandlerProxyTestType> { | |
249 public: | |
250 InputHandlerProxyTest() | |
251 : synchronous_root_scroll_(GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER), | |
252 install_synchronous_handler_( | |
253 GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER || | |
254 GetParam() == CHILD_SCROLL_SYNCHRONOUS_HANDLER), | |
255 expected_disposition_(InputHandlerProxy::DID_HANDLE) { | |
256 input_handler_.reset( | |
257 new content::InputHandlerProxy(&mock_input_handler_, &mock_client_)); | |
258 scroll_result_did_scroll_.did_scroll = true; | |
259 scroll_result_did_not_scroll_.did_scroll = false; | |
260 | |
261 if (install_synchronous_handler_) { | |
262 EXPECT_CALL(mock_input_handler_, | |
263 RequestUpdateForSynchronousInputHandler()) | |
264 .Times(1); | |
265 input_handler_->SetOnlySynchronouslyAnimateRootFlings( | |
266 &mock_synchronous_input_handler_); | |
267 } | |
268 | |
269 mock_input_handler_.set_is_scrolling_root(synchronous_root_scroll_); | |
270 | |
271 // Set a default device so tests don't always have to set this. | |
272 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; | |
273 } | |
274 | |
275 ~InputHandlerProxyTest() { | |
276 input_handler_.reset(); | |
277 } | |
278 | |
279 // This is defined as a macro so the line numbers can be traced back to the | |
280 // correct spot when it fails. | |
281 #define EXPECT_SET_NEEDS_ANIMATE_INPUT(times) \ | |
282 do { \ | |
283 if (synchronous_root_scroll_) { \ | |
284 EXPECT_CALL(mock_synchronous_input_handler_, \ | |
285 SetNeedsSynchronousAnimateInput()) \ | |
286 .Times(times); \ | |
287 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(0); \ | |
288 } else { \ | |
289 EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(times); \ | |
290 EXPECT_CALL(mock_synchronous_input_handler_, \ | |
291 SetNeedsSynchronousAnimateInput()) \ | |
292 .Times(0); \ | |
293 } \ | |
294 } while (false) | |
295 | |
296 // This is defined as a macro because when an expectation is not satisfied the | |
297 // only output you get out of gmock is the line number that set the expectation. | |
298 #define VERIFY_AND_RESET_MOCKS() \ | |
299 do { \ | |
300 testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); \ | |
301 testing::Mock::VerifyAndClearExpectations( \ | |
302 &mock_synchronous_input_handler_); \ | |
303 testing::Mock::VerifyAndClearExpectations(&mock_client_); \ | |
304 } while (false) | |
305 | |
306 void Animate(base::TimeTicks time) { | |
307 if (synchronous_root_scroll_) { | |
308 input_handler_->SynchronouslyAnimate(time); | |
309 } else { | |
310 input_handler_->Animate(time); | |
311 } | |
312 } | |
313 | |
314 void StartFling(base::TimeTicks timestamp, | |
315 WebGestureDevice source_device, | |
316 WebFloatPoint velocity, | |
317 WebPoint position) { | |
318 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
319 VERIFY_AND_RESET_MOCKS(); | |
320 | |
321 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
322 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
323 gesture_.type = WebInputEvent::GestureScrollBegin; | |
324 gesture_.sourceDevice = source_device; | |
325 EXPECT_EQ(expected_disposition_, | |
326 input_handler_->HandleInputEvent(gesture_)); | |
327 | |
328 VERIFY_AND_RESET_MOCKS(); | |
329 | |
330 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
331 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
332 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
333 | |
334 gesture_ = | |
335 CreateFling(timestamp, source_device, velocity, position, position, 0); | |
336 EXPECT_EQ(expected_disposition_, | |
337 input_handler_->HandleInputEvent(gesture_)); | |
338 | |
339 VERIFY_AND_RESET_MOCKS(); | |
340 } | |
341 | |
342 void CancelFling(base::TimeTicks timestamp) { | |
343 gesture_.timeStampSeconds = InSecondsF(timestamp); | |
344 gesture_.type = WebInputEvent::GestureFlingCancel; | |
345 EXPECT_EQ(expected_disposition_, | |
346 input_handler_->HandleInputEvent(gesture_)); | |
347 | |
348 VERIFY_AND_RESET_MOCKS(); | |
349 } | |
350 | |
351 void SetSmoothScrollEnabled(bool value) { | |
352 input_handler_->smooth_scroll_enabled_ = value; | |
353 } | |
354 | |
355 protected: | |
356 const bool synchronous_root_scroll_; | |
357 const bool install_synchronous_handler_; | |
358 testing::StrictMock<MockInputHandler> mock_input_handler_; | |
359 testing::StrictMock<MockSynchronousInputHandler> | |
360 mock_synchronous_input_handler_; | |
361 scoped_ptr<content::InputHandlerProxy> input_handler_; | |
362 testing::StrictMock<MockInputHandlerProxyClient> mock_client_; | |
363 WebGestureEvent gesture_; | |
364 InputHandlerProxy::EventDisposition expected_disposition_; | |
365 cc::InputHandlerScrollResult scroll_result_did_scroll_; | |
366 cc::InputHandlerScrollResult scroll_result_did_not_scroll_; | |
367 }; | |
368 | |
369 TEST_P(InputHandlerProxyTest, MouseWheelByPageMainThread) { | |
370 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
371 WebMouseWheelEvent wheel; | |
372 wheel.type = WebInputEvent::MouseWheel; | |
373 wheel.scrollByPage = true; | |
374 | |
375 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); | |
376 VERIFY_AND_RESET_MOCKS(); | |
377 } | |
378 | |
379 TEST_P(InputHandlerProxyTest, MouseWheelWithCtrlNotScroll) { | |
380 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
381 WebMouseWheelEvent wheel; | |
382 wheel.type = WebInputEvent::MouseWheel; | |
383 wheel.modifiers = WebInputEvent::ControlKey; | |
384 wheel.canScroll = false; | |
385 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); | |
386 VERIFY_AND_RESET_MOCKS(); | |
387 } | |
388 | |
389 TEST_P(InputHandlerProxyTest, MouseWheelWithPreciseScrollingDeltas) { | |
390 SetSmoothScrollEnabled(true); | |
391 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
392 WebMouseWheelEvent wheel; | |
393 wheel.type = WebInputEvent::MouseWheel; | |
394 | |
395 VERIFY_AND_RESET_MOCKS(); | |
396 | |
397 // Smooth scroll because hasPreciseScrollingDeltas is set to false. | |
398 wheel.hasPreciseScrollingDeltas = false; | |
399 EXPECT_CALL(mock_input_handler_, ScrollAnimated(::testing::_, ::testing::_)) | |
400 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
401 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); | |
402 | |
403 VERIFY_AND_RESET_MOCKS(); | |
404 | |
405 // No smooth scroll because hasPreciseScrollingDeltas is set to true. | |
406 wheel.hasPreciseScrollingDeltas = true; | |
407 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) | |
408 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
409 EXPECT_CALL(mock_input_handler_, ScrollBy(::testing::_, ::testing::_)) | |
410 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
411 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
412 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); | |
413 | |
414 VERIFY_AND_RESET_MOCKS(); | |
415 } | |
416 | |
417 TEST_P(InputHandlerProxyTest, MouseWheelScrollIgnored) { | |
418 SetSmoothScrollEnabled(true); | |
419 expected_disposition_ = InputHandlerProxy::DROP_EVENT; | |
420 WebMouseWheelEvent wheel; | |
421 wheel.type = WebInputEvent::MouseWheel; | |
422 | |
423 EXPECT_CALL(mock_input_handler_, ScrollAnimated(testing::_, testing::_)) | |
424 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); | |
425 | |
426 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); | |
427 VERIFY_AND_RESET_MOCKS(); | |
428 } | |
429 | |
430 TEST_P(InputHandlerProxyTest, GestureScrollStarted) { | |
431 // We shouldn't send any events to the widget for this gesture. | |
432 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
433 VERIFY_AND_RESET_MOCKS(); | |
434 | |
435 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
436 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
437 | |
438 gesture_.type = WebInputEvent::GestureScrollBegin; | |
439 EXPECT_EQ(expected_disposition_,input_handler_->HandleInputEvent(gesture_)); | |
440 | |
441 // The event should not be marked as handled if scrolling is not possible. | |
442 expected_disposition_ = InputHandlerProxy::DROP_EVENT; | |
443 VERIFY_AND_RESET_MOCKS(); | |
444 | |
445 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
446 gesture_.data.scrollUpdate.deltaY = | |
447 -40; // -Y means scroll down - i.e. in the +Y direction. | |
448 EXPECT_CALL(mock_input_handler_, | |
449 ScrollBy(testing::_, | |
450 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
451 .WillOnce(testing::Return(scroll_result_did_not_scroll_)); | |
452 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
453 | |
454 // Mark the event as handled if scroll happens. | |
455 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
456 VERIFY_AND_RESET_MOCKS(); | |
457 | |
458 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
459 gesture_.data.scrollUpdate.deltaY = | |
460 -40; // -Y means scroll down - i.e. in the +Y direction. | |
461 EXPECT_CALL(mock_input_handler_, | |
462 ScrollBy(testing::_, | |
463 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
464 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
465 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
466 | |
467 VERIFY_AND_RESET_MOCKS(); | |
468 | |
469 gesture_.type = WebInputEvent::GestureScrollEnd; | |
470 gesture_.data.scrollUpdate.deltaY = 0; | |
471 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
472 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
473 | |
474 VERIFY_AND_RESET_MOCKS(); | |
475 } | |
476 | |
477 TEST_P(InputHandlerProxyTest, GestureScrollOnMainThread) { | |
478 // We should send all events to the widget for this gesture. | |
479 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
480 VERIFY_AND_RESET_MOCKS(); | |
481 | |
482 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) | |
483 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); | |
484 | |
485 gesture_.type = WebInputEvent::GestureScrollBegin; | |
486 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
487 | |
488 VERIFY_AND_RESET_MOCKS(); | |
489 | |
490 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
491 gesture_.data.scrollUpdate.deltaY = 40; | |
492 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
493 | |
494 VERIFY_AND_RESET_MOCKS(); | |
495 | |
496 gesture_.type = WebInputEvent::GestureScrollEnd; | |
497 gesture_.data.scrollUpdate.deltaY = 0; | |
498 EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return()); | |
499 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
500 | |
501 VERIFY_AND_RESET_MOCKS(); | |
502 } | |
503 | |
504 TEST_P(InputHandlerProxyTest, GestureScrollIgnored) { | |
505 // We shouldn't handle the GestureScrollBegin. | |
506 // Instead, we should get a DROP_EVENT result, indicating | |
507 // that we could determine that there's nothing that could scroll or otherwise | |
508 // react to this gesture sequence and thus we should drop the whole gesture | |
509 // sequence on the floor, except for the ScrollEnd. | |
510 expected_disposition_ = InputHandlerProxy::DROP_EVENT; | |
511 VERIFY_AND_RESET_MOCKS(); | |
512 | |
513 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
514 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); | |
515 | |
516 gesture_.type = WebInputEvent::GestureScrollBegin; | |
517 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
518 | |
519 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
520 gesture_.type = WebInputEvent::GestureScrollEnd; | |
521 EXPECT_CALL(mock_input_handler_, ScrollEnd()).WillOnce(testing::Return()); | |
522 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
523 | |
524 VERIFY_AND_RESET_MOCKS(); | |
525 } | |
526 | |
527 TEST_P(InputHandlerProxyTest, GestureScrollBeginThatTargetViewport) { | |
528 // We shouldn't send any events to the widget for this gesture. | |
529 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
530 VERIFY_AND_RESET_MOCKS(); | |
531 | |
532 EXPECT_CALL(mock_input_handler_, RootScrollBegin(testing::_)) | |
533 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
534 | |
535 gesture_.type = WebInputEvent::GestureScrollBegin; | |
536 gesture_.data.scrollBegin.targetViewport = true; | |
537 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
538 | |
539 VERIFY_AND_RESET_MOCKS(); | |
540 } | |
541 | |
542 TEST_P(InputHandlerProxyTest, GesturePinch) { | |
543 // We shouldn't send any events to the widget for this gesture. | |
544 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
545 VERIFY_AND_RESET_MOCKS(); | |
546 | |
547 gesture_.type = WebInputEvent::GesturePinchBegin; | |
548 EXPECT_CALL(mock_input_handler_, HaveWheelEventHandlersAt(testing::_)) | |
549 .WillOnce(testing::Return(false)); | |
550 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); | |
551 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
552 | |
553 VERIFY_AND_RESET_MOCKS(); | |
554 | |
555 gesture_.type = WebInputEvent::GesturePinchUpdate; | |
556 gesture_.data.pinchUpdate.scale = 1.5; | |
557 gesture_.x = 7; | |
558 gesture_.y = 13; | |
559 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); | |
560 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
561 | |
562 VERIFY_AND_RESET_MOCKS(); | |
563 | |
564 gesture_.type = WebInputEvent::GesturePinchUpdate; | |
565 gesture_.data.pinchUpdate.scale = 0.5; | |
566 gesture_.data.pinchUpdate.zoomDisabled = true; | |
567 gesture_.x = 9; | |
568 gesture_.y = 6; | |
569 EXPECT_EQ(InputHandlerProxy::DROP_EVENT, | |
570 input_handler_->HandleInputEvent(gesture_)); | |
571 gesture_.data.pinchUpdate.zoomDisabled = false; | |
572 | |
573 VERIFY_AND_RESET_MOCKS(); | |
574 | |
575 gesture_.type = WebInputEvent::GesturePinchUpdate; | |
576 gesture_.data.pinchUpdate.scale = 0.5; | |
577 gesture_.x = 9; | |
578 gesture_.y = 6; | |
579 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); | |
580 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
581 | |
582 VERIFY_AND_RESET_MOCKS(); | |
583 | |
584 gesture_.type = WebInputEvent::GesturePinchEnd; | |
585 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); | |
586 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
587 | |
588 VERIFY_AND_RESET_MOCKS(); | |
589 } | |
590 | |
591 TEST_P(InputHandlerProxyTest, GesturePinchWithWheelHandler) { | |
592 // We will send the synthetic wheel event to the widget. | |
593 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
594 VERIFY_AND_RESET_MOCKS(); | |
595 | |
596 gesture_.type = WebInputEvent::GesturePinchBegin; | |
597 EXPECT_CALL(mock_input_handler_, HaveWheelEventHandlersAt(testing::_)) | |
598 .WillOnce(testing::Return(true)); | |
599 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
600 | |
601 VERIFY_AND_RESET_MOCKS(); | |
602 | |
603 gesture_.type = WebInputEvent::GesturePinchUpdate; | |
604 gesture_.data.pinchUpdate.scale = 1.5; | |
605 gesture_.x = 7; | |
606 gesture_.y = 13; | |
607 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
608 | |
609 VERIFY_AND_RESET_MOCKS(); | |
610 | |
611 gesture_.type = WebInputEvent::GesturePinchUpdate; | |
612 gesture_.data.pinchUpdate.scale = 0.5; | |
613 gesture_.x = 9; | |
614 gesture_.y = 6; | |
615 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
616 | |
617 VERIFY_AND_RESET_MOCKS(); | |
618 | |
619 gesture_.type = WebInputEvent::GesturePinchEnd; | |
620 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
621 } | |
622 | |
623 TEST_P(InputHandlerProxyTest, GesturePinchAfterScrollOnMainThread) { | |
624 // Scrolls will start by being sent to the main thread. | |
625 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
626 VERIFY_AND_RESET_MOCKS(); | |
627 | |
628 EXPECT_CALL(mock_input_handler_, ScrollBegin(::testing::_, ::testing::_)) | |
629 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); | |
630 | |
631 gesture_.type = WebInputEvent::GestureScrollBegin; | |
632 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
633 | |
634 VERIFY_AND_RESET_MOCKS(); | |
635 | |
636 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
637 gesture_.data.scrollUpdate.deltaY = 40; | |
638 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
639 | |
640 // However, after the pinch gesture starts, they should go to the impl | |
641 // thread. | |
642 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
643 VERIFY_AND_RESET_MOCKS(); | |
644 | |
645 gesture_.type = WebInputEvent::GesturePinchBegin; | |
646 EXPECT_CALL(mock_input_handler_, HaveWheelEventHandlersAt(testing::_)) | |
647 .WillOnce(testing::Return(false)); | |
648 EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); | |
649 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
650 | |
651 VERIFY_AND_RESET_MOCKS(); | |
652 | |
653 gesture_.type = WebInputEvent::GesturePinchUpdate; | |
654 gesture_.data.pinchUpdate.scale = 1.5; | |
655 gesture_.x = 7; | |
656 gesture_.y = 13; | |
657 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(1.5, gfx::Point(7, 13))); | |
658 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
659 | |
660 VERIFY_AND_RESET_MOCKS(); | |
661 | |
662 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
663 gesture_.data.scrollUpdate.deltaY = | |
664 -40; // -Y means scroll down - i.e. in the +Y direction. | |
665 EXPECT_CALL(mock_input_handler_, | |
666 ScrollBy(testing::_, | |
667 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
668 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
669 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
670 | |
671 VERIFY_AND_RESET_MOCKS(); | |
672 | |
673 gesture_.type = WebInputEvent::GesturePinchUpdate; | |
674 gesture_.data.pinchUpdate.scale = 0.5; | |
675 gesture_.x = 9; | |
676 gesture_.y = 6; | |
677 EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(.5, gfx::Point(9, 6))); | |
678 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
679 | |
680 VERIFY_AND_RESET_MOCKS(); | |
681 | |
682 gesture_.type = WebInputEvent::GesturePinchEnd; | |
683 EXPECT_CALL(mock_input_handler_, PinchGestureEnd()); | |
684 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
685 | |
686 // After the pinch gesture ends, they should go to back to the main | |
687 // thread. | |
688 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
689 VERIFY_AND_RESET_MOCKS(); | |
690 | |
691 gesture_.type = WebInputEvent::GestureScrollEnd; | |
692 gesture_.data.scrollUpdate.deltaY = 0; | |
693 EXPECT_CALL(mock_input_handler_, ScrollEnd()) | |
694 .WillOnce(testing::Return()); | |
695 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
696 | |
697 VERIFY_AND_RESET_MOCKS(); | |
698 } | |
699 | |
700 TEST_P(InputHandlerProxyTest, GestureFlingStartedTouchpad) { | |
701 // We shouldn't send any events to the widget for this gesture. | |
702 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
703 VERIFY_AND_RESET_MOCKS(); | |
704 | |
705 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
706 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
707 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
708 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
709 | |
710 gesture_.type = WebInputEvent::GestureFlingStart; | |
711 gesture_.data.flingStart.velocityX = 10; | |
712 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; | |
713 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
714 | |
715 VERIFY_AND_RESET_MOCKS(); | |
716 | |
717 // Verify that a GestureFlingCancel during an animation cancels it. | |
718 gesture_.type = WebInputEvent::GestureFlingCancel; | |
719 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; | |
720 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
721 } | |
722 | |
723 TEST_P(InputHandlerProxyTest, GestureFlingOnMainThreadTouchpad) { | |
724 // We should send all events to the widget for this gesture. | |
725 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
726 VERIFY_AND_RESET_MOCKS(); | |
727 | |
728 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
729 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); | |
730 | |
731 gesture_.type = WebInputEvent::GestureFlingStart; | |
732 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; | |
733 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
734 | |
735 // Since we returned ScrollStatusOnMainThread from scrollBegin, ensure the | |
736 // input handler knows it's scrolling off the impl thread | |
737 ASSERT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
738 | |
739 VERIFY_AND_RESET_MOCKS(); | |
740 | |
741 // Even if we didn't start a fling ourselves, we still need to send the cancel | |
742 // event to the widget. | |
743 gesture_.type = WebInputEvent::GestureFlingCancel; | |
744 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; | |
745 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
746 } | |
747 | |
748 TEST_P(InputHandlerProxyTest, GestureFlingIgnoredTouchpad) { | |
749 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
750 VERIFY_AND_RESET_MOCKS(); | |
751 | |
752 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
753 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); | |
754 | |
755 gesture_.type = WebInputEvent::GestureFlingStart; | |
756 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; | |
757 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
758 | |
759 expected_disposition_ = InputHandlerProxy::DROP_EVENT; | |
760 VERIFY_AND_RESET_MOCKS(); | |
761 | |
762 // Since the previous fling was ignored, we should also be dropping the next | |
763 // fling_cancel. | |
764 gesture_.type = WebInputEvent::GestureFlingCancel; | |
765 gesture_.sourceDevice = blink::WebGestureDeviceTouchpad; | |
766 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
767 } | |
768 | |
769 TEST_P(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) { | |
770 // We shouldn't send any events to the widget for this gesture. | |
771 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
772 VERIFY_AND_RESET_MOCKS(); | |
773 | |
774 // On the fling start, we should schedule an animation but not actually start | |
775 // scrolling. | |
776 gesture_.type = WebInputEvent::GestureFlingStart; | |
777 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
778 WebPoint fling_point = WebPoint(7, 13); | |
779 WebPoint fling_global_point = WebPoint(17, 23); | |
780 // Note that for trackpad, wheel events with the Control modifier are | |
781 // special (reserved for zoom), so don't set that here. | |
782 int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey; | |
783 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad, | |
784 fling_delta, | |
785 fling_point, | |
786 fling_global_point, | |
787 modifiers); | |
788 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
789 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
790 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
791 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
792 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
793 | |
794 VERIFY_AND_RESET_MOCKS(); | |
795 // The first animate call should let us pick up an animation start time, but | |
796 // we shouldn't actually move anywhere just yet. The first frame after the | |
797 // fling start will typically include the last scroll from the gesture that | |
798 // lead to the scroll (either wheel or gesture scroll), so there should be no | |
799 // visible hitch. | |
800 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
801 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
802 .Times(0); | |
803 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
804 Animate(time); | |
805 | |
806 VERIFY_AND_RESET_MOCKS(); | |
807 | |
808 // The second call should start scrolling in the -X direction. | |
809 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
810 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
811 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
812 EXPECT_CALL(mock_input_handler_, | |
813 ScrollBy(testing::_, | |
814 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
815 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
816 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
817 time += base::TimeDelta::FromMilliseconds(100); | |
818 Animate(time); | |
819 | |
820 VERIFY_AND_RESET_MOCKS(); | |
821 | |
822 // Let's say on the third call we hit a non-scrollable region. We should abort | |
823 // the fling and not scroll. | |
824 // We also should pass the current fling parameters out to the client so the | |
825 // rest of the fling can be | |
826 // transferred to the main thread. | |
827 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
828 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); | |
829 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); | |
830 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); | |
831 // Expected wheel fling animation parameters: | |
832 // *) fling_delta and fling_point should match the original GestureFlingStart | |
833 // event | |
834 // *) startTime should be 10 to match the time parameter of the first | |
835 // Animate() call after the GestureFlingStart | |
836 // *) cumulativeScroll depends on the curve, but since we've animated in the | |
837 // -X direction the X value should be < 0 | |
838 EXPECT_CALL( | |
839 mock_client_, | |
840 TransferActiveWheelFlingAnimation(testing::AllOf( | |
841 testing::Field(&WebActiveWheelFlingParameters::delta, | |
842 testing::Eq(fling_delta)), | |
843 testing::Field(&WebActiveWheelFlingParameters::point, | |
844 testing::Eq(fling_point)), | |
845 testing::Field(&WebActiveWheelFlingParameters::globalPoint, | |
846 testing::Eq(fling_global_point)), | |
847 testing::Field(&WebActiveWheelFlingParameters::modifiers, | |
848 testing::Eq(modifiers)), | |
849 testing::Field(&WebActiveWheelFlingParameters::startTime, | |
850 testing::Eq(10)), | |
851 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, | |
852 testing::Field(&WebSize::width, testing::Gt(0)))))); | |
853 time += base::TimeDelta::FromMilliseconds(100); | |
854 Animate(time); | |
855 | |
856 VERIFY_AND_RESET_MOCKS(); | |
857 | |
858 // Since we've aborted the fling, the next animation should be a no-op and | |
859 // should not result in another | |
860 // frame being requested. | |
861 EXPECT_SET_NEEDS_ANIMATE_INPUT(0); | |
862 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
863 .Times(0); | |
864 time += base::TimeDelta::FromMilliseconds(100); | |
865 Animate(time); | |
866 | |
867 // Since we've transferred the fling to the main thread, we need to pass the | |
868 // next GestureFlingCancel to the main | |
869 // thread as well. | |
870 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
871 gesture_.type = WebInputEvent::GestureFlingCancel; | |
872 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
873 | |
874 VERIFY_AND_RESET_MOCKS(); | |
875 } | |
876 | |
877 TEST_P(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) { | |
878 // We shouldn't send any events to the widget for this gesture. | |
879 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
880 VERIFY_AND_RESET_MOCKS(); | |
881 | |
882 // Start a gesture fling in the -X direction with zero Y movement. | |
883 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
884 WebPoint fling_point = WebPoint(7, 13); | |
885 WebPoint fling_global_point = WebPoint(17, 23); | |
886 // Note that for trackpad, wheel events with the Control modifier are | |
887 // special (reserved for zoom), so don't set that here. | |
888 int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey; | |
889 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad, | |
890 fling_delta, | |
891 fling_point, | |
892 fling_global_point, | |
893 modifiers); | |
894 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
895 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
896 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
897 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
898 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
899 | |
900 VERIFY_AND_RESET_MOCKS(); | |
901 | |
902 // Start the fling animation at time 10. This shouldn't actually scroll, just | |
903 // establish a start time. | |
904 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
905 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
906 .Times(0); | |
907 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
908 Animate(time); | |
909 | |
910 VERIFY_AND_RESET_MOCKS(); | |
911 | |
912 // The second call should start scrolling in the -X direction. | |
913 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
914 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
915 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
916 EXPECT_CALL(mock_input_handler_, | |
917 ScrollBy(testing::_, | |
918 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
919 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
920 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
921 time += base::TimeDelta::FromMilliseconds(100); | |
922 Animate(time); | |
923 | |
924 VERIFY_AND_RESET_MOCKS(); | |
925 | |
926 // Let's say on the third call we hit a non-scrollable region. We should abort | |
927 // the fling and not scroll. | |
928 // We also should pass the current fling parameters out to the client so the | |
929 // rest of the fling can be | |
930 // transferred to the main thread. | |
931 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
932 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); | |
933 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); | |
934 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); | |
935 | |
936 // Expected wheel fling animation parameters: | |
937 // *) fling_delta and fling_point should match the original GestureFlingStart | |
938 // event | |
939 // *) startTime should be 10 to match the time parameter of the first | |
940 // Animate() call after the GestureFlingStart | |
941 // *) cumulativeScroll depends on the curve, but since we've animated in the | |
942 // -X direction the X value should be < 0 | |
943 EXPECT_CALL( | |
944 mock_client_, | |
945 TransferActiveWheelFlingAnimation(testing::AllOf( | |
946 testing::Field(&WebActiveWheelFlingParameters::delta, | |
947 testing::Eq(fling_delta)), | |
948 testing::Field(&WebActiveWheelFlingParameters::point, | |
949 testing::Eq(fling_point)), | |
950 testing::Field(&WebActiveWheelFlingParameters::globalPoint, | |
951 testing::Eq(fling_global_point)), | |
952 testing::Field(&WebActiveWheelFlingParameters::modifiers, | |
953 testing::Eq(modifiers)), | |
954 testing::Field(&WebActiveWheelFlingParameters::startTime, | |
955 testing::Eq(10)), | |
956 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, | |
957 testing::Field(&WebSize::width, testing::Gt(0)))))); | |
958 time += base::TimeDelta::FromMilliseconds(100); | |
959 Animate(time); | |
960 | |
961 VERIFY_AND_RESET_MOCKS(); | |
962 | |
963 // Since we've aborted the fling, the next animation should be a no-op and | |
964 // should not result in another | |
965 // frame being requested. | |
966 EXPECT_SET_NEEDS_ANIMATE_INPUT(0); | |
967 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
968 .Times(0); | |
969 time += base::TimeDelta::FromMilliseconds(100); | |
970 Animate(time); | |
971 | |
972 VERIFY_AND_RESET_MOCKS(); | |
973 | |
974 // Since we've transferred the fling to the main thread, we need to pass the | |
975 // next GestureFlingCancel to the main | |
976 // thread as well. | |
977 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
978 gesture_.type = WebInputEvent::GestureFlingCancel; | |
979 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
980 | |
981 VERIFY_AND_RESET_MOCKS(); | |
982 input_handler_->MainThreadHasStoppedFlinging(); | |
983 | |
984 // Start a second gesture fling, this time in the +Y direction with no X. | |
985 fling_delta = WebFloatPoint(0, -1000); | |
986 fling_point = WebPoint(95, 87); | |
987 fling_global_point = WebPoint(32, 71); | |
988 modifiers = WebInputEvent::AltKey; | |
989 gesture_ = CreateFling(blink::WebGestureDeviceTouchpad, | |
990 fling_delta, | |
991 fling_point, | |
992 fling_global_point, | |
993 modifiers); | |
994 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
995 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
996 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
997 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
998 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
999 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1000 | |
1001 VERIFY_AND_RESET_MOCKS(); | |
1002 | |
1003 // Start the second fling animation at time 30. | |
1004 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1005 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1006 .Times(0); | |
1007 time = base::TimeTicks() + base::TimeDelta::FromSeconds(30); | |
1008 Animate(time); | |
1009 | |
1010 VERIFY_AND_RESET_MOCKS(); | |
1011 | |
1012 // Tick the second fling once normally. | |
1013 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1014 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1015 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1016 EXPECT_CALL(mock_input_handler_, | |
1017 ScrollBy(testing::_, | |
1018 testing::Property(&gfx::Vector2dF::y, testing::Gt(0)))) | |
1019 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1020 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1021 time += base::TimeDelta::FromMilliseconds(100); | |
1022 Animate(time); | |
1023 | |
1024 VERIFY_AND_RESET_MOCKS(); | |
1025 | |
1026 // Then abort the second fling. | |
1027 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1028 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); | |
1029 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); | |
1030 EXPECT_CALL(mock_input_handler_, ScrollEnd()).Times(0); | |
1031 | |
1032 // We should get parameters from the second fling, nothing from the first | |
1033 // fling should "leak". | |
1034 EXPECT_CALL( | |
1035 mock_client_, | |
1036 TransferActiveWheelFlingAnimation(testing::AllOf( | |
1037 testing::Field(&WebActiveWheelFlingParameters::delta, | |
1038 testing::Eq(fling_delta)), | |
1039 testing::Field(&WebActiveWheelFlingParameters::point, | |
1040 testing::Eq(fling_point)), | |
1041 testing::Field(&WebActiveWheelFlingParameters::globalPoint, | |
1042 testing::Eq(fling_global_point)), | |
1043 testing::Field(&WebActiveWheelFlingParameters::modifiers, | |
1044 testing::Eq(modifiers)), | |
1045 testing::Field(&WebActiveWheelFlingParameters::startTime, | |
1046 testing::Eq(30)), | |
1047 testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll, | |
1048 testing::Field(&WebSize::height, testing::Lt(0)))))); | |
1049 time += base::TimeDelta::FromMilliseconds(100); | |
1050 Animate(time); | |
1051 | |
1052 VERIFY_AND_RESET_MOCKS(); | |
1053 } | |
1054 | |
1055 TEST_P(InputHandlerProxyTest, GestureFlingStartedTouchscreen) { | |
1056 // We shouldn't send any events to the widget for this gesture. | |
1057 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1058 VERIFY_AND_RESET_MOCKS(); | |
1059 | |
1060 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1061 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1062 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1063 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1064 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1065 | |
1066 VERIFY_AND_RESET_MOCKS(); | |
1067 | |
1068 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1069 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1070 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1071 | |
1072 gesture_.type = WebInputEvent::GestureFlingStart; | |
1073 gesture_.data.flingStart.velocityX = 10; | |
1074 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1075 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1076 | |
1077 VERIFY_AND_RESET_MOCKS(); | |
1078 | |
1079 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1080 | |
1081 // Verify that a GestureFlingCancel during an animation cancels it. | |
1082 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1083 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1084 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1085 | |
1086 VERIFY_AND_RESET_MOCKS(); | |
1087 } | |
1088 | |
1089 TEST_P(InputHandlerProxyTest, GestureFlingOnMainThreadTouchscreen) { | |
1090 // We should send all events to the widget for this gesture. | |
1091 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
1092 VERIFY_AND_RESET_MOCKS(); | |
1093 | |
1094 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1095 .WillOnce(testing::Return(cc::InputHandler::SCROLL_ON_MAIN_THREAD)); | |
1096 | |
1097 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1098 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1099 | |
1100 VERIFY_AND_RESET_MOCKS(); | |
1101 | |
1102 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()).Times(0); | |
1103 | |
1104 gesture_.type = WebInputEvent::GestureFlingStart; | |
1105 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1106 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1107 | |
1108 VERIFY_AND_RESET_MOCKS(); | |
1109 | |
1110 // Even if we didn't start a fling ourselves, we still need to send the cancel | |
1111 // event to the widget. | |
1112 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1113 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1114 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1115 } | |
1116 | |
1117 TEST_P(InputHandlerProxyTest, GestureFlingIgnoredTouchscreen) { | |
1118 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1119 VERIFY_AND_RESET_MOCKS(); | |
1120 | |
1121 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1122 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1123 | |
1124 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1125 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1126 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1127 | |
1128 expected_disposition_ = InputHandlerProxy::DROP_EVENT; | |
1129 VERIFY_AND_RESET_MOCKS(); | |
1130 | |
1131 // Flings ignored by the InputHandler should be dropped, signalling the end | |
1132 // of the touch scroll sequence. | |
1133 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1134 .WillOnce(testing::Return(cc::InputHandler::SCROLL_IGNORED)); | |
1135 | |
1136 gesture_.type = WebInputEvent::GestureFlingStart; | |
1137 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1138 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1139 | |
1140 VERIFY_AND_RESET_MOCKS(); | |
1141 | |
1142 // Subsequent scrolls should behave normally, even without an intervening | |
1143 // GestureFlingCancel, as the original GestureFlingStart was dropped. | |
1144 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1145 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1146 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1147 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1148 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1149 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1150 | |
1151 VERIFY_AND_RESET_MOCKS(); | |
1152 } | |
1153 | |
1154 TEST_P(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) { | |
1155 // We shouldn't send any events to the widget for this gesture. | |
1156 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1157 VERIFY_AND_RESET_MOCKS(); | |
1158 | |
1159 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1160 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1161 | |
1162 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1163 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1164 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1165 | |
1166 VERIFY_AND_RESET_MOCKS(); | |
1167 | |
1168 // On the fling start, we should schedule an animation but not actually start | |
1169 // scrolling. | |
1170 WebFloatPoint fling_delta = WebFloatPoint(100, 0); | |
1171 WebPoint fling_point = WebPoint(7, 13); | |
1172 WebPoint fling_global_point = WebPoint(17, 23); | |
1173 // Note that for touchscreen the control modifier is not special. | |
1174 int modifiers = WebInputEvent::ControlKey; | |
1175 gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen, | |
1176 fling_delta, | |
1177 fling_point, | |
1178 fling_global_point, | |
1179 modifiers); | |
1180 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1181 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1182 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1183 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1184 | |
1185 VERIFY_AND_RESET_MOCKS(); | |
1186 // The first animate call should let us pick up an animation start time, but | |
1187 // we shouldn't actually move anywhere just yet. The first frame after the | |
1188 // fling start will typically include the last scroll from the gesture that | |
1189 // lead to the scroll (either wheel or gesture scroll), so there should be no | |
1190 // visible hitch. | |
1191 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1192 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
1193 Animate(time); | |
1194 | |
1195 VERIFY_AND_RESET_MOCKS(); | |
1196 | |
1197 // The second call should start scrolling in the -X direction. | |
1198 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1199 EXPECT_CALL(mock_input_handler_, | |
1200 ScrollBy(testing::_, | |
1201 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
1202 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1203 time += base::TimeDelta::FromMilliseconds(100); | |
1204 Animate(time); | |
1205 | |
1206 VERIFY_AND_RESET_MOCKS(); | |
1207 | |
1208 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1209 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1210 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1211 | |
1212 VERIFY_AND_RESET_MOCKS(); | |
1213 } | |
1214 | |
1215 TEST_P(InputHandlerProxyTest, GestureFlingWithValidTimestamp) { | |
1216 // We shouldn't send any events to the widget for this gesture. | |
1217 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1218 VERIFY_AND_RESET_MOCKS(); | |
1219 | |
1220 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1221 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1222 | |
1223 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1224 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1225 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1226 | |
1227 VERIFY_AND_RESET_MOCKS(); | |
1228 | |
1229 // On the fling start, we should schedule an animation but not actually start | |
1230 // scrolling. | |
1231 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
1232 base::TimeTicks time = base::TimeTicks() + dt; | |
1233 WebFloatPoint fling_delta = WebFloatPoint(100, 0); | |
1234 WebPoint fling_point = WebPoint(7, 13); | |
1235 WebPoint fling_global_point = WebPoint(17, 23); | |
1236 int modifiers = WebInputEvent::ControlKey; | |
1237 gesture_ = CreateFling(time, | |
1238 blink::WebGestureDeviceTouchscreen, | |
1239 fling_delta, | |
1240 fling_point, | |
1241 fling_global_point, | |
1242 modifiers); | |
1243 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1244 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1245 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1246 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1247 | |
1248 VERIFY_AND_RESET_MOCKS(); | |
1249 // With a valid time stamp, the first animate call should skip start time | |
1250 // initialization and immediately begin scroll update production. This reduces | |
1251 // the likelihood of a hitch between the scroll preceding the fling and | |
1252 // the first scroll generated by the fling. | |
1253 // Scrolling should start in the -X direction. | |
1254 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1255 EXPECT_CALL(mock_input_handler_, | |
1256 ScrollBy(testing::_, | |
1257 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
1258 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1259 time += dt; | |
1260 Animate(time); | |
1261 | |
1262 VERIFY_AND_RESET_MOCKS(); | |
1263 | |
1264 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1265 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1266 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1267 | |
1268 VERIFY_AND_RESET_MOCKS(); | |
1269 } | |
1270 | |
1271 TEST_P(InputHandlerProxyTest, GestureFlingWithInvalidTimestamp) { | |
1272 // We shouldn't send any events to the widget for this gesture. | |
1273 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1274 VERIFY_AND_RESET_MOCKS(); | |
1275 | |
1276 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1277 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1278 | |
1279 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1280 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1281 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1282 | |
1283 VERIFY_AND_RESET_MOCKS(); | |
1284 | |
1285 // On the fling start, we should schedule an animation but not actually start | |
1286 // scrolling. | |
1287 base::TimeDelta start_time_offset = base::TimeDelta::FromMilliseconds(10); | |
1288 gesture_.type = WebInputEvent::GestureFlingStart; | |
1289 WebFloatPoint fling_delta = WebFloatPoint(100, 0); | |
1290 WebPoint fling_point = WebPoint(7, 13); | |
1291 WebPoint fling_global_point = WebPoint(17, 23); | |
1292 int modifiers = WebInputEvent::ControlKey; | |
1293 gesture_.timeStampSeconds = start_time_offset.InSecondsF(); | |
1294 gesture_.data.flingStart.velocityX = fling_delta.x; | |
1295 gesture_.data.flingStart.velocityY = fling_delta.y; | |
1296 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1297 gesture_.x = fling_point.x; | |
1298 gesture_.y = fling_point.y; | |
1299 gesture_.globalX = fling_global_point.x; | |
1300 gesture_.globalY = fling_global_point.y; | |
1301 gesture_.modifiers = modifiers; | |
1302 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1303 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1304 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1305 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1306 | |
1307 VERIFY_AND_RESET_MOCKS(); | |
1308 // Event though a time stamp was provided for the fling event, it will be | |
1309 // ignored as its too far in the past relative to the first animate call's | |
1310 // timestamp. | |
1311 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1312 base::TimeTicks time = | |
1313 base::TimeTicks() + start_time_offset + base::TimeDelta::FromSeconds(1); | |
1314 Animate(time); | |
1315 | |
1316 VERIFY_AND_RESET_MOCKS(); | |
1317 | |
1318 // Further animation ticks should update the fling as usual. | |
1319 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1320 EXPECT_CALL(mock_input_handler_, | |
1321 ScrollBy(testing::_, | |
1322 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
1323 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1324 time += base::TimeDelta::FromMilliseconds(10); | |
1325 Animate(time); | |
1326 | |
1327 VERIFY_AND_RESET_MOCKS(); | |
1328 | |
1329 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1330 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1331 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1332 | |
1333 VERIFY_AND_RESET_MOCKS(); | |
1334 } | |
1335 | |
1336 TEST_P(InputHandlerProxyTest, GestureScrollOnImplThreadFlagClearedAfterFling) { | |
1337 // We shouldn't send any events to the widget for this gesture. | |
1338 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1339 VERIFY_AND_RESET_MOCKS(); | |
1340 | |
1341 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1342 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1343 | |
1344 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1345 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1346 | |
1347 // After sending a GestureScrollBegin, the member variable | |
1348 // |gesture_scroll_on_impl_thread_| should be true. | |
1349 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1350 | |
1351 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1352 VERIFY_AND_RESET_MOCKS(); | |
1353 | |
1354 // On the fling start, we should schedule an animation but not actually start | |
1355 // scrolling. | |
1356 WebFloatPoint fling_delta = WebFloatPoint(100, 0); | |
1357 WebPoint fling_point = WebPoint(7, 13); | |
1358 WebPoint fling_global_point = WebPoint(17, 23); | |
1359 int modifiers = WebInputEvent::ControlKey | WebInputEvent::AltKey; | |
1360 gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen, | |
1361 fling_delta, | |
1362 fling_point, | |
1363 fling_global_point, | |
1364 modifiers); | |
1365 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1366 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1367 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1368 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1369 | |
1370 // |gesture_scroll_on_impl_thread_| should still be true after | |
1371 // a GestureFlingStart is sent. | |
1372 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1373 | |
1374 VERIFY_AND_RESET_MOCKS(); | |
1375 // The first animate call should let us pick up an animation start time, but | |
1376 // we shouldn't actually move anywhere just yet. The first frame after the | |
1377 // fling start will typically include the last scroll from the gesture that | |
1378 // lead to the scroll (either wheel or gesture scroll), so there should be no | |
1379 // visible hitch. | |
1380 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1381 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
1382 Animate(time); | |
1383 | |
1384 VERIFY_AND_RESET_MOCKS(); | |
1385 | |
1386 // The second call should start scrolling in the -X direction. | |
1387 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1388 EXPECT_CALL(mock_input_handler_, | |
1389 ScrollBy(testing::_, | |
1390 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
1391 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1392 time += base::TimeDelta::FromMilliseconds(100); | |
1393 Animate(time); | |
1394 | |
1395 VERIFY_AND_RESET_MOCKS(); | |
1396 | |
1397 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1398 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1399 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1400 | |
1401 // |gesture_scroll_on_impl_thread_| should be false once | |
1402 // the fling has finished (note no GestureScrollEnd has been sent). | |
1403 EXPECT_TRUE(!input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1404 | |
1405 VERIFY_AND_RESET_MOCKS(); | |
1406 } | |
1407 | |
1408 TEST_P(InputHandlerProxyTest, | |
1409 BeginScrollWhenGestureScrollOnImplThreadFlagIsSet) { | |
1410 // We shouldn't send any events to the widget for this gesture. | |
1411 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1412 VERIFY_AND_RESET_MOCKS(); | |
1413 | |
1414 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1415 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1416 | |
1417 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1418 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1419 | |
1420 // After sending a GestureScrollBegin, the member variable | |
1421 // |gesture_scroll_on_impl_thread_| should be true. | |
1422 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1423 | |
1424 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1425 VERIFY_AND_RESET_MOCKS(); | |
1426 | |
1427 // On the fling start, we should schedule an animation but not actually start | |
1428 // scrolling. | |
1429 WebFloatPoint fling_delta = WebFloatPoint(100, 0); | |
1430 WebPoint fling_point = WebPoint(7, 13); | |
1431 WebPoint fling_global_point = WebPoint(17, 23); | |
1432 int modifiers = WebInputEvent::ControlKey | WebInputEvent::AltKey; | |
1433 gesture_ = CreateFling(blink::WebGestureDeviceTouchscreen, fling_delta, | |
1434 fling_point, fling_global_point, modifiers); | |
1435 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1436 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1437 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1438 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1439 | |
1440 // |gesture_scroll_on_impl_thread_| should still be true after | |
1441 // a GestureFlingStart is sent. | |
1442 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1443 | |
1444 VERIFY_AND_RESET_MOCKS(); | |
1445 | |
1446 // gesture_scroll_on_impl_thread_ is still true when this scroll begins. As a | |
1447 // result, this scroll begin will cancel the previous fling. | |
1448 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1449 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1450 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1451 | |
1452 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1453 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1454 | |
1455 // After sending a GestureScrollBegin, the member variable | |
1456 // |gesture_scroll_on_impl_thread_| should be true. | |
1457 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1458 VERIFY_AND_RESET_MOCKS(); | |
1459 } | |
1460 | |
1461 TEST_P(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) { | |
1462 // We shouldn't send any events to the widget for this gesture. | |
1463 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1464 VERIFY_AND_RESET_MOCKS(); | |
1465 | |
1466 // On the fling start, we should schedule an animation but not actually start | |
1467 // scrolling. | |
1468 gesture_.type = WebInputEvent::GestureFlingStart; | |
1469 WebFloatPoint fling_delta = WebFloatPoint(100, 100); | |
1470 gesture_.data.flingStart.velocityX = fling_delta.x; | |
1471 gesture_.data.flingStart.velocityY = fling_delta.y; | |
1472 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1473 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1474 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1475 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1476 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1477 VERIFY_AND_RESET_MOCKS(); | |
1478 | |
1479 // The first animate doesn't cause any scrolling. | |
1480 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1481 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
1482 Animate(time); | |
1483 VERIFY_AND_RESET_MOCKS(); | |
1484 | |
1485 // The second animate starts scrolling in the positive X and Y directions. | |
1486 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1487 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1488 EXPECT_CALL(mock_input_handler_, | |
1489 ScrollBy(testing::_, | |
1490 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))) | |
1491 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1492 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1493 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1494 time += base::TimeDelta::FromMilliseconds(100); | |
1495 Animate(time); | |
1496 VERIFY_AND_RESET_MOCKS(); | |
1497 | |
1498 // The third animate overscrolls in the positive Y direction but scrolls | |
1499 // somewhat. | |
1500 cc::InputHandlerScrollResult overscroll; | |
1501 overscroll.did_scroll = true; | |
1502 overscroll.did_overscroll_root = true; | |
1503 overscroll.accumulated_root_overscroll = gfx::Vector2dF(0, 100); | |
1504 overscroll.unused_scroll_delta = gfx::Vector2dF(0, 10); | |
1505 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1506 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1507 EXPECT_CALL(mock_input_handler_, | |
1508 ScrollBy(testing::_, | |
1509 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))) | |
1510 .WillOnce(testing::Return(overscroll)); | |
1511 EXPECT_CALL( | |
1512 mock_client_, | |
1513 DidOverscroll(testing::AllOf( | |
1514 testing::Field( | |
1515 &DidOverscrollParams::accumulated_overscroll, | |
1516 testing::Eq(overscroll.accumulated_root_overscroll)), | |
1517 testing::Field( | |
1518 &DidOverscrollParams::latest_overscroll_delta, | |
1519 testing::Eq(overscroll.unused_scroll_delta)), | |
1520 testing::Field( | |
1521 &DidOverscrollParams::current_fling_velocity, | |
1522 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))))); | |
1523 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1524 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1525 time += base::TimeDelta::FromMilliseconds(100); | |
1526 Animate(time); | |
1527 VERIFY_AND_RESET_MOCKS(); | |
1528 | |
1529 // The next call to animate will no longer scroll vertically. | |
1530 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1531 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1532 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1533 EXPECT_CALL(mock_input_handler_, | |
1534 ScrollBy(testing::_, | |
1535 testing::Property(&gfx::Vector2dF::y, testing::Eq(0)))) | |
1536 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1537 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1538 time += base::TimeDelta::FromMilliseconds(100); | |
1539 Animate(time); | |
1540 VERIFY_AND_RESET_MOCKS(); | |
1541 } | |
1542 | |
1543 TEST_P(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) { | |
1544 // We shouldn't send any events to the widget for this gesture. | |
1545 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1546 VERIFY_AND_RESET_MOCKS(); | |
1547 | |
1548 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1549 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1550 | |
1551 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1552 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1553 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1554 | |
1555 VERIFY_AND_RESET_MOCKS(); | |
1556 | |
1557 // On the fling start, we should schedule an animation but not actually start | |
1558 // scrolling. | |
1559 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
1560 base::TimeTicks time = base::TimeTicks() + dt; | |
1561 WebFloatPoint fling_delta = WebFloatPoint(100, 0); | |
1562 WebPoint fling_point = WebPoint(7, 13); | |
1563 WebPoint fling_global_point = WebPoint(17, 23); | |
1564 int modifiers = WebInputEvent::ControlKey; | |
1565 gesture_ = CreateFling(time, | |
1566 blink::WebGestureDeviceTouchscreen, | |
1567 fling_delta, | |
1568 fling_point, | |
1569 fling_global_point, | |
1570 modifiers); | |
1571 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1572 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1573 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1574 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1575 | |
1576 VERIFY_AND_RESET_MOCKS(); | |
1577 // With an animation timestamp equivalent to the starting timestamp, the | |
1578 // animation will simply be rescheduled. | |
1579 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1580 Animate(time); | |
1581 | |
1582 VERIFY_AND_RESET_MOCKS(); | |
1583 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1584 | |
1585 // A small time delta should not stop the fling, even if the client | |
1586 // reports no scrolling. | |
1587 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1588 EXPECT_CALL(mock_input_handler_, | |
1589 ScrollBy(testing::_, | |
1590 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
1591 .WillOnce(testing::Return(scroll_result_did_not_scroll_)); | |
1592 time += base::TimeDelta::FromMicroseconds(5); | |
1593 Animate(time); | |
1594 | |
1595 VERIFY_AND_RESET_MOCKS(); | |
1596 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1597 | |
1598 // A time delta of zero should not stop the fling, and neither should it | |
1599 // trigger scrolling on the client. | |
1600 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1601 Animate(time); | |
1602 | |
1603 VERIFY_AND_RESET_MOCKS(); | |
1604 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1605 | |
1606 // Lack of movement on the client, with a non-trivial scroll delta, should | |
1607 // terminate the fling. | |
1608 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1609 EXPECT_CALL(mock_input_handler_, | |
1610 ScrollBy(testing::_, | |
1611 testing::Property(&gfx::Vector2dF::x, testing::Lt(1)))) | |
1612 .WillOnce(testing::Return(scroll_result_did_not_scroll_)); | |
1613 time += base::TimeDelta::FromMilliseconds(100); | |
1614 Animate(time); | |
1615 | |
1616 VERIFY_AND_RESET_MOCKS(); | |
1617 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1618 } | |
1619 | |
1620 TEST_P(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) { | |
1621 cc::InputHandlerScrollResult overscroll; | |
1622 overscroll.did_scroll = true; | |
1623 overscroll.did_overscroll_root = true; | |
1624 | |
1625 // We shouldn't send any events to the widget for this gesture. | |
1626 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1627 VERIFY_AND_RESET_MOCKS(); | |
1628 | |
1629 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1630 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1631 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1632 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1633 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1634 VERIFY_AND_RESET_MOCKS(); | |
1635 | |
1636 // On the fling start, we should schedule an animation but not actually start | |
1637 // scrolling. | |
1638 gesture_.type = WebInputEvent::GestureFlingStart; | |
1639 WebFloatPoint fling_delta = WebFloatPoint(100, 100); | |
1640 gesture_.data.flingStart.velocityX = fling_delta.x; | |
1641 gesture_.data.flingStart.velocityY = fling_delta.y; | |
1642 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1643 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1644 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1645 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1646 VERIFY_AND_RESET_MOCKS(); | |
1647 | |
1648 // The first animate doesn't cause any scrolling. | |
1649 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1650 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
1651 Animate(time); | |
1652 VERIFY_AND_RESET_MOCKS(); | |
1653 | |
1654 // The second animate starts scrolling in the positive X and Y directions. | |
1655 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1656 EXPECT_CALL(mock_input_handler_, | |
1657 ScrollBy(testing::_, | |
1658 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))) | |
1659 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1660 time += base::TimeDelta::FromMilliseconds(10); | |
1661 Animate(time); | |
1662 VERIFY_AND_RESET_MOCKS(); | |
1663 | |
1664 // The third animate hits the bottom content edge. | |
1665 overscroll.accumulated_root_overscroll = gfx::Vector2dF(0, 100); | |
1666 overscroll.unused_scroll_delta = gfx::Vector2dF(0, 100); | |
1667 EXPECT_CALL(mock_input_handler_, | |
1668 ScrollBy(testing::_, | |
1669 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))) | |
1670 .WillOnce(testing::Return(overscroll)); | |
1671 EXPECT_CALL( | |
1672 mock_client_, | |
1673 DidOverscroll(testing::AllOf( | |
1674 testing::Field( | |
1675 &DidOverscrollParams::accumulated_overscroll, | |
1676 testing::Eq(overscroll.accumulated_root_overscroll)), | |
1677 testing::Field( | |
1678 &DidOverscrollParams::latest_overscroll_delta, | |
1679 testing::Eq(overscroll.unused_scroll_delta)), | |
1680 testing::Field( | |
1681 &DidOverscrollParams::current_fling_velocity, | |
1682 testing::Property(&gfx::Vector2dF::y, testing::Lt(0)))))); | |
1683 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1684 time += base::TimeDelta::FromMilliseconds(10); | |
1685 Animate(time); | |
1686 VERIFY_AND_RESET_MOCKS(); | |
1687 | |
1688 // The next call to animate will no longer scroll vertically. | |
1689 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1690 EXPECT_CALL(mock_input_handler_, | |
1691 ScrollBy(testing::_, | |
1692 testing::Property(&gfx::Vector2dF::y, testing::Eq(0)))) | |
1693 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1694 time += base::TimeDelta::FromMilliseconds(10); | |
1695 Animate(time); | |
1696 VERIFY_AND_RESET_MOCKS(); | |
1697 | |
1698 // The next call will hit the right edge. | |
1699 overscroll.accumulated_root_overscroll = gfx::Vector2dF(100, 100); | |
1700 overscroll.unused_scroll_delta = gfx::Vector2dF(100, 0); | |
1701 EXPECT_CALL(mock_input_handler_, | |
1702 ScrollBy(testing::_, | |
1703 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
1704 .WillOnce(testing::Return(overscroll)); | |
1705 EXPECT_CALL( | |
1706 mock_client_, | |
1707 DidOverscroll(testing::AllOf( | |
1708 testing::Field( | |
1709 &DidOverscrollParams::accumulated_overscroll, | |
1710 testing::Eq(overscroll.accumulated_root_overscroll)), | |
1711 testing::Field( | |
1712 &DidOverscrollParams::latest_overscroll_delta, | |
1713 testing::Eq(overscroll.unused_scroll_delta)), | |
1714 testing::Field( | |
1715 &DidOverscrollParams::current_fling_velocity, | |
1716 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))))); | |
1717 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1718 time += base::TimeDelta::FromMilliseconds(10); | |
1719 Animate(time); | |
1720 VERIFY_AND_RESET_MOCKS(); | |
1721 | |
1722 // The next call to animate will no longer scroll horizontally or vertically, | |
1723 // and the fling should be cancelled. | |
1724 EXPECT_SET_NEEDS_ANIMATE_INPUT(0); | |
1725 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0); | |
1726 time += base::TimeDelta::FromMilliseconds(10); | |
1727 Animate(time); | |
1728 VERIFY_AND_RESET_MOCKS(); | |
1729 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1730 } | |
1731 | |
1732 TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestNegative) { | |
1733 // None of the three touch points fall in the touch region. So the event | |
1734 // should be dropped. | |
1735 expected_disposition_ = InputHandlerProxy::DROP_EVENT; | |
1736 VERIFY_AND_RESET_MOCKS(); | |
1737 | |
1738 EXPECT_CALL(mock_input_handler_, | |
1739 DoTouchEventsBlockScrollAt( | |
1740 testing::Property(&gfx::Point::x, testing::Gt(0)))) | |
1741 .WillOnce(testing::Return(false)); | |
1742 EXPECT_CALL(mock_input_handler_, | |
1743 DoTouchEventsBlockScrollAt( | |
1744 testing::Property(&gfx::Point::x, testing::Lt(0)))) | |
1745 .WillOnce(testing::Return(false)); | |
1746 | |
1747 WebTouchEvent touch; | |
1748 touch.type = WebInputEvent::TouchStart; | |
1749 | |
1750 touch.touchesLength = 3; | |
1751 touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StateStationary, 0, 0); | |
1752 touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10); | |
1753 touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10); | |
1754 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch)); | |
1755 | |
1756 VERIFY_AND_RESET_MOCKS(); | |
1757 } | |
1758 | |
1759 TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestPositive) { | |
1760 // One of the touch points is on a touch-region. So the event should be sent | |
1761 // to the main thread. | |
1762 expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; | |
1763 VERIFY_AND_RESET_MOCKS(); | |
1764 | |
1765 EXPECT_CALL(mock_input_handler_, | |
1766 DoTouchEventsBlockScrollAt( | |
1767 testing::Property(&gfx::Point::x, testing::Eq(0)))) | |
1768 .WillOnce(testing::Return(false)); | |
1769 EXPECT_CALL(mock_input_handler_, | |
1770 DoTouchEventsBlockScrollAt( | |
1771 testing::Property(&gfx::Point::x, testing::Gt(0)))) | |
1772 .WillOnce(testing::Return(true)); | |
1773 // Since the second touch point hits a touch-region, there should be no | |
1774 // hit-testing for the third touch point. | |
1775 | |
1776 WebTouchEvent touch; | |
1777 touch.type = WebInputEvent::TouchStart; | |
1778 | |
1779 touch.touchesLength = 3; | |
1780 touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 0, 0); | |
1781 touch.touches[1] = CreateWebTouchPoint(WebTouchPoint::StatePressed, 10, 10); | |
1782 touch.touches[2] = CreateWebTouchPoint(WebTouchPoint::StatePressed, -10, 10); | |
1783 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch)); | |
1784 | |
1785 VERIFY_AND_RESET_MOCKS(); | |
1786 } | |
1787 | |
1788 TEST_P(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) { | |
1789 // We shouldn't send any events to the widget for this gesture. | |
1790 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1791 VERIFY_AND_RESET_MOCKS(); | |
1792 | |
1793 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1794 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1795 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1796 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1797 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1798 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1799 VERIFY_AND_RESET_MOCKS(); | |
1800 | |
1801 // Keyboard events received during a scroll should have no effect. | |
1802 WebKeyboardEvent key_event; | |
1803 key_event.type = WebInputEvent::KeyDown; | |
1804 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE, | |
1805 input_handler_->HandleInputEvent(key_event)); | |
1806 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1807 VERIFY_AND_RESET_MOCKS(); | |
1808 | |
1809 // On the fling start, animation should be scheduled, but no scrolling occurs. | |
1810 gesture_.type = WebInputEvent::GestureFlingStart; | |
1811 WebFloatPoint fling_delta = WebFloatPoint(100, 100); | |
1812 gesture_.data.flingStart.velocityX = fling_delta.x; | |
1813 gesture_.data.flingStart.velocityY = fling_delta.y; | |
1814 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1815 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1816 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1817 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1818 EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1819 VERIFY_AND_RESET_MOCKS(); | |
1820 | |
1821 // Keyboard events received during a fling should cancel the active fling. | |
1822 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1823 EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE, | |
1824 input_handler_->HandleInputEvent(key_event)); | |
1825 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1826 VERIFY_AND_RESET_MOCKS(); | |
1827 | |
1828 // The call to animate should have no effect, as the fling was cancelled. | |
1829 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
1830 Animate(time); | |
1831 VERIFY_AND_RESET_MOCKS(); | |
1832 | |
1833 // A fling cancel should be dropped, as there is nothing to cancel. | |
1834 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1835 EXPECT_EQ(InputHandlerProxy::DROP_EVENT, | |
1836 input_handler_->HandleInputEvent(gesture_)); | |
1837 EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing()); | |
1838 } | |
1839 | |
1840 TEST_P(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) { | |
1841 // We shouldn't send any events to the widget for this gesture. | |
1842 expected_disposition_ = InputHandlerProxy::DID_HANDLE; | |
1843 VERIFY_AND_RESET_MOCKS(); | |
1844 | |
1845 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
1846 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1847 | |
1848 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1849 gesture_.sourceDevice = blink::WebGestureDeviceTouchscreen; | |
1850 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1851 | |
1852 VERIFY_AND_RESET_MOCKS(); | |
1853 | |
1854 // On the fling start, we should schedule an animation but not actually start | |
1855 // scrolling. | |
1856 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
1857 base::TimeTicks time = base::TimeTicks() + dt; | |
1858 WebFloatPoint fling_delta = WebFloatPoint(100, 0); | |
1859 WebPoint fling_point = WebPoint(7, 13); | |
1860 WebPoint fling_global_point = WebPoint(17, 23); | |
1861 int modifiers = WebInputEvent::ControlKey; | |
1862 gesture_ = CreateFling(time, | |
1863 blink::WebGestureDeviceTouchscreen, | |
1864 fling_delta, | |
1865 fling_point, | |
1866 fling_global_point, | |
1867 modifiers); | |
1868 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1869 EXPECT_CALL(mock_input_handler_, FlingScrollBegin()) | |
1870 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
1871 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1872 | |
1873 VERIFY_AND_RESET_MOCKS(); | |
1874 | |
1875 // If we get a negative time delta, that is, the Animation tick time happens | |
1876 // before the fling's start time then we should *not* try scrolling and | |
1877 // instead reset the fling start time. | |
1878 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1879 EXPECT_CALL(mock_input_handler_, | |
1880 ScrollBy(testing::_, | |
1881 testing::_)).Times(0); | |
1882 time -= base::TimeDelta::FromMilliseconds(5); | |
1883 Animate(time); | |
1884 | |
1885 VERIFY_AND_RESET_MOCKS(); | |
1886 | |
1887 // The first call should have reset the start time so subsequent calls should | |
1888 // generate scroll events. | |
1889 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1890 EXPECT_CALL(mock_input_handler_, | |
1891 ScrollBy(testing::_, | |
1892 testing::Property(&gfx::Vector2dF::x, testing::Lt(0)))) | |
1893 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1894 | |
1895 Animate(time + base::TimeDelta::FromMilliseconds(1)); | |
1896 | |
1897 VERIFY_AND_RESET_MOCKS(); | |
1898 | |
1899 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
1900 gesture_.type = WebInputEvent::GestureFlingCancel; | |
1901 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1902 | |
1903 VERIFY_AND_RESET_MOCKS(); | |
1904 } | |
1905 | |
1906 TEST_P(InputHandlerProxyTest, FlingBoost) { | |
1907 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
1908 base::TimeTicks time = base::TimeTicks() + dt; | |
1909 base::TimeTicks last_animate_time = time; | |
1910 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
1911 WebPoint fling_point = WebPoint(7, 13); | |
1912 StartFling( | |
1913 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
1914 | |
1915 // Now cancel the fling. The fling cancellation should be deferred to allow | |
1916 // fling boosting events to arrive. | |
1917 time += dt; | |
1918 CancelFling(time); | |
1919 | |
1920 // The GestureScrollBegin should be swallowed by the fling if it hits the same | |
1921 // scrolling layer. | |
1922 EXPECT_CALL(mock_input_handler_, | |
1923 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) | |
1924 .WillOnce(testing::Return(true)); | |
1925 | |
1926 time += dt; | |
1927 gesture_.timeStampSeconds = InSecondsF(time); | |
1928 gesture_.type = WebInputEvent::GestureScrollBegin; | |
1929 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1930 | |
1931 VERIFY_AND_RESET_MOCKS(); | |
1932 | |
1933 // Animate calls within the deferred cancellation window should continue. | |
1934 time += dt; | |
1935 float expected_delta = | |
1936 (time - last_animate_time).InSecondsF() * -fling_delta.x; | |
1937 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1938 EXPECT_CALL(mock_input_handler_, | |
1939 ScrollBy(testing::_, | |
1940 testing::Property(&gfx::Vector2dF::x, | |
1941 testing::Eq(expected_delta)))) | |
1942 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1943 Animate(time); | |
1944 last_animate_time = time; | |
1945 | |
1946 VERIFY_AND_RESET_MOCKS(); | |
1947 | |
1948 // GestureScrollUpdates in the same direction and at sufficient speed should | |
1949 // be swallowed by the fling. | |
1950 time += dt; | |
1951 gesture_.timeStampSeconds = InSecondsF(time); | |
1952 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
1953 gesture_.data.scrollUpdate.deltaX = fling_delta.x; | |
1954 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1955 | |
1956 VERIFY_AND_RESET_MOCKS(); | |
1957 | |
1958 // Animate calls within the deferred cancellation window should continue. | |
1959 time += dt; | |
1960 expected_delta = (time - last_animate_time).InSecondsF() * -fling_delta.x; | |
1961 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1962 EXPECT_CALL(mock_input_handler_, | |
1963 ScrollBy(testing::_, | |
1964 testing::Property(&gfx::Vector2dF::x, | |
1965 testing::Eq(expected_delta)))) | |
1966 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1967 Animate(time); | |
1968 last_animate_time = time; | |
1969 | |
1970 VERIFY_AND_RESET_MOCKS(); | |
1971 | |
1972 // GestureFlingStart in the same direction and at sufficient speed should | |
1973 // boost the active fling. | |
1974 | |
1975 gesture_ = CreateFling(time, | |
1976 blink::WebGestureDeviceTouchscreen, | |
1977 fling_delta, | |
1978 fling_point, | |
1979 fling_point, | |
1980 0); | |
1981 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
1982 VERIFY_AND_RESET_MOCKS(); | |
1983 | |
1984 time += dt; | |
1985 // Note we get *2x* as much delta because 2 flings have combined. | |
1986 expected_delta = 2 * (time - last_animate_time).InSecondsF() * -fling_delta.x; | |
1987 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
1988 EXPECT_CALL(mock_input_handler_, | |
1989 ScrollBy(testing::_, | |
1990 testing::Property(&gfx::Vector2dF::x, | |
1991 testing::Eq(expected_delta)))) | |
1992 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
1993 Animate(time); | |
1994 last_animate_time = time; | |
1995 | |
1996 VERIFY_AND_RESET_MOCKS(); | |
1997 | |
1998 // Repeated GestureFlingStarts should accumulate. | |
1999 | |
2000 CancelFling(time); | |
2001 gesture_ = CreateFling(time, | |
2002 blink::WebGestureDeviceTouchscreen, | |
2003 fling_delta, | |
2004 fling_point, | |
2005 fling_point, | |
2006 0); | |
2007 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2008 VERIFY_AND_RESET_MOCKS(); | |
2009 | |
2010 time += dt; | |
2011 // Note we get *3x* as much delta because 3 flings have combined. | |
2012 expected_delta = 3 * (time - last_animate_time).InSecondsF() * -fling_delta.x; | |
2013 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
2014 EXPECT_CALL(mock_input_handler_, | |
2015 ScrollBy(testing::_, | |
2016 testing::Property(&gfx::Vector2dF::x, | |
2017 testing::Eq(expected_delta)))) | |
2018 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
2019 Animate(time); | |
2020 last_animate_time = time; | |
2021 | |
2022 VERIFY_AND_RESET_MOCKS(); | |
2023 | |
2024 // GestureFlingCancel should terminate the fling if no boosting gestures are | |
2025 // received within the timeout window. | |
2026 | |
2027 time += dt; | |
2028 gesture_.timeStampSeconds = InSecondsF(time); | |
2029 gesture_.type = WebInputEvent::GestureFlingCancel; | |
2030 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2031 | |
2032 VERIFY_AND_RESET_MOCKS(); | |
2033 | |
2034 time += base::TimeDelta::FromMilliseconds(100); | |
2035 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2036 Animate(time); | |
2037 | |
2038 VERIFY_AND_RESET_MOCKS(); | |
2039 } | |
2040 | |
2041 TEST_P(InputHandlerProxyTest, NoFlingBoostIfScrollTargetsDifferentLayer) { | |
2042 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2043 base::TimeTicks time = base::TimeTicks() + dt; | |
2044 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2045 WebPoint fling_point = WebPoint(7, 13); | |
2046 StartFling( | |
2047 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2048 | |
2049 // Cancel the fling. The fling cancellation should be deferred to allow | |
2050 // fling boosting events to arrive. | |
2051 time += dt; | |
2052 CancelFling(time); | |
2053 | |
2054 // If the GestureScrollBegin targets a different layer, the fling should be | |
2055 // cancelled and the scroll should be handled as usual. | |
2056 EXPECT_CALL(mock_input_handler_, | |
2057 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) | |
2058 .WillOnce(testing::Return(false)); | |
2059 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2060 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
2061 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
2062 | |
2063 time += dt; | |
2064 gesture_.timeStampSeconds = InSecondsF(time); | |
2065 gesture_.type = WebInputEvent::GestureScrollBegin; | |
2066 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2067 | |
2068 VERIFY_AND_RESET_MOCKS(); | |
2069 } | |
2070 | |
2071 TEST_P(InputHandlerProxyTest, NoFlingBoostIfScrollDelayed) { | |
2072 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2073 base::TimeTicks time = base::TimeTicks() + dt; | |
2074 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2075 WebPoint fling_point = WebPoint(7, 13); | |
2076 StartFling( | |
2077 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2078 | |
2079 // Cancel the fling. The fling cancellation should be deferred to allow | |
2080 // fling boosting events to arrive. | |
2081 time += dt; | |
2082 CancelFling(time); | |
2083 | |
2084 // The GestureScrollBegin should be swallowed by the fling if it hits the same | |
2085 // scrolling layer. | |
2086 EXPECT_CALL(mock_input_handler_, | |
2087 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) | |
2088 .WillOnce(testing::Return(true)); | |
2089 | |
2090 time += dt; | |
2091 gesture_.timeStampSeconds = InSecondsF(time); | |
2092 gesture_.type = WebInputEvent::GestureScrollBegin; | |
2093 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2094 | |
2095 VERIFY_AND_RESET_MOCKS(); | |
2096 | |
2097 // If no GestureScrollUpdate or GestureFlingStart is received within the | |
2098 // timeout window, the fling should be cancelled and scrolling should resume. | |
2099 time += base::TimeDelta::FromMilliseconds(100); | |
2100 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2101 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
2102 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
2103 Animate(time); | |
2104 | |
2105 VERIFY_AND_RESET_MOCKS(); | |
2106 } | |
2107 | |
2108 TEST_P(InputHandlerProxyTest, NoFlingBoostIfNotAnimated) { | |
2109 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2110 base::TimeTicks time = base::TimeTicks() + dt; | |
2111 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2112 WebPoint fling_point = WebPoint(7, 13); | |
2113 StartFling( | |
2114 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2115 | |
2116 // Animate fling once. | |
2117 time += dt; | |
2118 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)) | |
2119 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
2120 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
2121 Animate(time); | |
2122 | |
2123 // Cancel the fling after long delay of no animate. The fling cancellation | |
2124 // should be deferred to allow fling boosting events to arrive. | |
2125 time += base::TimeDelta::FromMilliseconds(100); | |
2126 CancelFling(time); | |
2127 | |
2128 // The GestureScrollBegin should be swallowed by the fling if it hits the same | |
2129 // scrolling layer. | |
2130 EXPECT_CALL(mock_input_handler_, | |
2131 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) | |
2132 .WillOnce(testing::Return(true)); | |
2133 | |
2134 time += dt; | |
2135 gesture_.timeStampSeconds = InSecondsF(time); | |
2136 gesture_.type = WebInputEvent::GestureScrollBegin; | |
2137 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2138 | |
2139 VERIFY_AND_RESET_MOCKS(); | |
2140 | |
2141 // Should exit scroll bosting on GestureScrollUpdate due to long delay | |
2142 // since last animate. Cancel old fling and start new scroll. | |
2143 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
2144 gesture_.data.scrollUpdate.deltaY = -40; | |
2145 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2146 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
2147 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
2148 EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)) | |
2149 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
2150 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2151 | |
2152 VERIFY_AND_RESET_MOCKS(); | |
2153 } | |
2154 | |
2155 TEST_P(InputHandlerProxyTest, NoFlingBoostIfFlingInDifferentDirection) { | |
2156 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2157 base::TimeTicks time = base::TimeTicks() + dt; | |
2158 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2159 WebPoint fling_point = WebPoint(7, 13); | |
2160 StartFling( | |
2161 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2162 | |
2163 // Cancel the fling. The fling cancellation should be deferred to allow | |
2164 // fling boosting events to arrive. | |
2165 time += dt; | |
2166 CancelFling(time); | |
2167 | |
2168 // If the new fling is orthogonal to the existing fling, no boosting should | |
2169 // take place, with the new fling replacing the old. | |
2170 WebFloatPoint orthogonal_fling_delta = | |
2171 WebFloatPoint(fling_delta.y, -fling_delta.x); | |
2172 gesture_ = CreateFling(time, | |
2173 blink::WebGestureDeviceTouchscreen, | |
2174 orthogonal_fling_delta, | |
2175 fling_point, | |
2176 fling_point, | |
2177 0); | |
2178 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2179 | |
2180 VERIFY_AND_RESET_MOCKS(); | |
2181 | |
2182 // Note that the new fling delta uses the orthogonal, unboosted fling | |
2183 // velocity. | |
2184 time += dt; | |
2185 float expected_delta = dt.InSecondsF() * -orthogonal_fling_delta.y; | |
2186 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
2187 EXPECT_CALL(mock_input_handler_, | |
2188 ScrollBy(testing::_, | |
2189 testing::Property(&gfx::Vector2dF::y, | |
2190 testing::Eq(expected_delta)))) | |
2191 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
2192 Animate(time); | |
2193 | |
2194 VERIFY_AND_RESET_MOCKS(); | |
2195 } | |
2196 | |
2197 TEST_P(InputHandlerProxyTest, NoFlingBoostIfScrollInDifferentDirection) { | |
2198 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2199 base::TimeTicks time = base::TimeTicks() + dt; | |
2200 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2201 WebPoint fling_point = WebPoint(7, 13); | |
2202 StartFling( | |
2203 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2204 | |
2205 // Cancel the fling. The fling cancellation should be deferred to allow | |
2206 // fling boosting events to arrive. | |
2207 time += dt; | |
2208 CancelFling(time); | |
2209 | |
2210 // The GestureScrollBegin should be swallowed by the fling if it hits the same | |
2211 // scrolling layer. | |
2212 EXPECT_CALL(mock_input_handler_, | |
2213 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) | |
2214 .WillOnce(testing::Return(true)); | |
2215 | |
2216 time += dt; | |
2217 gesture_.timeStampSeconds = InSecondsF(time); | |
2218 gesture_.type = WebInputEvent::GestureScrollBegin; | |
2219 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2220 | |
2221 VERIFY_AND_RESET_MOCKS(); | |
2222 | |
2223 // If the GestureScrollUpdate is in a different direction than the fling, | |
2224 // the fling should be cancelled and scrolling should resume. | |
2225 time += dt; | |
2226 gesture_.timeStampSeconds = InSecondsF(time); | |
2227 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
2228 gesture_.data.scrollUpdate.deltaX = -fling_delta.x; | |
2229 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2230 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
2231 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
2232 EXPECT_CALL(mock_input_handler_, | |
2233 ScrollBy(testing::_, | |
2234 testing::Property(&gfx::Vector2dF::x, | |
2235 testing::Eq(fling_delta.x)))) | |
2236 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
2237 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2238 | |
2239 VERIFY_AND_RESET_MOCKS(); | |
2240 } | |
2241 | |
2242 TEST_P(InputHandlerProxyTest, NoFlingBoostIfFlingTooSlow) { | |
2243 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2244 base::TimeTicks time = base::TimeTicks() + dt; | |
2245 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2246 WebPoint fling_point = WebPoint(7, 13); | |
2247 StartFling( | |
2248 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2249 | |
2250 // Cancel the fling. The fling cancellation should be deferred to allow | |
2251 // fling boosting events to arrive. | |
2252 time += dt; | |
2253 CancelFling(time); | |
2254 | |
2255 // If the new fling is too slow, no boosting should take place, with the new | |
2256 // fling replacing the old. | |
2257 WebFloatPoint small_fling_delta = WebFloatPoint(100, 0); | |
2258 gesture_ = CreateFling(time, | |
2259 blink::WebGestureDeviceTouchscreen, | |
2260 small_fling_delta, | |
2261 fling_point, | |
2262 fling_point, | |
2263 0); | |
2264 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2265 | |
2266 VERIFY_AND_RESET_MOCKS(); | |
2267 | |
2268 // Note that the new fling delta uses the *slow*, unboosted fling velocity. | |
2269 time += dt; | |
2270 float expected_delta = dt.InSecondsF() * -small_fling_delta.x; | |
2271 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
2272 EXPECT_CALL(mock_input_handler_, | |
2273 ScrollBy(testing::_, | |
2274 testing::Property(&gfx::Vector2dF::x, | |
2275 testing::Eq(expected_delta)))) | |
2276 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
2277 Animate(time); | |
2278 | |
2279 VERIFY_AND_RESET_MOCKS(); | |
2280 } | |
2281 | |
2282 TEST_P(InputHandlerProxyTest, NoFlingBoostIfPreventBoostingFlagIsSet) { | |
2283 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2284 base::TimeTicks time = base::TimeTicks() + dt; | |
2285 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2286 WebPoint fling_point = WebPoint(7, 13); | |
2287 | |
2288 StartFling( | |
2289 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2290 | |
2291 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2292 | |
2293 // Cancel the fling. The fling cancellation should not be deferred because of | |
2294 // prevent boosting flag set. | |
2295 gesture_.data.flingCancel.preventBoosting = true; | |
2296 time += dt; | |
2297 CancelFling(time); | |
2298 | |
2299 // VERIFY_AND_RESET_MOCKS already called by CancelFling | |
2300 } | |
2301 | |
2302 TEST_P(InputHandlerProxyTest, FlingBoostTerminatedDuringScrollSequence) { | |
2303 base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10); | |
2304 base::TimeTicks time = base::TimeTicks() + dt; | |
2305 base::TimeTicks last_animate_time = time; | |
2306 WebFloatPoint fling_delta = WebFloatPoint(1000, 0); | |
2307 WebPoint fling_point = WebPoint(7, 13); | |
2308 StartFling( | |
2309 time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point); | |
2310 | |
2311 // Now cancel the fling. The fling cancellation should be deferred to allow | |
2312 // fling boosting events to arrive. | |
2313 time += dt; | |
2314 CancelFling(time); | |
2315 | |
2316 // The GestureScrollBegin should be swallowed by the fling. | |
2317 time += dt; | |
2318 gesture_.timeStampSeconds = InSecondsF(time); | |
2319 gesture_.type = WebInputEvent::GestureScrollBegin; | |
2320 EXPECT_CALL(mock_input_handler_, | |
2321 IsCurrentlyScrollingLayerAt(testing::_, testing::_)) | |
2322 .WillOnce(testing::Return(true)); | |
2323 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2324 | |
2325 VERIFY_AND_RESET_MOCKS(); | |
2326 | |
2327 // Now animate the fling to completion (in this case, the fling should | |
2328 // terminate because the input handler reports a failed scroll). As the fling | |
2329 // was cancelled during an active scroll sequence, a synthetic | |
2330 // GestureScrollBegin should be processed, resuming the scroll. | |
2331 time += dt; | |
2332 float expected_delta = | |
2333 (time - last_animate_time).InSecondsF() * -fling_delta.x; | |
2334 EXPECT_CALL(mock_input_handler_, | |
2335 ScrollBy(testing::_, | |
2336 testing::Property(&gfx::Vector2dF::x, | |
2337 testing::Eq(expected_delta)))) | |
2338 .WillOnce(testing::Return(scroll_result_did_not_scroll_)); | |
2339 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2340 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
2341 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
2342 Animate(time); | |
2343 | |
2344 VERIFY_AND_RESET_MOCKS(); | |
2345 | |
2346 // Subsequent GestureScrollUpdates after the cancelled, boosted fling should | |
2347 // cause scrolling as usual. | |
2348 time += dt; | |
2349 expected_delta = 7.3f; | |
2350 gesture_.timeStampSeconds = InSecondsF(time); | |
2351 gesture_.type = WebInputEvent::GestureScrollUpdate; | |
2352 gesture_.data.scrollUpdate.deltaX = -expected_delta; | |
2353 EXPECT_CALL(mock_input_handler_, | |
2354 ScrollBy(testing::_, | |
2355 testing::Property(&gfx::Vector2dF::x, | |
2356 testing::Eq(expected_delta)))) | |
2357 .WillOnce(testing::Return(scroll_result_did_scroll_)); | |
2358 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2359 | |
2360 VERIFY_AND_RESET_MOCKS(); | |
2361 | |
2362 // GestureScrollEnd should terminate the resumed scroll properly. | |
2363 time += dt; | |
2364 gesture_.timeStampSeconds = InSecondsF(time); | |
2365 gesture_.type = WebInputEvent::GestureScrollEnd; | |
2366 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2367 EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_)); | |
2368 | |
2369 VERIFY_AND_RESET_MOCKS(); | |
2370 } | |
2371 | |
2372 TEST_P(InputHandlerProxyTest, DidReceiveInputEvent_ForFling) { | |
2373 testing::StrictMock<MockInputHandlerProxyClientWithDidAnimateForInput> | |
2374 mock_client; | |
2375 input_handler_.reset( | |
2376 new content::InputHandlerProxy(&mock_input_handler_, &mock_client)); | |
2377 if (install_synchronous_handler_) { | |
2378 EXPECT_CALL(mock_input_handler_, RequestUpdateForSynchronousInputHandler()) | |
2379 .Times(1); | |
2380 input_handler_->SetOnlySynchronouslyAnimateRootFlings( | |
2381 &mock_synchronous_input_handler_); | |
2382 } | |
2383 mock_input_handler_.set_is_scrolling_root(synchronous_root_scroll_); | |
2384 | |
2385 gesture_.type = WebInputEvent::GestureFlingStart; | |
2386 WebFloatPoint fling_delta = WebFloatPoint(100, 100); | |
2387 gesture_.data.flingStart.velocityX = fling_delta.x; | |
2388 gesture_.data.flingStart.velocityY = fling_delta.y; | |
2389 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
2390 EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) | |
2391 .WillOnce(testing::Return(cc::InputHandler::SCROLL_STARTED)); | |
2392 EXPECT_CALL(mock_input_handler_, ScrollEnd()); | |
2393 EXPECT_EQ(InputHandlerProxy::DID_HANDLE, | |
2394 input_handler_->HandleInputEvent(gesture_)); | |
2395 VERIFY_AND_RESET_MOCKS(); | |
2396 | |
2397 EXPECT_SET_NEEDS_ANIMATE_INPUT(1); | |
2398 EXPECT_CALL(mock_client, DidAnimateForInput()); | |
2399 base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10); | |
2400 Animate(time); | |
2401 | |
2402 VERIFY_AND_RESET_MOCKS(); | |
2403 } | |
2404 | |
2405 TEST(SynchronousInputHandlerProxyTest, StartupShutdown) { | |
2406 testing::StrictMock<MockInputHandler> mock_input_handler; | |
2407 testing::StrictMock<MockInputHandlerProxyClient> mock_client; | |
2408 testing::StrictMock<MockSynchronousInputHandler> | |
2409 mock_synchronous_input_handler; | |
2410 content::InputHandlerProxy proxy(&mock_input_handler, &mock_client); | |
2411 | |
2412 // When adding a SynchronousInputHandler, immediately request an | |
2413 // UpdateRootLayerStateForSynchronousInputHandler() call. | |
2414 EXPECT_CALL(mock_input_handler, RequestUpdateForSynchronousInputHandler()) | |
2415 .Times(1); | |
2416 proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler); | |
2417 | |
2418 testing::Mock::VerifyAndClearExpectations(&mock_input_handler); | |
2419 testing::Mock::VerifyAndClearExpectations(&mock_client); | |
2420 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler); | |
2421 | |
2422 EXPECT_CALL(mock_input_handler, RequestUpdateForSynchronousInputHandler()) | |
2423 .Times(0); | |
2424 proxy.SetOnlySynchronouslyAnimateRootFlings(nullptr); | |
2425 | |
2426 testing::Mock::VerifyAndClearExpectations(&mock_input_handler); | |
2427 testing::Mock::VerifyAndClearExpectations(&mock_client); | |
2428 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler); | |
2429 } | |
2430 | |
2431 TEST(SynchronousInputHandlerProxyTest, UpdateRootLayerState) { | |
2432 testing::NiceMock<MockInputHandler> mock_input_handler; | |
2433 testing::StrictMock<MockInputHandlerProxyClient> mock_client; | |
2434 testing::StrictMock<MockSynchronousInputHandler> | |
2435 mock_synchronous_input_handler; | |
2436 content::InputHandlerProxy proxy(&mock_input_handler, &mock_client); | |
2437 | |
2438 proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler); | |
2439 | |
2440 // When adding a SynchronousInputHandler, immediately request an | |
2441 // UpdateRootLayerStateForSynchronousInputHandler() call. | |
2442 EXPECT_CALL( | |
2443 mock_synchronous_input_handler, | |
2444 UpdateRootLayerState(gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4), | |
2445 gfx::SizeF(5, 6), 7, 8, 9)) | |
2446 .Times(1); | |
2447 proxy.UpdateRootLayerStateForSynchronousInputHandler( | |
2448 gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4), gfx::SizeF(5, 6), 7, 8, | |
2449 9); | |
2450 | |
2451 testing::Mock::VerifyAndClearExpectations(&mock_input_handler); | |
2452 testing::Mock::VerifyAndClearExpectations(&mock_client); | |
2453 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler); | |
2454 } | |
2455 | |
2456 TEST(SynchronousInputHandlerProxyTest, SetOffset) { | |
2457 testing::NiceMock<MockInputHandler> mock_input_handler; | |
2458 testing::StrictMock<MockInputHandlerProxyClient> mock_client; | |
2459 testing::StrictMock<MockSynchronousInputHandler> | |
2460 mock_synchronous_input_handler; | |
2461 content::InputHandlerProxy proxy(&mock_input_handler, &mock_client); | |
2462 | |
2463 proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler); | |
2464 | |
2465 EXPECT_CALL(mock_input_handler, SetSynchronousInputHandlerRootScrollOffset( | |
2466 gfx::ScrollOffset(5, 6))); | |
2467 proxy.SynchronouslySetRootScrollOffset(gfx::ScrollOffset(5, 6)); | |
2468 | |
2469 testing::Mock::VerifyAndClearExpectations(&mock_input_handler); | |
2470 testing::Mock::VerifyAndClearExpectations(&mock_client); | |
2471 testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler); | |
2472 } | |
2473 | |
2474 INSTANTIATE_TEST_CASE_P(AnimateInput, | |
2475 InputHandlerProxyTest, | |
2476 testing::ValuesIn(test_types)); | |
2477 } // namespace test | |
2478 } // namespace content | |
OLD | NEW |