Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / synthetic_gesture_controller_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
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"
27
28 using blink::WebInputEvent;
29 using blink::WebMouseEvent;
30 using blink::WebMouseWheelEvent;
31 using blink::WebTouchEvent;
32
33 namespace content {
34
35 namespace {
36
37 const int kFlushInputRateInMs = 16;
38 const int kPointerAssumedStoppedTimeMs = 43;
39 const int kTouchSlopInDips = 7;
40
41 class MockSyntheticGesture : public SyntheticGesture {
42  public:
43   MockSyntheticGesture(bool* finished, int num_steps)
44       : finished_(finished),
45         num_steps_(num_steps),
46         step_count_(0) {
47     *finished_ = false;
48   }
49   virtual ~MockSyntheticGesture() {}
50
51   virtual Result ForwardInputEvents(const base::TimeTicks& timestamp,
52                                     SyntheticGestureTarget* target) OVERRIDE {
53     step_count_++;
54     if (step_count_ == num_steps_) {
55       *finished_ = true;
56       return SyntheticGesture::GESTURE_FINISHED;
57     } else if (step_count_ > num_steps_) {
58       *finished_ = true;
59       // Return arbitrary failure.
60       return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
61     }
62
63     return SyntheticGesture::GESTURE_RUNNING;
64   }
65
66  protected:
67   bool* finished_;
68   int num_steps_;
69   int step_count_;
70 };
71
72 class MockSyntheticGestureTarget : public SyntheticGestureTarget {
73  public:
74   MockSyntheticGestureTarget()
75       : flush_requested_(false),
76         pointer_assumed_stopped_time_ms_(kPointerAssumedStoppedTimeMs) {}
77   virtual ~MockSyntheticGestureTarget() {}
78
79   // SyntheticGestureTarget:
80   virtual void DispatchInputEventToPlatform(
81       const WebInputEvent& event) OVERRIDE {}
82
83   virtual void SetNeedsFlush() OVERRIDE {
84     flush_requested_ = true;
85   }
86
87   virtual SyntheticGestureParams::GestureSourceType
88   GetDefaultSyntheticGestureSourceType() const OVERRIDE {
89     return SyntheticGestureParams::TOUCH_INPUT;
90   }
91
92   virtual base::TimeDelta PointerAssumedStoppedTime() const OVERRIDE {
93     return base::TimeDelta::FromMilliseconds(pointer_assumed_stopped_time_ms_);
94   }
95
96   void set_pointer_assumed_stopped_time_ms(int time_ms) {
97     pointer_assumed_stopped_time_ms_ = time_ms;
98   }
99
100   virtual int GetTouchSlopInDips() const OVERRIDE {
101     return kTouchSlopInDips;
102   }
103
104   bool flush_requested() const { return flush_requested_; }
105   void ClearFlushRequest() { flush_requested_ = false; }
106
107  private:
108   bool flush_requested_;
109
110   int pointer_assumed_stopped_time_ms_;
111 };
112
113 class MockScrollGestureTarget : public MockSyntheticGestureTarget {
114  public:
115   MockScrollGestureTarget() : total_abs_scroll_distance_length_(0) {}
116   virtual ~MockScrollGestureTarget() {}
117
118   gfx::Vector2dF start_to_end_distance() const {
119     return start_to_end_distance_;
120   }
121   float total_abs_scroll_distance_length() const {
122     return total_abs_scroll_distance_length_;
123   }
124
125  protected:
126   gfx::Vector2dF start_to_end_distance_;
127   float total_abs_scroll_distance_length_;
128 };
129
130 class MockScrollMouseTarget : public MockScrollGestureTarget {
131  public:
132   MockScrollMouseTarget() {}
133   virtual ~MockScrollMouseTarget() {}
134
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();
143   }
144 };
145
146 class MockScrollTouchTarget : public MockScrollGestureTarget {
147  public:
148   MockScrollTouchTarget() : started_(false) {}
149   virtual ~MockScrollTouchTarget() {}
150
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);
156
157     if (!started_) {
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_;
162       started_ = true;
163     } else {
164       ASSERT_NE(touch_event.type, WebInputEvent::TouchStart);
165       ASSERT_NE(touch_event.type, WebInputEvent::TouchCancel);
166
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();
171
172       if (touch_event.type == WebInputEvent::TouchEnd)
173         start_to_end_distance_ = touch_point - start_;
174
175       last_touch_point_ = touch_point;
176     }
177   }
178
179  protected:
180   gfx::Point start_;
181   gfx::PointF last_touch_point_;
182   bool started_;
183 };
184
185 class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
186  public:
187   enum ZoomDirection {
188     ZOOM_DIRECTION_UNKNOWN,
189     ZOOM_IN,
190     ZOOM_OUT
191   };
192
193   MockSyntheticPinchTouchTarget()
194       : total_num_pixels_covered_(0),
195         last_pointer_distance_(0),
196         zoom_direction_(ZOOM_DIRECTION_UNKNOWN),
197         started_(false) {}
198   virtual ~MockSyntheticPinchTouchTarget() {}
199
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);
205
206     if (!started_) {
207       ASSERT_EQ(touch_event.type, WebInputEvent::TouchStart);
208
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();
212
213       started_ = true;
214     } else {
215       ASSERT_NE(touch_event.type, WebInputEvent::TouchStart);
216       ASSERT_NE(touch_event.type, WebInputEvent::TouchCancel);
217
218       gfx::PointF current_0 = gfx::PointF(touch_event.touches[0].position);
219       gfx::PointF current_1 = gfx::PointF(touch_event.touches[1].position);
220
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();
224
225       if (last_pointer_distance_ != pointer_distance) {
226         if (zoom_direction_ == ZOOM_DIRECTION_UNKNOWN)
227           zoom_direction_ =
228               ComputeZoomDirection(last_pointer_distance_, pointer_distance);
229         else
230           EXPECT_EQ(
231               zoom_direction_,
232               ComputeZoomDirection(last_pointer_distance_, pointer_distance));
233       }
234
235       last_pointer_distance_ = pointer_distance;
236     }
237   }
238
239   float total_num_pixels_covered() const { return total_num_pixels_covered_; }
240   ZoomDirection zoom_direction() const { return zoom_direction_; }
241
242  private:
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
247                                                             : ZOOM_OUT;
248   }
249
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_;
255   bool started_;
256 };
257
258 class MockSyntheticTapGestureTarget : public MockSyntheticGestureTarget {
259  public:
260   MockSyntheticTapGestureTarget() : state_(NOT_STARTED) {}
261   virtual ~MockSyntheticTapGestureTarget() {}
262
263   bool GestureFinished() const { return state_ == FINISHED; }
264   gfx::PointF position() const { return position_; }
265   base::TimeDelta GetDuration() const { return stop_time_ - start_time_; }
266
267  protected:
268   enum GestureState {
269     NOT_STARTED,
270     STARTED,
271     FINISHED
272   };
273
274   gfx::PointF position_;
275   base::TimeDelta start_time_;
276   base::TimeDelta stop_time_;
277   GestureState state_;
278 };
279
280 class MockSyntheticTapTouchTarget : public MockSyntheticTapGestureTarget {
281  public:
282   MockSyntheticTapTouchTarget() {}
283   virtual ~MockSyntheticTapTouchTarget() {}
284
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);
290
291     switch (state_) {
292       case NOT_STARTED:
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));
297         state_ = STARTED;
298         break;
299       case STARTED:
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));
304         state_ = FINISHED;
305         break;
306       case FINISHED:
307         EXPECT_FALSE(true);
308         break;
309     }
310   }
311 };
312
313 class MockSyntheticTapMouseTarget : public MockSyntheticTapGestureTarget {
314  public:
315   MockSyntheticTapMouseTarget() {}
316   virtual ~MockSyntheticTapMouseTarget() {}
317
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);
322
323     switch (state_) {
324       case NOT_STARTED:
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));
331         state_ = STARTED;
332         break;
333       case STARTED:
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));
340         state_ = FINISHED;
341         break;
342       case FINISHED:
343         EXPECT_FALSE(true);
344         break;
345     }
346   }
347 };
348
349 class SyntheticGestureControllerTest : public testing::Test {
350  public:
351   SyntheticGestureControllerTest() {}
352   virtual ~SyntheticGestureControllerTest() {}
353
354  protected:
355   template<typename MockGestureTarget>
356   void CreateControllerAndTarget() {
357     target_ = new MockGestureTarget();
358     controller_.reset(new SyntheticGestureController(
359         scoped_ptr<SyntheticGestureTarget>(target_)));
360   }
361
362   virtual void SetUp() OVERRIDE {
363     start_time_ = base::TimeTicks::Now();
364     time_ = start_time_;
365     num_success_ = 0;
366     num_failure_ = 0;
367   }
368
369   virtual void TearDown() OVERRIDE {
370     controller_.reset();
371     target_ = NULL;
372     time_ = base::TimeTicks();
373   }
374
375   void QueueSyntheticGesture(scoped_ptr<SyntheticGesture> gesture) {
376     controller_->QueueSyntheticGesture(gesture.Pass(),
377         base::Bind(&SyntheticGestureControllerTest::OnSyntheticGestureCompleted,
378             base::Unretained(this)));
379   }
380
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_);
387       }
388       controller_->OnDidFlushInput();
389     }
390   }
391
392   void OnSyntheticGestureCompleted(SyntheticGesture::Result result) {
393     DCHECK_NE(result, SyntheticGesture::GESTURE_RUNNING);
394     if (result == SyntheticGesture::GESTURE_FINISHED)
395       num_success_++;
396     else
397       num_failure_++;
398   }
399
400   base::TimeDelta GetTotalTime() const { return time_ - start_time_; }
401
402   MockSyntheticGestureTarget* target_;
403   scoped_ptr<SyntheticGestureController> controller_;
404   base::TimeTicks start_time_;
405   base::TimeTicks time_;
406   int num_success_;
407   int num_failure_;
408 };
409
410 TEST_F(SyntheticGestureControllerTest, SingleGesture) {
411   CreateControllerAndTarget<MockSyntheticGestureTarget>();
412
413   bool finished;
414   scoped_ptr<MockSyntheticGesture> gesture(
415       new MockSyntheticGesture(&finished, 3));
416   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
417   FlushInputUntilComplete();
418
419   EXPECT_TRUE(finished);
420   EXPECT_EQ(1, num_success_);
421   EXPECT_EQ(0, num_failure_);
422 }
423
424 TEST_F(SyntheticGestureControllerTest, GestureFailed) {
425   CreateControllerAndTarget<MockSyntheticGestureTarget>();
426
427   bool finished;
428   scoped_ptr<MockSyntheticGesture> gesture(
429       new MockSyntheticGesture(&finished, 0));
430   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
431   FlushInputUntilComplete();
432
433   EXPECT_TRUE(finished);
434   EXPECT_EQ(1, num_failure_);
435   EXPECT_EQ(0, num_success_);
436 }
437
438 TEST_F(SyntheticGestureControllerTest, SuccessiveGestures) {
439   CreateControllerAndTarget<MockSyntheticGestureTarget>();
440
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));
446
447   // Queue first gesture and wait for it to finish
448   QueueSyntheticGesture(gesture_1.PassAs<SyntheticGesture>());
449   FlushInputUntilComplete();
450
451   EXPECT_TRUE(finished_1);
452   EXPECT_EQ(1, num_success_);
453   EXPECT_EQ(0, num_failure_);
454
455   // Queue second gesture.
456   QueueSyntheticGesture(gesture_2.PassAs<SyntheticGesture>());
457   FlushInputUntilComplete();
458
459   EXPECT_TRUE(finished_2);
460   EXPECT_EQ(2, num_success_);
461   EXPECT_EQ(0, num_failure_);
462 }
463
464 TEST_F(SyntheticGestureControllerTest, TwoGesturesInFlight) {
465   CreateControllerAndTarget<MockSyntheticGestureTarget>();
466
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));
472
473   QueueSyntheticGesture(gesture_1.PassAs<SyntheticGesture>());
474   QueueSyntheticGesture(gesture_2.PassAs<SyntheticGesture>());
475   FlushInputUntilComplete();
476
477   EXPECT_TRUE(finished_1);
478   EXPECT_TRUE(finished_2);
479
480   EXPECT_EQ(2, num_success_);
481   EXPECT_EQ(0, num_failure_);
482 }
483
484 TEST_F(SyntheticGestureControllerTest, GestureCompletedOnDidFlushInput) {
485   CreateControllerAndTarget<MockSyntheticGestureTarget>();
486
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));
492
493   QueueSyntheticGesture(gesture_1.PassAs<SyntheticGesture>());
494   QueueSyntheticGesture(gesture_2.PassAs<SyntheticGesture>());
495
496   while (target_->flush_requested()) {
497     target_->ClearFlushRequest();
498     time_ += base::TimeDelta::FromMilliseconds(kFlushInputRateInMs);
499     controller_->Flush(time_);
500   }
501   EXPECT_EQ(0, num_success_);
502   controller_->OnDidFlushInput();
503   EXPECT_EQ(1, num_success_);
504
505   while (target_->flush_requested()) {
506     target_->ClearFlushRequest();
507     time_ += base::TimeDelta::FromMilliseconds(kFlushInputRateInMs);
508     controller_->Flush(time_);
509   }
510   EXPECT_EQ(1, num_success_);
511   controller_->OnDidFlushInput();
512   EXPECT_EQ(2, num_success_);
513 }
514
515 gfx::Vector2d AddTouchSlopToVector(const gfx::Vector2d& vector,
516                                    SyntheticGestureTarget* target) {
517   const int kTouchSlop = target->GetTouchSlopInDips();
518
519   int x = vector.x();
520   if (x > 0)
521     x += kTouchSlop;
522   else if (x < 0)
523     x -= kTouchSlop;
524
525   int y = vector.y();
526   if (y > 0)
527     y += kTouchSlop;
528   else if (y < 0)
529     y -= kTouchSlop;
530
531   return gfx::Vector2d(x, y);
532 }
533
534 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchVertical) {
535   CreateControllerAndTarget<MockScrollTouchTarget>();
536
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));
541
542   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
543       new SyntheticSmoothScrollGesture(params));
544   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
545   FlushInputUntilComplete();
546
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));
554 }
555
556 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchHorizontal) {
557   CreateControllerAndTarget<MockScrollTouchTarget>();
558
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));
563
564   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
565       new SyntheticSmoothScrollGesture(params));
566   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
567   FlushInputUntilComplete();
568
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);
582 }
583
584 void CheckIsWithinRangeSingle(float scroll_distance,
585                               int target_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());
590   } else {
591     EXPECT_GE(target_distance, scroll_distance);
592     EXPECT_GE(scroll_distance, target_distance - target->GetTouchSlopInDips());
593   }
594 }
595
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);
602 }
603
604 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchDiagonal) {
605   CreateControllerAndTarget<MockScrollTouchTarget>();
606
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));
611
612   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
613       new SyntheticSmoothScrollGesture(params));
614   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
615   FlushInputUntilComplete();
616
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_);
623 }
624
625 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchLongStop) {
626   CreateControllerAndTarget<MockScrollTouchTarget>();
627
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;
636
637   target_->set_pointer_assumed_stopped_time_ms(543);
638
639   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
640       new SyntheticSmoothScrollGesture(params));
641   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
642   FlushInputUntilComplete();
643
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());
651 }
652
653 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchFling) {
654   CreateControllerAndTarget<MockScrollTouchTarget>();
655
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;
664
665   target_->set_pointer_assumed_stopped_time_ms(543);
666
667   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
668       new SyntheticSmoothScrollGesture(params));
669   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
670   FlushInputUntilComplete();
671
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());
679 }
680
681 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureTouchZeroDistance) {
682   CreateControllerAndTarget<MockScrollTouchTarget>();
683
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));
688
689   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
690       new SyntheticSmoothScrollGesture(params));
691   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
692   FlushInputUntilComplete();
693
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());
699 }
700
701 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureMouseVertical) {
702   CreateControllerAndTarget<MockScrollMouseTarget>();
703
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));
708
709   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
710       new SyntheticSmoothScrollGesture(params));
711   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
712   FlushInputUntilComplete();
713
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());
719 }
720
721 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureMouseHorizontal) {
722   CreateControllerAndTarget<MockScrollMouseTarget>();
723
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));
728
729   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
730       new SyntheticSmoothScrollGesture(params));
731   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
732   FlushInputUntilComplete();
733
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());
739 }
740
741 TEST_F(SyntheticGestureControllerTest, SingleScrollGestureMouseDiagonal) {
742   CreateControllerAndTarget<MockScrollMouseTarget>();
743
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));
748
749   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
750       new SyntheticSmoothScrollGesture(params));
751   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
752   FlushInputUntilComplete();
753
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());
759 }
760
761 TEST_F(SyntheticGestureControllerTest, MultiScrollGestureMouse) {
762   CreateControllerAndTarget<MockScrollMouseTarget>();
763
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));
769
770   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
771       new SyntheticSmoothScrollGesture(params));
772   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
773   FlushInputUntilComplete();
774
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());
781 }
782
783 TEST_F(SyntheticGestureControllerTest, MultiScrollGestureMouseHorizontal) {
784   CreateControllerAndTarget<MockScrollMouseTarget>();
785
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));
791
792   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
793       new SyntheticSmoothScrollGesture(params));
794   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
795   FlushInputUntilComplete();
796
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());
807 }
808
809 void CheckIsWithinRangeMulti(float scroll_distance,
810                              int target_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());
815   } else {
816     EXPECT_LE(scroll_distance, target_distance + target->GetTouchSlopInDips());
817     EXPECT_GE(scroll_distance, target_distance - target->GetTouchSlopInDips());
818   }
819 }
820
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);
827 }
828
829 TEST_F(SyntheticGestureControllerTest, MultiScrollGestureTouch) {
830   CreateControllerAndTarget<MockScrollTouchTarget>();
831
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));
837
838   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
839       new SyntheticSmoothScrollGesture(params));
840   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
841   FlushInputUntilComplete();
842
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],
850       target_);
851 }
852
853 TEST_F(SyntheticGestureControllerTest, MultiScrollGestureTouchVertical) {
854   CreateControllerAndTarget<MockScrollTouchTarget>();
855
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));
861
862   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
863       new SyntheticSmoothScrollGesture(params));
864   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
865   FlushInputUntilComplete();
866
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.
872   EXPECT_FLOAT_EQ(
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],
877                                  target_),
878             scroll_target->start_to_end_distance() - gfx::Vector2dF(0, 0.001f));
879 }
880
881 TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) {
882   CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
883
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);
889
890   scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
891   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
892   FlushInputUntilComplete();
893
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());
902 }
903
904 TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
905   CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
906
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);
912
913   scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
914   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
915   FlushInputUntilComplete();
916
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());
925 }
926
927 TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZeroPixelsCovered) {
928   CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
929
930   SyntheticPinchGestureParams params;
931   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
932   params.zoom_in = true;
933   params.total_num_pixels_covered = 0;
934
935   scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
936   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
937   FlushInputUntilComplete();
938
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());
946 }
947
948 TEST_F(SyntheticGestureControllerTest, TapGestureTouch) {
949   CreateControllerAndTarget<MockSyntheticTapTouchTarget>();
950
951   SyntheticTapGestureParams params;
952   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
953   params.duration_ms = 123;
954   params.position.SetPoint(87, -124);
955
956   scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
957   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
958   FlushInputUntilComplete();
959
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));
969 }
970
971 TEST_F(SyntheticGestureControllerTest, TapGestureMouse) {
972   CreateControllerAndTarget<MockSyntheticTapMouseTarget>();
973
974   SyntheticTapGestureParams params;
975   params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
976   params.duration_ms = 79;
977   params.position.SetPoint(98, 123);
978
979   scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
980   QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
981   FlushInputUntilComplete();
982
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));
992 }
993
994 }  // namespace
995
996 }  // namespace content