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