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.
6 #include "base/memory/scoped_ptr.h"
7 #include "base/time/time.h"
8 #include "content/browser/renderer_host/input/synthetic_gesture.h"
9 #include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
10 #include "content/browser/renderer_host/input/synthetic_gesture_target.h"
11 #include "content/browser/renderer_host/input/synthetic_pinch_gesture.h"
12 #include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
13 #include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
14 #include "content/browser/renderer_host/render_widget_host_delegate.h"
15 #include "content/common/input/synthetic_pinch_gesture_params.h"
16 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
17 #include "content/common/input/synthetic_tap_gesture_params.h"
18 #include "content/public/test/mock_render_process_host.h"
19 #include "content/public/test/test_browser_context.h"
20 #include "content/test/test_render_view_host.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/WebKit/public/web/WebInputEvent.h"
23 #include "ui/gfx/point.h"
24 #include "ui/gfx/point_f.h"
25 #include "ui/gfx/vector2d.h"
26 #include "ui/gfx/vector2d_f.h"
28 using blink::WebInputEvent
;
29 using blink::WebMouseEvent
;
30 using blink::WebMouseWheelEvent
;
31 using blink::WebTouchEvent
;
37 const int kFlushInputRateInMs
= 16;
38 const int kPointerAssumedStoppedTimeMs
= 43;
39 const int kTouchSlopInDips
= 7;
41 class MockSyntheticGesture
: public SyntheticGesture
{
43 MockSyntheticGesture(bool* finished
, int num_steps
)
44 : finished_(finished
),
45 num_steps_(num_steps
),
49 virtual ~MockSyntheticGesture() {}
51 virtual Result
ForwardInputEvents(const base::TimeTicks
& timestamp
,
52 SyntheticGestureTarget
* target
) OVERRIDE
{
54 if (step_count_
== num_steps_
) {
56 return SyntheticGesture::GESTURE_FINISHED
;
57 } else if (step_count_
> num_steps_
) {
59 // Return arbitrary failure.
60 return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED
;
63 return SyntheticGesture::GESTURE_RUNNING
;
72 class MockSyntheticGestureTarget
: public SyntheticGestureTarget
{
74 MockSyntheticGestureTarget()
75 : flush_requested_(false),
76 pointer_assumed_stopped_time_ms_(kPointerAssumedStoppedTimeMs
) {}
77 virtual ~MockSyntheticGestureTarget() {}
79 // SyntheticGestureTarget:
80 virtual void DispatchInputEventToPlatform(
81 const WebInputEvent
& event
) OVERRIDE
{}
83 virtual void SetNeedsFlush() OVERRIDE
{
84 flush_requested_
= true;
87 virtual SyntheticGestureParams::GestureSourceType
88 GetDefaultSyntheticGestureSourceType() const OVERRIDE
{
89 return SyntheticGestureParams::TOUCH_INPUT
;
92 virtual base::TimeDelta
PointerAssumedStoppedTime() const OVERRIDE
{
93 return base::TimeDelta::FromMilliseconds(pointer_assumed_stopped_time_ms_
);
96 void set_pointer_assumed_stopped_time_ms(int time_ms
) {
97 pointer_assumed_stopped_time_ms_
= time_ms
;
100 virtual int GetTouchSlopInDips() const OVERRIDE
{
101 return kTouchSlopInDips
;
104 bool flush_requested() const { return flush_requested_
; }
105 void ClearFlushRequest() { flush_requested_
= false; }
108 bool flush_requested_
;
110 int pointer_assumed_stopped_time_ms_
;
113 class MockScrollGestureTarget
: public MockSyntheticGestureTarget
{
115 MockScrollGestureTarget() : total_abs_scroll_distance_length_(0) {}
116 virtual ~MockScrollGestureTarget() {}
118 gfx::Vector2dF
start_to_end_distance() const {
119 return start_to_end_distance_
;
121 float total_abs_scroll_distance_length() const {
122 return total_abs_scroll_distance_length_
;
126 gfx::Vector2dF start_to_end_distance_
;
127 float total_abs_scroll_distance_length_
;
130 class MockScrollMouseTarget
: public MockScrollGestureTarget
{
132 MockScrollMouseTarget() {}
133 virtual ~MockScrollMouseTarget() {}
135 virtual void DispatchInputEventToPlatform(
136 const WebInputEvent
& event
) OVERRIDE
{
137 ASSERT_EQ(event
.type
, WebInputEvent::MouseWheel
);
138 const WebMouseWheelEvent
& mouse_wheel_event
=
139 static_cast<const WebMouseWheelEvent
&>(event
);
140 gfx::Vector2dF
delta(mouse_wheel_event
.deltaX
, mouse_wheel_event
.deltaY
);
141 start_to_end_distance_
+= delta
;
142 total_abs_scroll_distance_length_
+= delta
.Length();
146 class MockScrollTouchTarget
: public MockScrollGestureTarget
{
148 MockScrollTouchTarget() : started_(false) {}
149 virtual ~MockScrollTouchTarget() {}
151 virtual void DispatchInputEventToPlatform(
152 const WebInputEvent
& event
) OVERRIDE
{
153 ASSERT_TRUE(WebInputEvent::isTouchEventType(event
.type
));
154 const WebTouchEvent
& touch_event
= static_cast<const WebTouchEvent
&>(event
);
155 ASSERT_EQ(touch_event
.touchesLength
, 1U);
158 ASSERT_EQ(touch_event
.type
, WebInputEvent::TouchStart
);
159 start_
.SetPoint(touch_event
.touches
[0].position
.x
,
160 touch_event
.touches
[0].position
.y
);
161 last_touch_point_
= start_
;
164 ASSERT_NE(touch_event
.type
, WebInputEvent::TouchStart
);
165 ASSERT_NE(touch_event
.type
, WebInputEvent::TouchCancel
);
167 gfx::PointF
touch_point(touch_event
.touches
[0].position
.x
,
168 touch_event
.touches
[0].position
.y
);
169 gfx::Vector2dF delta
= touch_point
- last_touch_point_
;
170 total_abs_scroll_distance_length_
+= delta
.Length();
172 if (touch_event
.type
== WebInputEvent::TouchEnd
)
173 start_to_end_distance_
= touch_point
- start_
;
175 last_touch_point_
= touch_point
;
181 gfx::PointF last_touch_point_
;
185 class MockSyntheticPinchTouchTarget
: public MockSyntheticGestureTarget
{
188 ZOOM_DIRECTION_UNKNOWN
,
193 MockSyntheticPinchTouchTarget()
194 : total_num_pixels_covered_(0),
195 last_pointer_distance_(0),
196 zoom_direction_(ZOOM_DIRECTION_UNKNOWN
),
198 virtual ~MockSyntheticPinchTouchTarget() {}
200 virtual void DispatchInputEventToPlatform(
201 const WebInputEvent
& event
) OVERRIDE
{
202 ASSERT_TRUE(WebInputEvent::isTouchEventType(event
.type
));
203 const WebTouchEvent
& touch_event
= static_cast<const WebTouchEvent
&>(event
);
204 ASSERT_EQ(touch_event
.touchesLength
, 2U);
207 ASSERT_EQ(touch_event
.type
, WebInputEvent::TouchStart
);
209 start_0_
= gfx::PointF(touch_event
.touches
[0].position
);
210 start_1_
= gfx::PointF(touch_event
.touches
[1].position
);
211 last_pointer_distance_
= (start_0_
- start_1_
).Length();
215 ASSERT_NE(touch_event
.type
, WebInputEvent::TouchStart
);
216 ASSERT_NE(touch_event
.type
, WebInputEvent::TouchCancel
);
218 gfx::PointF current_0
= gfx::PointF(touch_event
.touches
[0].position
);
219 gfx::PointF current_1
= gfx::PointF(touch_event
.touches
[1].position
);
221 total_num_pixels_covered_
=
222 (current_0
- start_0_
).Length() + (current_1
- start_1_
).Length();
223 float pointer_distance
= (current_0
- current_1
).Length();
225 if (last_pointer_distance_
!= pointer_distance
) {
226 if (zoom_direction_
== ZOOM_DIRECTION_UNKNOWN
)
228 ComputeZoomDirection(last_pointer_distance_
, pointer_distance
);
232 ComputeZoomDirection(last_pointer_distance_
, pointer_distance
));
235 last_pointer_distance_
= pointer_distance
;
239 float total_num_pixels_covered() const { return total_num_pixels_covered_
; }
240 ZoomDirection
zoom_direction() const { return zoom_direction_
; }
243 ZoomDirection
ComputeZoomDirection(float last_pointer_distance
,
244 float current_pointer_distance
) {
245 DCHECK_NE(last_pointer_distance
, current_pointer_distance
);
246 return last_pointer_distance
< current_pointer_distance
? ZOOM_IN
250 float total_num_pixels_covered_
;
251 float last_pointer_distance_
;
252 ZoomDirection zoom_direction_
;
253 gfx::PointF start_0_
;
254 gfx::PointF start_1_
;
258 class MockSyntheticTapGestureTarget
: public MockSyntheticGestureTarget
{
260 MockSyntheticTapGestureTarget() : state_(NOT_STARTED
) {}
261 virtual ~MockSyntheticTapGestureTarget() {}
263 bool GestureFinished() const { return state_
== FINISHED
; }
264 gfx::PointF
position() const { return position_
; }
265 base::TimeDelta
GetDuration() const { return stop_time_
- start_time_
; }
274 gfx::PointF position_
;
275 base::TimeDelta start_time_
;
276 base::TimeDelta stop_time_
;
280 class MockSyntheticTapTouchTarget
: public MockSyntheticTapGestureTarget
{
282 MockSyntheticTapTouchTarget() {}
283 virtual ~MockSyntheticTapTouchTarget() {}
285 virtual void DispatchInputEventToPlatform(
286 const WebInputEvent
& event
) OVERRIDE
{
287 ASSERT_TRUE(WebInputEvent::isTouchEventType(event
.type
));
288 const WebTouchEvent
& touch_event
= static_cast<const WebTouchEvent
&>(event
);
289 ASSERT_EQ(touch_event
.touchesLength
, 1U);
293 EXPECT_EQ(touch_event
.type
, WebInputEvent::TouchStart
);
294 position_
= gfx::PointF(touch_event
.touches
[0].position
);
295 start_time_
= base::TimeDelta::FromMilliseconds(
296 static_cast<int64
>(touch_event
.timeStampSeconds
* 1000));
300 EXPECT_EQ(touch_event
.type
, WebInputEvent::TouchEnd
);
301 EXPECT_EQ(position_
, gfx::PointF(touch_event
.touches
[0].position
));
302 stop_time_
= base::TimeDelta::FromMilliseconds(
303 static_cast<int64
>(touch_event
.timeStampSeconds
* 1000));
313 class MockSyntheticTapMouseTarget
: public MockSyntheticTapGestureTarget
{
315 MockSyntheticTapMouseTarget() {}
316 virtual ~MockSyntheticTapMouseTarget() {}
318 virtual void DispatchInputEventToPlatform(
319 const WebInputEvent
& event
) OVERRIDE
{
320 ASSERT_TRUE(WebInputEvent::isMouseEventType(event
.type
));
321 const WebMouseEvent
& mouse_event
= static_cast<const WebMouseEvent
&>(event
);
325 EXPECT_EQ(mouse_event
.type
, WebInputEvent::MouseDown
);
326 EXPECT_EQ(mouse_event
.button
, WebMouseEvent::ButtonLeft
);
327 EXPECT_EQ(mouse_event
.clickCount
, 1);
328 position_
= gfx::PointF(mouse_event
.x
, mouse_event
.y
);
329 start_time_
= base::TimeDelta::FromMilliseconds(
330 static_cast<int64
>(mouse_event
.timeStampSeconds
* 1000));
334 EXPECT_EQ(mouse_event
.type
, WebInputEvent::MouseUp
);
335 EXPECT_EQ(mouse_event
.button
, WebMouseEvent::ButtonLeft
);
336 EXPECT_EQ(mouse_event
.clickCount
, 1);
337 EXPECT_EQ(position_
, gfx::PointF(mouse_event
.x
, mouse_event
.y
));
338 stop_time_
= base::TimeDelta::FromMilliseconds(
339 static_cast<int64
>(mouse_event
.timeStampSeconds
* 1000));
349 class SyntheticGestureControllerTest
: public testing::Test
{
351 SyntheticGestureControllerTest() {}
352 virtual ~SyntheticGestureControllerTest() {}
355 template<typename MockGestureTarget
>
356 void CreateControllerAndTarget() {
357 target_
= new MockGestureTarget();
358 controller_
.reset(new SyntheticGestureController(
359 scoped_ptr
<SyntheticGestureTarget
>(target_
)));
362 virtual void SetUp() OVERRIDE
{
363 start_time_
= base::TimeTicks::Now();
369 virtual void TearDown() OVERRIDE
{
372 time_
= base::TimeTicks();
375 void QueueSyntheticGesture(scoped_ptr
<SyntheticGesture
> gesture
) {
376 controller_
->QueueSyntheticGesture(gesture
.Pass(),
377 base::Bind(&SyntheticGestureControllerTest::OnSyntheticGestureCompleted
,
378 base::Unretained(this)));
381 void FlushInputUntilComplete() {
382 while (target_
->flush_requested()) {
383 while (target_
->flush_requested()) {
384 target_
->ClearFlushRequest();
385 time_
+= base::TimeDelta::FromMilliseconds(kFlushInputRateInMs
);
386 controller_
->Flush(time_
);
388 controller_
->OnDidFlushInput();
392 void OnSyntheticGestureCompleted(SyntheticGesture::Result result
) {
393 DCHECK_NE(result
, SyntheticGesture::GESTURE_RUNNING
);
394 if (result
== SyntheticGesture::GESTURE_FINISHED
)
400 base::TimeDelta
GetTotalTime() const { return time_
- start_time_
; }
402 MockSyntheticGestureTarget
* target_
;
403 scoped_ptr
<SyntheticGestureController
> controller_
;
404 base::TimeTicks start_time_
;
405 base::TimeTicks time_
;
410 TEST_F(SyntheticGestureControllerTest
, SingleGesture
) {
411 CreateControllerAndTarget
<MockSyntheticGestureTarget
>();
414 scoped_ptr
<MockSyntheticGesture
> gesture(
415 new MockSyntheticGesture(&finished
, 3));
416 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
417 FlushInputUntilComplete();
419 EXPECT_TRUE(finished
);
420 EXPECT_EQ(1, num_success_
);
421 EXPECT_EQ(0, num_failure_
);
424 TEST_F(SyntheticGestureControllerTest
, GestureFailed
) {
425 CreateControllerAndTarget
<MockSyntheticGestureTarget
>();
428 scoped_ptr
<MockSyntheticGesture
> gesture(
429 new MockSyntheticGesture(&finished
, 0));
430 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
431 FlushInputUntilComplete();
433 EXPECT_TRUE(finished
);
434 EXPECT_EQ(1, num_failure_
);
435 EXPECT_EQ(0, num_success_
);
438 TEST_F(SyntheticGestureControllerTest
, SuccessiveGestures
) {
439 CreateControllerAndTarget
<MockSyntheticGestureTarget
>();
441 bool finished_1
, finished_2
;
442 scoped_ptr
<MockSyntheticGesture
> gesture_1(
443 new MockSyntheticGesture(&finished_1
, 2));
444 scoped_ptr
<MockSyntheticGesture
> gesture_2(
445 new MockSyntheticGesture(&finished_2
, 4));
447 // Queue first gesture and wait for it to finish
448 QueueSyntheticGesture(gesture_1
.PassAs
<SyntheticGesture
>());
449 FlushInputUntilComplete();
451 EXPECT_TRUE(finished_1
);
452 EXPECT_EQ(1, num_success_
);
453 EXPECT_EQ(0, num_failure_
);
455 // Queue second gesture.
456 QueueSyntheticGesture(gesture_2
.PassAs
<SyntheticGesture
>());
457 FlushInputUntilComplete();
459 EXPECT_TRUE(finished_2
);
460 EXPECT_EQ(2, num_success_
);
461 EXPECT_EQ(0, num_failure_
);
464 TEST_F(SyntheticGestureControllerTest
, TwoGesturesInFlight
) {
465 CreateControllerAndTarget
<MockSyntheticGestureTarget
>();
467 bool finished_1
, finished_2
;
468 scoped_ptr
<MockSyntheticGesture
> gesture_1(
469 new MockSyntheticGesture(&finished_1
, 2));
470 scoped_ptr
<MockSyntheticGesture
> gesture_2(
471 new MockSyntheticGesture(&finished_2
, 4));
473 QueueSyntheticGesture(gesture_1
.PassAs
<SyntheticGesture
>());
474 QueueSyntheticGesture(gesture_2
.PassAs
<SyntheticGesture
>());
475 FlushInputUntilComplete();
477 EXPECT_TRUE(finished_1
);
478 EXPECT_TRUE(finished_2
);
480 EXPECT_EQ(2, num_success_
);
481 EXPECT_EQ(0, num_failure_
);
484 TEST_F(SyntheticGestureControllerTest
, GestureCompletedOnDidFlushInput
) {
485 CreateControllerAndTarget
<MockSyntheticGestureTarget
>();
487 bool finished_1
, finished_2
;
488 scoped_ptr
<MockSyntheticGesture
> gesture_1(
489 new MockSyntheticGesture(&finished_1
, 2));
490 scoped_ptr
<MockSyntheticGesture
> gesture_2(
491 new MockSyntheticGesture(&finished_2
, 4));
493 QueueSyntheticGesture(gesture_1
.PassAs
<SyntheticGesture
>());
494 QueueSyntheticGesture(gesture_2
.PassAs
<SyntheticGesture
>());
496 while (target_
->flush_requested()) {
497 target_
->ClearFlushRequest();
498 time_
+= base::TimeDelta::FromMilliseconds(kFlushInputRateInMs
);
499 controller_
->Flush(time_
);
501 EXPECT_EQ(0, num_success_
);
502 controller_
->OnDidFlushInput();
503 EXPECT_EQ(1, num_success_
);
505 while (target_
->flush_requested()) {
506 target_
->ClearFlushRequest();
507 time_
+= base::TimeDelta::FromMilliseconds(kFlushInputRateInMs
);
508 controller_
->Flush(time_
);
510 EXPECT_EQ(1, num_success_
);
511 controller_
->OnDidFlushInput();
512 EXPECT_EQ(2, num_success_
);
515 gfx::Vector2d
AddTouchSlopToVector(const gfx::Vector2d
& vector
,
516 SyntheticGestureTarget
* target
) {
517 const int kTouchSlop
= target
->GetTouchSlopInDips();
531 return gfx::Vector2d(x
, y
);
534 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureTouchVertical
) {
535 CreateControllerAndTarget
<MockScrollTouchTarget
>();
537 SyntheticSmoothScrollGestureParams params
;
538 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
539 params
.anchor
.SetPoint(89, 32);
540 params
.distances
.push_back(gfx::Vector2d(0, 123));
542 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
543 new SyntheticSmoothScrollGesture(params
));
544 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
545 FlushInputUntilComplete();
547 MockScrollGestureTarget
* scroll_target
=
548 static_cast<MockScrollGestureTarget
*>(target_
);
549 EXPECT_EQ(1, num_success_
);
550 EXPECT_EQ(0, num_failure_
);
551 // TODO(dominikg): Remove adjustment when crbug.com/332418 is fixed.
552 EXPECT_EQ(AddTouchSlopToVector(params
.distances
[0], target_
),
553 scroll_target
->start_to_end_distance() - gfx::Vector2dF(0, 0.001f
));
556 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureTouchHorizontal
) {
557 CreateControllerAndTarget
<MockScrollTouchTarget
>();
559 SyntheticSmoothScrollGestureParams params
;
560 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
561 params
.anchor
.SetPoint(12, -23);
562 params
.distances
.push_back(gfx::Vector2d(-234, 0));
564 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
565 new SyntheticSmoothScrollGesture(params
));
566 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
567 FlushInputUntilComplete();
569 MockScrollGestureTarget
* scroll_target
=
570 static_cast<MockScrollGestureTarget
*>(target_
);
571 EXPECT_EQ(1, num_success_
);
572 EXPECT_EQ(0, num_failure_
);
573 // TODO(dominikg): Use vector comparison when crbug.com/332418 is fixed.
574 //EXPECT_EQ(AddTouchSlopToVector(params.distances[0], target_),
575 // scroll_target->start_to_end_distance());
576 EXPECT_EQ(AddTouchSlopToVector(params
.distances
[0], target_
).x(),
577 scroll_target
->start_to_end_distance().x());
578 EXPECT_LT(AddTouchSlopToVector(params
.distances
[0], target_
).y(),
579 scroll_target
->start_to_end_distance().y());
580 EXPECT_GE(AddTouchSlopToVector(params
.distances
[0], target_
).y(),
581 scroll_target
->start_to_end_distance().y() - 0.001f
);
584 void CheckIsWithinRangeSingle(float scroll_distance
,
586 SyntheticGestureTarget
* target
) {
587 if (target_distance
> 0) {
588 EXPECT_LE(target_distance
, scroll_distance
);
589 EXPECT_LE(scroll_distance
, target_distance
+ target
->GetTouchSlopInDips());
591 EXPECT_GE(target_distance
, scroll_distance
);
592 EXPECT_GE(scroll_distance
, target_distance
- target
->GetTouchSlopInDips());
596 void CheckSingleScrollDistanceIsWithinRange(
597 const gfx::Vector2dF
& scroll_distance
,
598 const gfx::Vector2d
& target_distance
,
599 SyntheticGestureTarget
* target
) {
600 CheckIsWithinRangeSingle(scroll_distance
.x(), target_distance
.x(), target
);
601 CheckIsWithinRangeSingle(scroll_distance
.y(), target_distance
.y(), target
);
604 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureTouchDiagonal
) {
605 CreateControllerAndTarget
<MockScrollTouchTarget
>();
607 SyntheticSmoothScrollGestureParams params
;
608 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
609 params
.anchor
.SetPoint(0, 7);
610 params
.distances
.push_back(gfx::Vector2d(413, -83));
612 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
613 new SyntheticSmoothScrollGesture(params
));
614 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
615 FlushInputUntilComplete();
617 MockScrollGestureTarget
* scroll_target
=
618 static_cast<MockScrollGestureTarget
*>(target_
);
619 EXPECT_EQ(1, num_success_
);
620 EXPECT_EQ(0, num_failure_
);
621 CheckSingleScrollDistanceIsWithinRange(
622 scroll_target
->start_to_end_distance(), params
.distances
[0], target_
);
625 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureTouchLongStop
) {
626 CreateControllerAndTarget
<MockScrollTouchTarget
>();
628 // Create a smooth scroll with a short distance and set the pointer assumed
629 // stopped time high, so that the stopping should dominate the time the
630 // gesture is active.
631 SyntheticSmoothScrollGestureParams params
;
632 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
633 params
.anchor
.SetPoint(-98, -23);
634 params
.distances
.push_back(gfx::Vector2d(21, -12));
635 params
.prevent_fling
= true;
637 target_
->set_pointer_assumed_stopped_time_ms(543);
639 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
640 new SyntheticSmoothScrollGesture(params
));
641 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
642 FlushInputUntilComplete();
644 MockScrollGestureTarget
* scroll_target
=
645 static_cast<MockScrollGestureTarget
*>(target_
);
646 EXPECT_EQ(1, num_success_
);
647 EXPECT_EQ(0, num_failure_
);
648 CheckSingleScrollDistanceIsWithinRange(
649 scroll_target
->start_to_end_distance(), params
.distances
[0], target_
);
650 EXPECT_GE(GetTotalTime(), target_
->PointerAssumedStoppedTime());
653 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureTouchFling
) {
654 CreateControllerAndTarget
<MockScrollTouchTarget
>();
656 // Create a smooth scroll with a short distance and set the pointer assumed
657 // stopped time high. Disable 'prevent_fling' and check that the gesture
658 // finishes without waiting before it stops.
659 SyntheticSmoothScrollGestureParams params
;
660 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
661 params
.anchor
.SetPoint(-89, 78);
662 params
.distances
.push_back(gfx::Vector2d(-43, 19));
663 params
.prevent_fling
= false;
665 target_
->set_pointer_assumed_stopped_time_ms(543);
667 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
668 new SyntheticSmoothScrollGesture(params
));
669 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
670 FlushInputUntilComplete();
672 MockScrollGestureTarget
* scroll_target
=
673 static_cast<MockScrollGestureTarget
*>(target_
);
674 EXPECT_EQ(1, num_success_
);
675 EXPECT_EQ(0, num_failure_
);
676 CheckSingleScrollDistanceIsWithinRange(
677 scroll_target
->start_to_end_distance(), params
.distances
[0], target_
);
678 EXPECT_LE(GetTotalTime(), target_
->PointerAssumedStoppedTime());
681 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureTouchZeroDistance
) {
682 CreateControllerAndTarget
<MockScrollTouchTarget
>();
684 SyntheticSmoothScrollGestureParams params
;
685 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
686 params
.anchor
.SetPoint(-32, 43);
687 params
.distances
.push_back(gfx::Vector2d(0, 0));
689 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
690 new SyntheticSmoothScrollGesture(params
));
691 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
692 FlushInputUntilComplete();
694 MockScrollGestureTarget
* scroll_target
=
695 static_cast<MockScrollGestureTarget
*>(target_
);
696 EXPECT_EQ(1, num_success_
);
697 EXPECT_EQ(0, num_failure_
);
698 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_target
->start_to_end_distance());
701 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureMouseVertical
) {
702 CreateControllerAndTarget
<MockScrollMouseTarget
>();
704 SyntheticSmoothScrollGestureParams params
;
705 params
.gesture_source_type
= SyntheticGestureParams::MOUSE_INPUT
;
706 params
.anchor
.SetPoint(432, 89);
707 params
.distances
.push_back(gfx::Vector2d(0, -234));
709 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
710 new SyntheticSmoothScrollGesture(params
));
711 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
712 FlushInputUntilComplete();
714 MockScrollGestureTarget
* scroll_target
=
715 static_cast<MockScrollGestureTarget
*>(target_
);
716 EXPECT_EQ(1, num_success_
);
717 EXPECT_EQ(0, num_failure_
);
718 EXPECT_EQ(params
.distances
[0], scroll_target
->start_to_end_distance());
721 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureMouseHorizontal
) {
722 CreateControllerAndTarget
<MockScrollMouseTarget
>();
724 SyntheticSmoothScrollGestureParams params
;
725 params
.gesture_source_type
= SyntheticGestureParams::MOUSE_INPUT
;
726 params
.anchor
.SetPoint(90, 12);
727 params
.distances
.push_back(gfx::Vector2d(345, 0));
729 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
730 new SyntheticSmoothScrollGesture(params
));
731 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
732 FlushInputUntilComplete();
734 MockScrollGestureTarget
* scroll_target
=
735 static_cast<MockScrollGestureTarget
*>(target_
);
736 EXPECT_EQ(1, num_success_
);
737 EXPECT_EQ(0, num_failure_
);
738 EXPECT_EQ(params
.distances
[0], scroll_target
->start_to_end_distance());
741 TEST_F(SyntheticGestureControllerTest
, SingleScrollGestureMouseDiagonal
) {
742 CreateControllerAndTarget
<MockScrollMouseTarget
>();
744 SyntheticSmoothScrollGestureParams params
;
745 params
.gesture_source_type
= SyntheticGestureParams::MOUSE_INPUT
;
746 params
.anchor
.SetPoint(90, 12);
747 params
.distances
.push_back(gfx::Vector2d(-194, 303));
749 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
750 new SyntheticSmoothScrollGesture(params
));
751 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
752 FlushInputUntilComplete();
754 MockScrollGestureTarget
* scroll_target
=
755 static_cast<MockScrollGestureTarget
*>(target_
);
756 EXPECT_EQ(1, num_success_
);
757 EXPECT_EQ(0, num_failure_
);
758 EXPECT_EQ(params
.distances
[0], scroll_target
->start_to_end_distance());
761 TEST_F(SyntheticGestureControllerTest
, MultiScrollGestureMouse
) {
762 CreateControllerAndTarget
<MockScrollMouseTarget
>();
764 SyntheticSmoothScrollGestureParams params
;
765 params
.gesture_source_type
= SyntheticGestureParams::MOUSE_INPUT
;
766 params
.anchor
.SetPoint(90, 12);
767 params
.distances
.push_back(gfx::Vector2d(-129, 212));
768 params
.distances
.push_back(gfx::Vector2d(8, -9));
770 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
771 new SyntheticSmoothScrollGesture(params
));
772 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
773 FlushInputUntilComplete();
775 MockScrollGestureTarget
* scroll_target
=
776 static_cast<MockScrollGestureTarget
*>(target_
);
777 EXPECT_EQ(1, num_success_
);
778 EXPECT_EQ(0, num_failure_
);
779 EXPECT_EQ(params
.distances
[0] + params
.distances
[1],
780 scroll_target
->start_to_end_distance());
783 TEST_F(SyntheticGestureControllerTest
, MultiScrollGestureMouseHorizontal
) {
784 CreateControllerAndTarget
<MockScrollMouseTarget
>();
786 SyntheticSmoothScrollGestureParams params
;
787 params
.gesture_source_type
= SyntheticGestureParams::MOUSE_INPUT
;
788 params
.anchor
.SetPoint(90, 12);
789 params
.distances
.push_back(gfx::Vector2d(-129, 0));
790 params
.distances
.push_back(gfx::Vector2d(79, 0));
792 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
793 new SyntheticSmoothScrollGesture(params
));
794 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
795 FlushInputUntilComplete();
797 MockScrollGestureTarget
* scroll_target
=
798 static_cast<MockScrollGestureTarget
*>(target_
);
799 EXPECT_EQ(1, num_success_
);
800 EXPECT_EQ(0, num_failure_
);
801 // This check only works for horizontal or vertical scrolls because of
802 // floating point precision issues with diagonal scrolls.
803 EXPECT_FLOAT_EQ(params
.distances
[0].Length() + params
.distances
[1].Length(),
804 scroll_target
->total_abs_scroll_distance_length());
805 EXPECT_EQ(params
.distances
[0] + params
.distances
[1],
806 scroll_target
->start_to_end_distance());
809 void CheckIsWithinRangeMulti(float scroll_distance
,
811 SyntheticGestureTarget
* target
) {
812 if (target_distance
> 0) {
813 EXPECT_GE(scroll_distance
, target_distance
- target
->GetTouchSlopInDips());
814 EXPECT_LE(scroll_distance
, target_distance
+ target
->GetTouchSlopInDips());
816 EXPECT_LE(scroll_distance
, target_distance
+ target
->GetTouchSlopInDips());
817 EXPECT_GE(scroll_distance
, target_distance
- target
->GetTouchSlopInDips());
821 void CheckMultiScrollDistanceIsWithinRange(
822 const gfx::Vector2dF
& scroll_distance
,
823 const gfx::Vector2d
& target_distance
,
824 SyntheticGestureTarget
* target
) {
825 CheckIsWithinRangeMulti(scroll_distance
.x(), target_distance
.x(), target
);
826 CheckIsWithinRangeMulti(scroll_distance
.y(), target_distance
.y(), target
);
829 TEST_F(SyntheticGestureControllerTest
, MultiScrollGestureTouch
) {
830 CreateControllerAndTarget
<MockScrollTouchTarget
>();
832 SyntheticSmoothScrollGestureParams params
;
833 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
834 params
.anchor
.SetPoint(8, -13);
835 params
.distances
.push_back(gfx::Vector2d(234, 133));
836 params
.distances
.push_back(gfx::Vector2d(-9, 78));
838 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
839 new SyntheticSmoothScrollGesture(params
));
840 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
841 FlushInputUntilComplete();
843 MockScrollGestureTarget
* scroll_target
=
844 static_cast<MockScrollGestureTarget
*>(target_
);
845 EXPECT_EQ(1, num_success_
);
846 EXPECT_EQ(0, num_failure_
);
847 CheckMultiScrollDistanceIsWithinRange(
848 scroll_target
->start_to_end_distance(),
849 params
.distances
[0] + params
.distances
[1],
853 TEST_F(SyntheticGestureControllerTest
, MultiScrollGestureTouchVertical
) {
854 CreateControllerAndTarget
<MockScrollTouchTarget
>();
856 SyntheticSmoothScrollGestureParams params
;
857 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
858 params
.anchor
.SetPoint(234, -13);
859 params
.distances
.push_back(gfx::Vector2d(0, 133));
860 params
.distances
.push_back(gfx::Vector2d(0, 78));
862 scoped_ptr
<SyntheticSmoothScrollGesture
> gesture(
863 new SyntheticSmoothScrollGesture(params
));
864 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
865 FlushInputUntilComplete();
867 MockScrollGestureTarget
* scroll_target
=
868 static_cast<MockScrollGestureTarget
*>(target_
);
869 EXPECT_EQ(1, num_success_
);
870 EXPECT_EQ(0, num_failure_
);
871 // TODO(dominikg): Remove adjustment when crbug.com/332418 is fixed.
873 params
.distances
[0].Length() + params
.distances
[1].Length() +
874 target_
->GetTouchSlopInDips(),
875 scroll_target
->total_abs_scroll_distance_length() - 0.001f
);
876 EXPECT_EQ(AddTouchSlopToVector(params
.distances
[0] + params
.distances
[1],
878 scroll_target
->start_to_end_distance() - gfx::Vector2dF(0, 0.001f
));
881 TEST_F(SyntheticGestureControllerTest
, PinchGestureTouchZoomIn
) {
882 CreateControllerAndTarget
<MockSyntheticPinchTouchTarget
>();
884 SyntheticPinchGestureParams params
;
885 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
886 params
.zoom_in
= true;
887 params
.total_num_pixels_covered
= 345;
888 params
.anchor
.SetPoint(54, 89);
890 scoped_ptr
<SyntheticPinchGesture
> gesture(new SyntheticPinchGesture(params
));
891 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
892 FlushInputUntilComplete();
894 MockSyntheticPinchTouchTarget
* pinch_target
=
895 static_cast<MockSyntheticPinchTouchTarget
*>(target_
);
896 EXPECT_EQ(1, num_success_
);
897 EXPECT_EQ(0, num_failure_
);
898 EXPECT_EQ(pinch_target
->zoom_direction(),
899 MockSyntheticPinchTouchTarget::ZOOM_IN
);
900 EXPECT_EQ(params
.total_num_pixels_covered
+ 2 * target_
->GetTouchSlopInDips(),
901 pinch_target
->total_num_pixels_covered());
904 TEST_F(SyntheticGestureControllerTest
, PinchGestureTouchZoomOut
) {
905 CreateControllerAndTarget
<MockSyntheticPinchTouchTarget
>();
907 SyntheticPinchGestureParams params
;
908 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
909 params
.zoom_in
= false;
910 params
.total_num_pixels_covered
= 456;
911 params
.anchor
.SetPoint(-12, 93);
913 scoped_ptr
<SyntheticPinchGesture
> gesture(new SyntheticPinchGesture(params
));
914 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
915 FlushInputUntilComplete();
917 MockSyntheticPinchTouchTarget
* pinch_target
=
918 static_cast<MockSyntheticPinchTouchTarget
*>(target_
);
919 EXPECT_EQ(1, num_success_
);
920 EXPECT_EQ(0, num_failure_
);
921 EXPECT_EQ(pinch_target
->zoom_direction(),
922 MockSyntheticPinchTouchTarget::ZOOM_OUT
);
923 EXPECT_EQ(params
.total_num_pixels_covered
+ 2 * target_
->GetTouchSlopInDips(),
924 pinch_target
->total_num_pixels_covered());
927 TEST_F(SyntheticGestureControllerTest
, PinchGestureTouchZeroPixelsCovered
) {
928 CreateControllerAndTarget
<MockSyntheticPinchTouchTarget
>();
930 SyntheticPinchGestureParams params
;
931 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
932 params
.zoom_in
= true;
933 params
.total_num_pixels_covered
= 0;
935 scoped_ptr
<SyntheticPinchGesture
> gesture(new SyntheticPinchGesture(params
));
936 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
937 FlushInputUntilComplete();
939 MockSyntheticPinchTouchTarget
* pinch_target
=
940 static_cast<MockSyntheticPinchTouchTarget
*>(target_
);
941 EXPECT_EQ(1, num_success_
);
942 EXPECT_EQ(0, num_failure_
);
943 EXPECT_EQ(pinch_target
->zoom_direction(),
944 MockSyntheticPinchTouchTarget::ZOOM_DIRECTION_UNKNOWN
);
945 EXPECT_EQ(0, pinch_target
->total_num_pixels_covered());
948 TEST_F(SyntheticGestureControllerTest
, TapGestureTouch
) {
949 CreateControllerAndTarget
<MockSyntheticTapTouchTarget
>();
951 SyntheticTapGestureParams params
;
952 params
.gesture_source_type
= SyntheticGestureParams::TOUCH_INPUT
;
953 params
.duration_ms
= 123;
954 params
.position
.SetPoint(87, -124);
956 scoped_ptr
<SyntheticTapGesture
> gesture(new SyntheticTapGesture(params
));
957 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
958 FlushInputUntilComplete();
960 MockSyntheticTapTouchTarget
* tap_target
=
961 static_cast<MockSyntheticTapTouchTarget
*>(target_
);
962 EXPECT_EQ(1, num_success_
);
963 EXPECT_EQ(0, num_failure_
);
964 EXPECT_TRUE(tap_target
->GestureFinished());
965 EXPECT_EQ(tap_target
->position(), params
.position
);
966 EXPECT_EQ(tap_target
->GetDuration().InMilliseconds(), params
.duration_ms
);
967 EXPECT_GE(GetTotalTime(),
968 base::TimeDelta::FromMilliseconds(params
.duration_ms
));
971 TEST_F(SyntheticGestureControllerTest
, TapGestureMouse
) {
972 CreateControllerAndTarget
<MockSyntheticTapMouseTarget
>();
974 SyntheticTapGestureParams params
;
975 params
.gesture_source_type
= SyntheticGestureParams::MOUSE_INPUT
;
976 params
.duration_ms
= 79;
977 params
.position
.SetPoint(98, 123);
979 scoped_ptr
<SyntheticTapGesture
> gesture(new SyntheticTapGesture(params
));
980 QueueSyntheticGesture(gesture
.PassAs
<SyntheticGesture
>());
981 FlushInputUntilComplete();
983 MockSyntheticTapMouseTarget
* tap_target
=
984 static_cast<MockSyntheticTapMouseTarget
*>(target_
);
985 EXPECT_EQ(1, num_success_
);
986 EXPECT_EQ(0, num_failure_
);
987 EXPECT_TRUE(tap_target
->GestureFinished());
988 EXPECT_EQ(tap_target
->position(), params
.position
);
989 EXPECT_EQ(tap_target
->GetDuration().InMilliseconds(), params
.duration_ms
);
990 EXPECT_GE(GetTotalTime(),
991 base::TimeDelta::FromMilliseconds(params
.duration_ms
));
996 } // namespace content