Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / touch_emulator_unittest.cc
1 // Copyright 2014 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 <vector>
6
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/time/time.h"
11 #include "content/browser/renderer_host/input/touch_emulator.h"
12 #include "content/browser/renderer_host/input/touch_emulator_client.h"
13 #include "content/common/input/web_input_event_traits.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/events/gesture_detection/gesture_config_helper.h"
16
17 #if defined(USE_AURA)
18 #include "ui/aura/env.h"
19 #include "ui/aura/test/test_screen.h"
20 #endif
21
22 using blink::WebGestureEvent;
23 using blink::WebInputEvent;
24 using blink::WebKeyboardEvent;
25 using blink::WebMouseEvent;
26 using blink::WebMouseWheelEvent;
27 using blink::WebTouchEvent;
28 using blink::WebTouchPoint;
29
30 namespace content {
31
32 class TouchEmulatorTest : public testing::Test,
33                           public TouchEmulatorClient {
34  public:
35   TouchEmulatorTest()
36       : shift_pressed_(false),
37         mouse_pressed_(false),
38         last_mouse_x_(-1),
39         last_mouse_y_(-1) {
40     last_event_time_seconds_ =
41         (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
42     event_time_delta_seconds_ = 0.1;
43   }
44
45   virtual ~TouchEmulatorTest() {}
46
47   // testing::Test
48   virtual void SetUp() OVERRIDE {
49 #if defined(USE_AURA)
50     aura::Env::CreateInstance(true);
51     screen_.reset(aura::TestScreen::Create(gfx::Size()));
52     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
53 #endif
54
55     emulator_.reset(new TouchEmulator(this));
56     emulator_->Enable(true /* allow_pinch */);
57   }
58
59   virtual void TearDown() OVERRIDE {
60     emulator_->Disable();
61     EXPECT_EQ("", ExpectedEvents());
62
63 #if defined(USE_AURA)
64     aura::Env::DeleteInstance();
65     screen_.reset();
66 #endif
67   }
68
69   virtual void ForwardGestureEvent(
70       const blink::WebGestureEvent& event) OVERRIDE {
71     forwarded_events_.push_back(event.type);
72   }
73
74   virtual void ForwardTouchEvent(
75       const blink::WebTouchEvent& event) OVERRIDE {
76     forwarded_events_.push_back(event.type);
77     EXPECT_EQ(1U, event.touchesLength);
78     EXPECT_EQ(last_mouse_x_, event.touches[0].position.x);
79     EXPECT_EQ(last_mouse_y_, event.touches[0].position.y);
80     int expectedCancelable = event.type != WebInputEvent::TouchCancel;
81     EXPECT_EQ(expectedCancelable, event.cancelable);
82     emulator()->HandleTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
83   }
84
85   virtual void SetCursor(const WebCursor& cursor) OVERRIDE {}
86
87   virtual void ShowContextMenuAtPoint(const gfx::Point& point) OVERRIDE {}
88
89  protected:
90   TouchEmulator* emulator() const {
91     return emulator_.get();
92   }
93
94   int modifiers() const {
95     return shift_pressed_ ? WebInputEvent::ShiftKey : 0;
96   }
97
98   std::string ExpectedEvents() {
99     std::string result;
100     for (size_t i = 0; i < forwarded_events_.size(); ++i) {
101       if (i != 0)
102         result += " ";
103       result += WebInputEventTraits::GetName(forwarded_events_[i]);
104     }
105     forwarded_events_.clear();
106     return result;
107   }
108
109   double GetNextEventTimeSeconds() {
110     last_event_time_seconds_ += event_time_delta_seconds_;
111     return last_event_time_seconds_;
112   }
113
114   void set_event_time_delta_seconds_(double delta) {
115     event_time_delta_seconds_ = delta;
116   }
117
118   void SendKeyboardEvent(WebInputEvent::Type type) {
119     WebKeyboardEvent event;
120     event.timeStampSeconds = GetNextEventTimeSeconds();
121     event.type = type;
122     event.modifiers = modifiers();
123     emulator()->HandleKeyboardEvent(event);
124   }
125
126   void PressShift() {
127     DCHECK(!shift_pressed_);
128     shift_pressed_ = true;
129     SendKeyboardEvent(WebInputEvent::KeyDown);
130   }
131
132   void ReleaseShift() {
133     DCHECK(shift_pressed_);
134     shift_pressed_ = false;
135     SendKeyboardEvent(WebInputEvent::KeyUp);
136   }
137
138   void SendMouseEvent(WebInputEvent::Type type, int  x, int y) {
139     WebMouseEvent event;
140     event.timeStampSeconds = GetNextEventTimeSeconds();
141     event.type = type;
142     event.button = mouse_pressed_ ? WebMouseEvent::ButtonLeft :
143         WebMouseEvent::ButtonNone;
144     event.modifiers = modifiers();
145     last_mouse_x_ = x;
146     last_mouse_y_ = y;
147     event.x = event.windowX = event.globalX = x;
148     event.y = event.windowY = event.globalY = y;
149     emulator()->HandleMouseEvent(event);
150   }
151
152   bool SendMouseWheelEvent() {
153     WebMouseWheelEvent event;
154     event.type = WebInputEvent::MouseWheel;
155     event.timeStampSeconds = GetNextEventTimeSeconds();
156     // Return whether mouse wheel is forwarded.
157     return !emulator()->HandleMouseWheelEvent(event);
158   }
159
160   void MouseDown(int x, int y) {
161     DCHECK(!mouse_pressed_);
162     if (x != last_mouse_x_ || y != last_mouse_y_)
163       SendMouseEvent(WebInputEvent::MouseMove, x, y);
164     mouse_pressed_ = true;
165     SendMouseEvent(WebInputEvent::MouseDown, x, y);
166   }
167
168   void MouseDrag(int x, int y) {
169     DCHECK(mouse_pressed_);
170     SendMouseEvent(WebInputEvent::MouseMove, x, y);
171   }
172
173   void MouseMove(int x, int y) {
174     DCHECK(!mouse_pressed_);
175     SendMouseEvent(WebInputEvent::MouseMove, x, y);
176   }
177
178   void MouseUp(int x, int y) {
179     DCHECK(mouse_pressed_);
180     if (x != last_mouse_x_ || y != last_mouse_y_)
181       SendMouseEvent(WebInputEvent::MouseMove, x, y);
182     SendMouseEvent(WebInputEvent::MouseUp, x, y);
183     mouse_pressed_ = false;
184   }
185
186  private:
187   scoped_ptr<TouchEmulator> emulator_;
188   std::vector<WebInputEvent::Type> forwarded_events_;
189 #if defined(USE_AURA)
190   scoped_ptr<gfx::Screen> screen_;
191 #endif
192   double last_event_time_seconds_;
193   double event_time_delta_seconds_;
194   bool shift_pressed_;
195   bool mouse_pressed_;
196   int last_mouse_x_;
197   int last_mouse_y_;
198   base::MessageLoopForUI message_loop_;
199 };
200
201
202 TEST_F(TouchEmulatorTest, NoTouches) {
203   MouseMove(100, 200);
204   MouseMove(300, 300);
205   EXPECT_EQ("", ExpectedEvents());
206 }
207
208 TEST_F(TouchEmulatorTest, Touch) {
209   MouseMove(100, 200);
210   EXPECT_EQ("", ExpectedEvents());
211   MouseDown(100, 200);
212   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
213   MouseUp(200, 200);
214   EXPECT_EQ(
215       "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate"
216       " TouchEnd GestureScrollEnd",
217       ExpectedEvents());
218 }
219
220 TEST_F(TouchEmulatorTest, MultipleTouches) {
221   MouseMove(100, 200);
222   EXPECT_EQ("", ExpectedEvents());
223   MouseDown(100, 200);
224   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
225   MouseUp(200, 200);
226   EXPECT_EQ(
227       "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate"
228       " TouchEnd GestureScrollEnd",
229       ExpectedEvents());
230   MouseMove(300, 200);
231   MouseMove(200, 200);
232   EXPECT_EQ("", ExpectedEvents());
233   MouseDown(300, 200);
234   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
235   MouseDrag(300, 300);
236   EXPECT_EQ(
237       "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
238       ExpectedEvents());
239   MouseDrag(300, 400);
240   EXPECT_EQ("TouchMove GestureScrollUpdate", ExpectedEvents());
241   MouseUp(300, 500);
242   EXPECT_EQ(
243       "TouchMove GestureScrollUpdate TouchEnd GestureScrollEnd",
244       ExpectedEvents());
245 }
246
247 TEST_F(TouchEmulatorTest, Pinch) {
248   MouseDown(100, 200);
249   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
250   MouseDrag(200, 200);
251   EXPECT_EQ(
252       "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
253       ExpectedEvents());
254   PressShift();
255   EXPECT_EQ("", ExpectedEvents());
256   MouseDrag(300, 200);
257   EXPECT_EQ("TouchMove GesturePinchBegin", ExpectedEvents());
258   ReleaseShift();
259   EXPECT_EQ("", ExpectedEvents());
260   MouseDrag(400, 200);
261   EXPECT_EQ(
262       "TouchMove GesturePinchEnd GestureScrollUpdate",
263       ExpectedEvents());
264   MouseUp(400, 200);
265   EXPECT_EQ("TouchEnd GestureScrollEnd", ExpectedEvents());
266 }
267
268 TEST_F(TouchEmulatorTest, DisableAndReenable) {
269   MouseDown(100, 200);
270   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
271   MouseDrag(200, 200);
272   EXPECT_EQ(
273       "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
274       ExpectedEvents());
275   PressShift();
276   MouseDrag(300, 200);
277   EXPECT_EQ("TouchMove GesturePinchBegin", ExpectedEvents());
278
279   // Disable while pinch is in progress.
280   emulator()->Disable();
281   EXPECT_EQ("TouchCancel GesturePinchEnd GestureScrollEnd", ExpectedEvents());
282   MouseUp(300, 200);
283   ReleaseShift();
284   MouseMove(300, 300);
285   EXPECT_EQ("", ExpectedEvents());
286
287   emulator()->Enable(true /* allow_pinch */);
288   MouseDown(300, 300);
289   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
290   MouseDrag(300, 400);
291   EXPECT_EQ(
292       "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
293       ExpectedEvents());
294
295   // Disable while scroll is in progress.
296   emulator()->Disable();
297   EXPECT_EQ("TouchCancel GestureScrollEnd", ExpectedEvents());
298 }
299
300 TEST_F(TouchEmulatorTest, MouseMovesDropped) {
301   MouseMove(100, 200);
302   EXPECT_EQ("", ExpectedEvents());
303   MouseDown(100, 200);
304   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
305
306   // Mouse move after mouse down is never dropped.
307   set_event_time_delta_seconds_(0.001);
308   MouseDrag(200, 200);
309   EXPECT_EQ(
310       "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
311       ExpectedEvents());
312
313   // The following mouse moves are dropped.
314   MouseDrag(300, 200);
315   EXPECT_EQ("", ExpectedEvents());
316   MouseDrag(350, 200);
317   EXPECT_EQ("", ExpectedEvents());
318
319   // Dispatching again.
320   set_event_time_delta_seconds_(0.1);
321   MouseDrag(400, 200);
322   EXPECT_EQ(
323       "TouchMove GestureScrollUpdate",
324       ExpectedEvents());
325   MouseUp(400, 200);
326   EXPECT_EQ(
327       "TouchEnd GestureScrollEnd",
328       ExpectedEvents());
329 }
330
331 TEST_F(TouchEmulatorTest, MouseWheel) {
332   MouseMove(100, 200);
333   EXPECT_EQ("", ExpectedEvents());
334   EXPECT_TRUE(SendMouseWheelEvent());
335   MouseDown(100, 200);
336   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
337   EXPECT_FALSE(SendMouseWheelEvent());
338   MouseUp(100, 200);
339   EXPECT_EQ("TouchEnd GestureShowPress GestureTap", ExpectedEvents());
340   EXPECT_TRUE(SendMouseWheelEvent());
341   MouseDown(300, 200);
342   EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
343   EXPECT_FALSE(SendMouseWheelEvent());
344   emulator()->Disable();
345   EXPECT_EQ("TouchCancel GestureTapCancel", ExpectedEvents());
346   EXPECT_TRUE(SendMouseWheelEvent());
347   emulator()->Enable(true /* allow_pinch */);
348   EXPECT_TRUE(SendMouseWheelEvent());
349 }
350
351 }  // namespace content