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.
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"
18 #include "ui/aura/env.h"
19 #include "ui/aura/test/test_screen.h"
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;
32 class TouchEmulatorTest : public testing::Test,
33 public TouchEmulatorClient {
36 : shift_pressed_(false),
37 mouse_pressed_(false),
40 last_event_time_seconds_ =
41 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
42 event_time_delta_seconds_ = 0.1;
45 virtual ~TouchEmulatorTest() {}
48 virtual void SetUp() OVERRIDE {
50 aura::Env::CreateInstance(true);
51 screen_.reset(aura::TestScreen::Create(gfx::Size()));
52 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
55 emulator_.reset(new TouchEmulator(this));
56 emulator_->Enable(true /* allow_pinch */);
59 virtual void TearDown() OVERRIDE {
61 EXPECT_EQ("", ExpectedEvents());
64 aura::Env::DeleteInstance();
69 virtual void ForwardGestureEvent(
70 const blink::WebGestureEvent& event) OVERRIDE {
71 forwarded_events_.push_back(event.type);
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);
85 virtual void SetCursor(const WebCursor& cursor) OVERRIDE {}
87 virtual void ShowContextMenuAtPoint(const gfx::Point& point) OVERRIDE {}
90 TouchEmulator* emulator() const {
91 return emulator_.get();
94 int modifiers() const {
95 return shift_pressed_ ? WebInputEvent::ShiftKey : 0;
98 std::string ExpectedEvents() {
100 for (size_t i = 0; i < forwarded_events_.size(); ++i) {
103 result += WebInputEventTraits::GetName(forwarded_events_[i]);
105 forwarded_events_.clear();
109 double GetNextEventTimeSeconds() {
110 last_event_time_seconds_ += event_time_delta_seconds_;
111 return last_event_time_seconds_;
114 void set_event_time_delta_seconds_(double delta) {
115 event_time_delta_seconds_ = delta;
118 void SendKeyboardEvent(WebInputEvent::Type type) {
119 WebKeyboardEvent event;
120 event.timeStampSeconds = GetNextEventTimeSeconds();
122 event.modifiers = modifiers();
123 emulator()->HandleKeyboardEvent(event);
127 DCHECK(!shift_pressed_);
128 shift_pressed_ = true;
129 SendKeyboardEvent(WebInputEvent::KeyDown);
132 void ReleaseShift() {
133 DCHECK(shift_pressed_);
134 shift_pressed_ = false;
135 SendKeyboardEvent(WebInputEvent::KeyUp);
138 void SendMouseEvent(WebInputEvent::Type type, int x, int y) {
140 event.timeStampSeconds = GetNextEventTimeSeconds();
142 event.button = mouse_pressed_ ? WebMouseEvent::ButtonLeft :
143 WebMouseEvent::ButtonNone;
144 event.modifiers = modifiers();
147 event.x = event.windowX = event.globalX = x;
148 event.y = event.windowY = event.globalY = y;
149 emulator()->HandleMouseEvent(event);
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);
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);
168 void MouseDrag(int x, int y) {
169 DCHECK(mouse_pressed_);
170 SendMouseEvent(WebInputEvent::MouseMove, x, y);
173 void MouseMove(int x, int y) {
174 DCHECK(!mouse_pressed_);
175 SendMouseEvent(WebInputEvent::MouseMove, x, y);
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;
187 scoped_ptr<TouchEmulator> emulator_;
188 std::vector<WebInputEvent::Type> forwarded_events_;
189 #if defined(USE_AURA)
190 scoped_ptr<gfx::Screen> screen_;
192 double last_event_time_seconds_;
193 double event_time_delta_seconds_;
198 base::MessageLoopForUI message_loop_;
202 TEST_F(TouchEmulatorTest, NoTouches) {
205 EXPECT_EQ("", ExpectedEvents());
208 TEST_F(TouchEmulatorTest, Touch) {
210 EXPECT_EQ("", ExpectedEvents());
212 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
215 "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate"
216 " TouchEnd GestureScrollEnd",
220 TEST_F(TouchEmulatorTest, MultipleTouches) {
222 EXPECT_EQ("", ExpectedEvents());
224 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
227 "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate"
228 " TouchEnd GestureScrollEnd",
232 EXPECT_EQ("", ExpectedEvents());
234 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
237 "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
240 EXPECT_EQ("TouchMove GestureScrollUpdate", ExpectedEvents());
243 "TouchMove GestureScrollUpdate TouchEnd GestureScrollEnd",
247 TEST_F(TouchEmulatorTest, Pinch) {
249 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
252 "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
255 EXPECT_EQ("", ExpectedEvents());
257 EXPECT_EQ("TouchMove GesturePinchBegin", ExpectedEvents());
259 EXPECT_EQ("", ExpectedEvents());
262 "TouchMove GesturePinchEnd GestureScrollUpdate",
265 EXPECT_EQ("TouchEnd GestureScrollEnd", ExpectedEvents());
268 TEST_F(TouchEmulatorTest, DisableAndReenable) {
270 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
273 "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
277 EXPECT_EQ("TouchMove GesturePinchBegin", ExpectedEvents());
279 // Disable while pinch is in progress.
280 emulator()->Disable();
281 EXPECT_EQ("TouchCancel GesturePinchEnd GestureScrollEnd", ExpectedEvents());
285 EXPECT_EQ("", ExpectedEvents());
287 emulator()->Enable(true /* allow_pinch */);
289 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
292 "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
295 // Disable while scroll is in progress.
296 emulator()->Disable();
297 EXPECT_EQ("TouchCancel GestureScrollEnd", ExpectedEvents());
300 TEST_F(TouchEmulatorTest, MouseMovesDropped) {
302 EXPECT_EQ("", ExpectedEvents());
304 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
306 // Mouse move after mouse down is never dropped.
307 set_event_time_delta_seconds_(0.001);
310 "TouchMove GestureTapCancel GestureScrollBegin GestureScrollUpdate",
313 // The following mouse moves are dropped.
315 EXPECT_EQ("", ExpectedEvents());
317 EXPECT_EQ("", ExpectedEvents());
319 // Dispatching again.
320 set_event_time_delta_seconds_(0.1);
323 "TouchMove GestureScrollUpdate",
327 "TouchEnd GestureScrollEnd",
331 TEST_F(TouchEmulatorTest, MouseWheel) {
333 EXPECT_EQ("", ExpectedEvents());
334 EXPECT_TRUE(SendMouseWheelEvent());
336 EXPECT_EQ("TouchStart GestureTapDown", ExpectedEvents());
337 EXPECT_FALSE(SendMouseWheelEvent());
339 EXPECT_EQ("TouchEnd GestureShowPress GestureTap", ExpectedEvents());
340 EXPECT_TRUE(SendMouseWheelEvent());
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());
351 } // namespace content