985210dd8b1b2ca159b3c40e51450f93c9bb026c
[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/memory/scoped_ptr.h"
6 #include "base/time/time.h"
7 #include "content/browser/renderer_host/input/synthetic_gesture.h"
8 #include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
9 #include "content/browser/renderer_host/input/synthetic_gesture_target.h"
10 #include "content/browser/renderer_host/input/synthetic_pinch_gesture.h"
11 #include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
12 #include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
13 #include "content/browser/renderer_host/render_widget_host_delegate.h"
14 #include "content/common/input/synthetic_pinch_gesture_params.h"
15 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
16 #include "content/common/input/synthetic_tap_gesture_params.h"
17 #include "content/public/test/mock_render_process_host.h"
18 #include "content/public/test/test_browser_context.h"
19 #include "content/test/test_render_view_host.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/WebKit/public/web/WebInputEvent.h"
22 #include "ui/gfx/point.h"
23 #include "ui/gfx/point_f.h"
24 #include "ui/gfx/vector2d.h"
25 #include "ui/gfx/vector2d_f.h"
26
27 using blink::WebInputEvent;
28 using blink::WebMouseEvent;
29 using blink::WebMouseWheelEvent;
30 using blink::WebTouchEvent;
31
32 namespace content {
33
34 namespace {
35
36 const int kFlushInputRateInMs = 16;
37 const int kPointerAssumedStoppedTimeMs = 43;
38 const int kTouchSlopInDips = 7;
39
40 class MockSyntheticGesture : public SyntheticGesture {
41  public:
42   MockSyntheticGesture(bool* finished, int num_steps)
43       : finished_(finished),
44         num_steps_(num_steps),
45         step_count_(0) {
46     *finished_ = false;
47   }
48   virtual ~MockSyntheticGesture() {}
49
50   virtual Result ForwardInputEvents(const base::TimeTicks& timestamp,
51                                     SyntheticGestureTarget* target) OVERRIDE {
52     step_count_++;
53     if (step_count_ == num_steps_) {
54       *finished_ = true;
55       return SyntheticGesture::GESTURE_FINISHED;
56     } else if (step_count_ > num_steps_) {
57       *finished_ = true;
58       // Return arbitrary failure.
59       return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
60     }
61
62     return SyntheticGesture::GESTURE_RUNNING;
63   }
64
65  protected:
66   bool* finished_;
67   int num_steps_;
68   int step_count_;
69 };
70
71 class MockSyntheticGestureTarget : public SyntheticGestureTarget {
72  public:
73   MockSyntheticGestureTarget()
74       : num_success_(0),
75         num_failure_(0),
76         flush_requested_(false),
77         pointer_assumed_stopped_time_ms_(kPointerAssumedStoppedTimeMs) {}
78   virtual ~MockSyntheticGestureTarget() {}
79
80   // SyntheticGestureTarget:
81   virtual void DispatchInputEventToPlatform(
82       const WebInputEvent& event) OVERRIDE {}
83
84   virtual void OnSyntheticGestureCompleted(
85       SyntheticGesture::Result result) OVERRIDE {
86     DCHECK_NE(result, SyntheticGesture::GESTURE_RUNNING);
87     if (result == SyntheticGesture::GESTURE_FINISHED)
88       num_success_++;
89     else
90       num_failure_++;
91   }
92
93   virtual void SetNeedsFlush() OVERRIDE {
94     flush_requested_ = true;
95   }
96
97   virtual SyntheticGestureParams::GestureSourceType
98   GetDefaultSyntheticGestureSourceType() const OVERRIDE {
99     return SyntheticGestureParams::TOUCH_INPUT;
100   }
101   virtual bool SupportsSyntheticGestureSourceType(
102       SyntheticGestureParams::GestureSourceType gesture_source_type)
103       const OVERRIDE {
104     return true;
105   }
106
107   virtual base::TimeDelta PointerAssumedStoppedTime() const OVERRIDE {
108     return base::TimeDelta::FromMilliseconds(pointer_assumed_stopped_time_ms_);
109   }
110
111   void set_pointer_assumed_stopped_time_ms(int time_ms) {
112     pointer_assumed_stopped_time_ms_ = time_ms;
113   }
114
115   virtual int GetTouchSlopInDips() const OVERRIDE {
116     return kTouchSlopInDips;
117   }
118
119   int num_success() const { return num_success_; }
120   int num_failure() const { return num_failure_; }
121
122   bool flush_requested() const { return flush_requested_; }
123   void ClearFlushRequest() { flush_requested_ = false; }
124
125  private:
126   int num_success_;
127   int num_failure_;
128
129   bool flush_requested_;
130
131   int pointer_assumed_stopped_time_ms_;
132 };
133
134 class MockSyntheticSmoothScrollGestureTarget
135     : public MockSyntheticGestureTarget {
136  public:
137   MockSyntheticSmoothScrollGestureTarget() {}
138   virtual ~MockSyntheticSmoothScrollGestureTarget() {}
139
140   gfx::Vector2dF scroll_distance() const { return scroll_distance_; }
141
142  protected:
143   gfx::Vector2dF scroll_distance_;
144 };
145
146 class MockSyntheticSmoothScrollMouseTarget
147     : public MockSyntheticSmoothScrollGestureTarget {
148  public:
149   MockSyntheticSmoothScrollMouseTarget() {}
150   virtual ~MockSyntheticSmoothScrollMouseTarget() {}
151
152   virtual void DispatchInputEventToPlatform(
153       const WebInputEvent& event) OVERRIDE {
154     ASSERT_EQ(event.type, WebInputEvent::MouseWheel);
155     const WebMouseWheelEvent& mouse_wheel_event =
156         static_cast<const WebMouseWheelEvent&>(event);
157     scroll_distance_ -= gfx::Vector2dF(mouse_wheel_event.deltaX,
158                                        mouse_wheel_event.deltaY);
159   }
160 };
161
162 class MockSyntheticSmoothScrollTouchTarget
163     : public MockSyntheticSmoothScrollGestureTarget {
164  public:
165   MockSyntheticSmoothScrollTouchTarget()
166       : started_(false) {}
167   virtual ~MockSyntheticSmoothScrollTouchTarget() {}
168
169   virtual void DispatchInputEventToPlatform(
170       const WebInputEvent& event) OVERRIDE {
171     ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type));
172     const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
173     ASSERT_EQ(touch_event.touchesLength, 1U);
174
175     if (!started_) {
176       ASSERT_EQ(touch_event.type, WebInputEvent::TouchStart);
177       anchor_.SetPoint(touch_event.touches[0].position.x,
178                        touch_event.touches[0].position.y);
179       started_ = true;
180     } else {
181       ASSERT_NE(touch_event.type, WebInputEvent::TouchStart);
182       ASSERT_NE(touch_event.type, WebInputEvent::TouchCancel);
183       // Ignore move events.
184
185       if (touch_event.type == WebInputEvent::TouchEnd)
186         scroll_distance_ =
187             anchor_ - gfx::PointF(touch_event.touches[0].position.x,
188                                   touch_event.touches[0].position.y);
189     }
190   }
191
192  protected:
193   gfx::Point anchor_;
194   bool started_;
195 };
196
197 class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
198  public:
199   enum ZoomDirection {
200     ZOOM_DIRECTION_UNKNOWN,
201     ZOOM_IN,
202     ZOOM_OUT
203   };
204
205   MockSyntheticPinchTouchTarget()
206       : total_num_pixels_covered_(0),
207         last_pointer_distance_(0),
208         zoom_direction_(ZOOM_DIRECTION_UNKNOWN),
209         started_(false) {}
210   virtual ~MockSyntheticPinchTouchTarget() {}
211
212   virtual void DispatchInputEventToPlatform(
213       const WebInputEvent& event) OVERRIDE {
214     ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type));
215     const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
216     ASSERT_EQ(touch_event.touchesLength, 2U);
217
218     if (!started_) {
219       ASSERT_EQ(touch_event.type, WebInputEvent::TouchStart);
220
221       start_0_ = gfx::PointF(touch_event.touches[0].position.x,
222                              touch_event.touches[0].position.y);
223       start_1_ = gfx::PointF(touch_event.touches[1].position.x,
224                              touch_event.touches[1].position.y);
225       last_pointer_distance_ = (start_0_ - start_1_).Length();
226
227       started_ = true;
228     } else {
229       ASSERT_NE(touch_event.type, WebInputEvent::TouchStart);
230       ASSERT_NE(touch_event.type, WebInputEvent::TouchCancel);
231
232       gfx::PointF current_0 = gfx::PointF(touch_event.touches[0].position.x,
233                                           touch_event.touches[0].position.y);
234       gfx::PointF current_1 = gfx::PointF(touch_event.touches[1].position.x,
235                                           touch_event.touches[1].position.y);
236
237       total_num_pixels_covered_ =
238           (current_0 - start_0_).Length() + (current_1 - start_1_).Length();
239       float pointer_distance = (current_0 - current_1).Length();
240
241       if (last_pointer_distance_ != pointer_distance) {
242         if (zoom_direction_ == ZOOM_DIRECTION_UNKNOWN)
243           zoom_direction_ =
244               ComputeZoomDirection(last_pointer_distance_, pointer_distance);
245         else
246           EXPECT_EQ(
247               zoom_direction_,
248               ComputeZoomDirection(last_pointer_distance_, pointer_distance));
249       }
250
251       last_pointer_distance_ = pointer_distance;
252     }
253   }
254
255   float total_num_pixels_covered() const { return total_num_pixels_covered_; }
256   ZoomDirection zoom_direction() const { return zoom_direction_; }
257
258  private:
259   ZoomDirection ComputeZoomDirection(float last_pointer_distance,
260                                      float current_pointer_distance) {
261     DCHECK_NE(last_pointer_distance, current_pointer_distance);
262     return last_pointer_distance < current_pointer_distance ? ZOOM_IN
263                                                             : ZOOM_OUT;
264   }
265
266   float total_num_pixels_covered_;
267   float last_pointer_distance_;
268   ZoomDirection zoom_direction_;
269   gfx::PointF start_0_;
270   gfx::PointF start_1_;
271   bool started_;
272 };
273
274 class MockSyntheticTapGestureTarget : public MockSyntheticGestureTarget {
275  public:
276   MockSyntheticTapGestureTarget() : state_(NOT_STARTED) {}
277   virtual ~MockSyntheticTapGestureTarget() {}
278
279   bool GestureFinished() const { return state_ == FINISHED; }
280   gfx::PointF position() const { return position_; }
281   base::TimeDelta GetDuration() const { return stop_time_ - start_time_; }
282
283  protected:
284   enum GestureState {
285     NOT_STARTED,
286     STARTED,
287     FINISHED
288   };
289
290   // TODO(tdresser): clean up accesses to position_ once WebTouchPoint stores
291   // its location as a WebFloatPoint. See crbug.com/336807.
292   gfx::PointF position_;
293   base::TimeDelta start_time_;
294   base::TimeDelta stop_time_;
295   GestureState state_;
296 };
297
298 class MockSyntheticTapTouchTarget : public MockSyntheticTapGestureTarget {
299  public:
300   MockSyntheticTapTouchTarget() {}
301   virtual ~MockSyntheticTapTouchTarget() {}
302
303   virtual void DispatchInputEventToPlatform(
304         const WebInputEvent& event) OVERRIDE {
305     ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type));
306     const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
307     ASSERT_EQ(touch_event.touchesLength, 1U);
308
309     switch (state_) {
310       case NOT_STARTED:
311         EXPECT_EQ(touch_event.type, WebInputEvent::TouchStart);
312         position_ = gfx::PointF(touch_event.touches[0].position.x,
313                                 touch_event.touches[0].position.y);
314         start_time_ = base::TimeDelta::FromMilliseconds(
315             static_cast<int64>(touch_event.timeStampSeconds * 1000));
316         state_ = STARTED;
317         break;
318       case STARTED:
319         EXPECT_EQ(touch_event.type, WebInputEvent::TouchEnd);
320         EXPECT_EQ(position_, gfx::PointF(touch_event.touches[0].position.x,
321                                          touch_event.touches[0].position.y));
322         stop_time_ = base::TimeDelta::FromMilliseconds(
323             static_cast<int64>(touch_event.timeStampSeconds * 1000));
324         state_ = FINISHED;
325         break;
326       case FINISHED:
327         EXPECT_FALSE(true);
328         break;
329     }
330   }
331 };
332
333 class MockSyntheticTapMouseTarget : public MockSyntheticTapGestureTarget {
334  public:
335   MockSyntheticTapMouseTarget() {}
336   virtual ~MockSyntheticTapMouseTarget() {}
337
338   virtual void DispatchInputEventToPlatform(
339         const WebInputEvent& event) OVERRIDE {
340     ASSERT_TRUE(WebInputEvent::isMouseEventType(event.type));
341     const WebMouseEvent& mouse_event = static_cast<const WebMouseEvent&>(event);
342
343     switch (state_) {
344       case NOT_STARTED:
345         EXPECT_EQ(mouse_event.type, WebInputEvent::MouseDown);
346         EXPECT_EQ(mouse_event.button, WebMouseEvent::ButtonLeft);
347         EXPECT_EQ(mouse_event.clickCount, 1);
348         position_ = gfx::Point(mouse_event.x, mouse_event.y);
349         start_time_ = base::TimeDelta::FromMilliseconds(
350             static_cast<int64>(mouse_event.timeStampSeconds * 1000));
351         state_ = STARTED;
352         break;
353       case STARTED:
354         EXPECT_EQ(mouse_event.type, WebInputEvent::MouseUp);
355         EXPECT_EQ(mouse_event.button, WebMouseEvent::ButtonLeft);
356         EXPECT_EQ(mouse_event.clickCount, 1);
357         EXPECT_EQ(position_, gfx::Point(mouse_event.x, mouse_event.y));
358         stop_time_ = base::TimeDelta::FromMilliseconds(
359             static_cast<int64>(mouse_event.timeStampSeconds * 1000));
360         state_ = FINISHED;
361         break;
362       case FINISHED:
363         EXPECT_FALSE(true);
364         break;
365     }
366   }
367 };
368
369 class SyntheticGestureControllerTest : public testing::Test {
370  public:
371   SyntheticGestureControllerTest() {}
372   virtual ~SyntheticGestureControllerTest() {}
373
374  protected:
375   template<typename MockGestureTarget>
376   void CreateControllerAndTarget() {
377     target_ = new MockGestureTarget();
378
379     controller_.reset(new SyntheticGestureController(
380         scoped_ptr<SyntheticGestureTarget>(target_)));
381   }
382
383   virtual void SetUp() OVERRIDE {
384     start_time_ = base::TimeTicks::Now();
385     time_ = start_time_;
386   }
387
388   virtual void TearDown() OVERRIDE {
389     controller_.reset();
390     target_ = NULL;
391     time_ = base::TimeTicks();
392   }
393
394   void FlushInputUntilComplete() {
395     while (target_->flush_requested()) {
396       target_->ClearFlushRequest();
397       time_ += base::TimeDelta::FromMilliseconds(kFlushInputRateInMs);
398       controller_->Flush(time_);
399     }
400   }
401
402   base::TimeDelta GetTotalTime() const { return time_ - start_time_; }
403
404   MockSyntheticGestureTarget* target_;
405   scoped_ptr<SyntheticGestureController> controller_;
406   base::TimeTicks start_time_;
407   base::TimeTicks time_;
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   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
417   FlushInputUntilComplete();
418
419   EXPECT_TRUE(finished);
420   EXPECT_EQ(1, target_->num_success());
421   EXPECT_EQ(0, target_->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   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
431   FlushInputUntilComplete();
432
433   EXPECT_TRUE(finished);
434   EXPECT_EQ(1, target_->num_failure());
435   EXPECT_EQ(0, target_->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   controller_->QueueSyntheticGesture(gesture_1.PassAs<SyntheticGesture>());
449   FlushInputUntilComplete();
450
451   EXPECT_TRUE(finished_1);
452   EXPECT_EQ(1, target_->num_success());
453   EXPECT_EQ(0, target_->num_failure());
454
455   // Queue second gesture.
456   controller_->QueueSyntheticGesture(gesture_2.PassAs<SyntheticGesture>());
457   FlushInputUntilComplete();
458
459   EXPECT_TRUE(finished_2);
460   EXPECT_EQ(2, target_->num_success());
461   EXPECT_EQ(0, target_->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   controller_->QueueSyntheticGesture(gesture_1.PassAs<SyntheticGesture>());
474   controller_->QueueSyntheticGesture(gesture_2.PassAs<SyntheticGesture>());
475   FlushInputUntilComplete();
476
477   EXPECT_TRUE(finished_1);
478   EXPECT_TRUE(finished_2);
479
480   EXPECT_EQ(2, target_->num_success());
481   EXPECT_EQ(0, target_->num_failure());
482 }
483
484 gfx::Vector2d AddTouchSlopToVector(const gfx::Vector2d& vector,
485                                    SyntheticGestureTarget* target) {
486   const int kTouchSlop = target->GetTouchSlopInDips();
487
488   int x = vector.x();
489   if (x > 0)
490     x += kTouchSlop;
491   else if (x < 0)
492     x -= kTouchSlop;
493
494   int y = vector.y();
495   if (y > 0)
496     y += kTouchSlop;
497   else if (y < 0)
498     y -= kTouchSlop;
499
500   return gfx::Vector2d(x, y);
501 }
502
503 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchVertical) {
504   CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
505
506   SyntheticSmoothScrollGestureParams params;
507   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
508   params.distance = gfx::Vector2d(0, 123);
509   params.anchor.SetPoint(89, 32);
510
511   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
512       new SyntheticSmoothScrollGesture(params));
513   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
514   FlushInputUntilComplete();
515
516   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
517       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
518   EXPECT_EQ(1, target_->num_success());
519   EXPECT_EQ(0, target_->num_failure());
520   EXPECT_EQ(AddTouchSlopToVector(params.distance, target_),
521             smooth_scroll_target->scroll_distance());
522 }
523
524 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchHorizontal) {
525   CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
526
527   SyntheticSmoothScrollGestureParams params;
528   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
529   params.distance = gfx::Vector2d(-234, 0);
530   params.anchor.SetPoint(12, -23);
531
532   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
533       new SyntheticSmoothScrollGesture(params));
534   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
535   FlushInputUntilComplete();
536
537   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
538       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
539   EXPECT_EQ(1, target_->num_success());
540   EXPECT_EQ(0, target_->num_failure());
541   EXPECT_EQ(AddTouchSlopToVector(params.distance, target_),
542             smooth_scroll_target->scroll_distance());
543 }
544
545 void CheckIsWithinRange(float scroll_distance,
546                         int target_distance,
547                         SyntheticGestureTarget* target) {
548   if (target_distance > 0) {
549     EXPECT_LE(target_distance, scroll_distance);
550     EXPECT_LE(scroll_distance, target_distance + target->GetTouchSlopInDips());
551   } else {
552     EXPECT_GE(target_distance, scroll_distance);
553     EXPECT_GE(scroll_distance, target_distance - target->GetTouchSlopInDips());
554   }
555 }
556
557 void CheckScrollDistanceIsWithinRange(const gfx::Vector2dF& scroll_distance,
558                                       const gfx::Vector2d& target_distance,
559                                       SyntheticGestureTarget* target) {
560   CheckIsWithinRange(scroll_distance.x(), target_distance.x(), target);
561   CheckIsWithinRange(scroll_distance.y(), target_distance.y(), target);
562 }
563
564 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchDiagonal) {
565   CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
566
567   SyntheticSmoothScrollGestureParams params;
568   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
569   params.distance = gfx::Vector2d(413, -83);
570   params.anchor.SetPoint(0, 7);
571
572   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
573       new SyntheticSmoothScrollGesture(params));
574   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
575   FlushInputUntilComplete();
576
577   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
578       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
579   EXPECT_EQ(1, target_->num_success());
580   EXPECT_EQ(0, target_->num_failure());
581   CheckScrollDistanceIsWithinRange(
582       smooth_scroll_target->scroll_distance(), params.distance, target_);
583 }
584
585 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchLongStop) {
586   CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
587
588   // Create a smooth scroll with a short distance and set the pointer assumed
589   // stopped time high, so that the stopping should dominate the time the
590   // gesture is active.
591   SyntheticSmoothScrollGestureParams params;
592   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
593   params.distance = gfx::Vector2d(21, -12);
594   params.prevent_fling = true;
595   params.anchor.SetPoint(-98, -23);
596
597   target_->set_pointer_assumed_stopped_time_ms(543);
598
599   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
600       new SyntheticSmoothScrollGesture(params));
601   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
602   FlushInputUntilComplete();
603
604   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
605       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
606   EXPECT_EQ(1, target_->num_success());
607   EXPECT_EQ(0, target_->num_failure());
608   CheckScrollDistanceIsWithinRange(
609       smooth_scroll_target->scroll_distance(), params.distance, target_);
610   EXPECT_GE(GetTotalTime(), target_->PointerAssumedStoppedTime());
611 }
612
613 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchFling) {
614   CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
615
616   // Create a smooth scroll with a short distance and set the pointer assumed
617   // stopped time high. Disable 'prevent_fling' and check that the gesture
618   // finishes without waiting before it stops.
619   SyntheticSmoothScrollGestureParams params;
620   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
621   params.distance = gfx::Vector2d(-43, 19);
622   params.prevent_fling = false;
623   params.anchor.SetPoint(-89, 78);
624
625   target_->set_pointer_assumed_stopped_time_ms(543);
626
627   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
628       new SyntheticSmoothScrollGesture(params));
629   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
630   FlushInputUntilComplete();
631
632   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
633       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
634   EXPECT_EQ(1, target_->num_success());
635   EXPECT_EQ(0, target_->num_failure());
636   CheckScrollDistanceIsWithinRange(
637       smooth_scroll_target->scroll_distance(), params.distance, target_);
638   EXPECT_LE(GetTotalTime(), target_->PointerAssumedStoppedTime());
639 }
640
641 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchZeroDistance) {
642   CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
643
644   SyntheticSmoothScrollGestureParams params;
645   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
646   params.distance = gfx::Vector2d(0, 0);
647   params.anchor.SetPoint(-32, 43);
648
649   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
650       new SyntheticSmoothScrollGesture(params));
651   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
652   FlushInputUntilComplete();
653
654   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
655       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
656   EXPECT_EQ(1, target_->num_success());
657   EXPECT_EQ(0, target_->num_failure());
658   EXPECT_EQ(gfx::Vector2dF(0, 0), smooth_scroll_target->scroll_distance());
659 }
660
661 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouseVertical) {
662   CreateControllerAndTarget<MockSyntheticSmoothScrollMouseTarget>();
663
664   SyntheticSmoothScrollGestureParams params;
665   params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
666   params.distance = gfx::Vector2d(0, -234);
667   params.anchor.SetPoint(432, 89);
668
669   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
670       new SyntheticSmoothScrollGesture(params));
671   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
672   FlushInputUntilComplete();
673
674   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
675       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
676   EXPECT_EQ(1, target_->num_success());
677   EXPECT_EQ(0, target_->num_failure());
678   EXPECT_EQ(params.distance, smooth_scroll_target->scroll_distance());
679 }
680
681 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouseHorizontal) {
682   CreateControllerAndTarget<MockSyntheticSmoothScrollMouseTarget>();
683
684   SyntheticSmoothScrollGestureParams params;
685   params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
686   params.distance = gfx::Vector2d(345, 0);
687   params.anchor.SetPoint(90, 12);
688
689   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
690       new SyntheticSmoothScrollGesture(params));
691   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
692   FlushInputUntilComplete();
693
694   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
695       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
696   EXPECT_EQ(1, target_->num_success());
697   EXPECT_EQ(0, target_->num_failure());
698   EXPECT_EQ(params.distance, smooth_scroll_target->scroll_distance());
699 }
700
701 TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouseDiagonal) {
702   CreateControllerAndTarget<MockSyntheticSmoothScrollMouseTarget>();
703
704   SyntheticSmoothScrollGestureParams params;
705   params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
706   params.distance = gfx::Vector2d(-194, 303);
707   params.anchor.SetPoint(90, 12);
708
709   scoped_ptr<SyntheticSmoothScrollGesture> gesture(
710       new SyntheticSmoothScrollGesture(params));
711   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
712   FlushInputUntilComplete();
713
714   MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
715       static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
716   EXPECT_EQ(1, target_->num_success());
717   EXPECT_EQ(0, target_->num_failure());
718   EXPECT_EQ(params.distance, smooth_scroll_target->scroll_distance());
719 }
720
721 TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) {
722   CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
723
724   SyntheticPinchGestureParams params;
725   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
726   params.zoom_in = true;
727   params.total_num_pixels_covered = 345;
728   params.anchor.SetPoint(54, 89);
729
730   scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
731   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
732   FlushInputUntilComplete();
733
734   MockSyntheticPinchTouchTarget* pinch_target =
735       static_cast<MockSyntheticPinchTouchTarget*>(target_);
736   EXPECT_EQ(1, target_->num_success());
737   EXPECT_EQ(0, target_->num_failure());
738   EXPECT_EQ(pinch_target->zoom_direction(),
739             MockSyntheticPinchTouchTarget::ZOOM_IN);
740   EXPECT_EQ(params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(),
741             pinch_target->total_num_pixels_covered());
742 }
743
744 TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
745   CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
746
747   SyntheticPinchGestureParams params;
748   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
749   params.zoom_in = false;
750   params.total_num_pixels_covered = 456;
751   params.anchor.SetPoint(-12, 93);
752
753   scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
754   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
755   FlushInputUntilComplete();
756
757   MockSyntheticPinchTouchTarget* pinch_target =
758       static_cast<MockSyntheticPinchTouchTarget*>(target_);
759   EXPECT_EQ(1, target_->num_success());
760   EXPECT_EQ(0, target_->num_failure());
761   EXPECT_EQ(pinch_target->zoom_direction(),
762             MockSyntheticPinchTouchTarget::ZOOM_OUT);
763   EXPECT_EQ(params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(),
764             pinch_target->total_num_pixels_covered());
765 }
766
767 TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZeroPixelsCovered) {
768   CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
769
770   SyntheticPinchGestureParams params;
771   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
772   params.zoom_in = true;
773   params.total_num_pixels_covered = 0;
774
775   scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
776   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
777   FlushInputUntilComplete();
778
779   MockSyntheticPinchTouchTarget* pinch_target =
780       static_cast<MockSyntheticPinchTouchTarget*>(target_);
781   EXPECT_EQ(1, target_->num_success());
782   EXPECT_EQ(0, target_->num_failure());
783   EXPECT_EQ(pinch_target->zoom_direction(),
784             MockSyntheticPinchTouchTarget::ZOOM_DIRECTION_UNKNOWN);
785   EXPECT_EQ(0, pinch_target->total_num_pixels_covered());
786 }
787
788 TEST_F(SyntheticGestureControllerTest, TapGestureTouch) {
789   CreateControllerAndTarget<MockSyntheticTapTouchTarget>();
790
791   SyntheticTapGestureParams params;
792   params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
793   params.duration_ms = 123;
794   params.position.SetPoint(87, -124);
795
796   scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
797   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
798   FlushInputUntilComplete();
799
800   MockSyntheticTapTouchTarget* tap_target =
801       static_cast<MockSyntheticTapTouchTarget*>(target_);
802   EXPECT_EQ(1, target_->num_success());
803   EXPECT_EQ(0, target_->num_failure());
804   EXPECT_TRUE(tap_target->GestureFinished());
805   EXPECT_EQ(tap_target->position(), params.position);
806   EXPECT_EQ(tap_target->GetDuration().InMilliseconds(), params.duration_ms);
807   EXPECT_GE(GetTotalTime(),
808             base::TimeDelta::FromMilliseconds(params.duration_ms));
809 }
810
811 TEST_F(SyntheticGestureControllerTest, TapGestureMouse) {
812   CreateControllerAndTarget<MockSyntheticTapMouseTarget>();
813
814   SyntheticTapGestureParams params;
815   params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
816   params.duration_ms = 79;
817   params.position.SetPoint(98, 123);
818
819   scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
820   controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
821   FlushInputUntilComplete();
822
823   MockSyntheticTapMouseTarget* tap_target =
824       static_cast<MockSyntheticTapMouseTarget*>(target_);
825   EXPECT_EQ(1, target_->num_success());
826   EXPECT_EQ(0, target_->num_failure());
827   EXPECT_TRUE(tap_target->GestureFinished());
828   EXPECT_EQ(tap_target->position(), params.position);
829   EXPECT_EQ(tap_target->GetDuration().InMilliseconds(), params.duration_ms);
830   EXPECT_GE(GetTotalTime(),
831             base::TimeDelta::FromMilliseconds(params.duration_ms));
832 }
833
834 }  // namespace
835
836 }  // namespace content