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 "content/common/input/input_param_traits.h"
6
7#include "content/common/input/input_event.h"
8#include "content/common/input/synthetic_gesture_params.h"
9#include "content/common/input/synthetic_pinch_gesture_params.h"
10#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
11#include "content/common/input_messages.h"
12#include "ipc/ipc_message.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "third_party/WebKit/public/web/WebInputEvent.h"
15
16namespace content {
17namespace {
18
19typedef ScopedVector<InputEvent> InputEvents;
20
21class InputParamTraitsTest : public testing::Test {
22 protected:
23  static void Compare(const InputEvent* a, const InputEvent* b) {
24    EXPECT_EQ(!!a->web_event, !!b->web_event);
25    if (a->web_event && b->web_event) {
26      const size_t a_size = a->web_event->size;
27      ASSERT_EQ(a_size, b->web_event->size);
28      EXPECT_EQ(0, memcmp(a->web_event.get(), b->web_event.get(), a_size));
29    }
30    EXPECT_EQ(a->latency_info.latency_components.size(),
31              b->latency_info.latency_components.size());
32    EXPECT_EQ(a->is_keyboard_shortcut, b->is_keyboard_shortcut);
33  }
34
35  static void Compare(const InputEvents* a, const InputEvents* b) {
36    for (size_t i = 0; i < a->size(); ++i)
37      Compare((*a)[i], (*b)[i]);
38  }
39
40  static void Compare(const SyntheticSmoothScrollGestureParams* a,
41                      const SyntheticSmoothScrollGestureParams* b) {
42    EXPECT_EQ(a->gesture_source_type, b->gesture_source_type);
43    EXPECT_EQ(a->anchor, b->anchor);
44    EXPECT_EQ(a->distances.size(), b->distances.size());
45    for (size_t i = 0; i < a->distances.size(); i++)
46        EXPECT_EQ(a->distances[i], b->distances[i]);
47    EXPECT_EQ(a->prevent_fling, b->prevent_fling);
48    EXPECT_EQ(a->speed_in_pixels_s, b->speed_in_pixels_s);
49  }
50
51  static void Compare(const SyntheticPinchGestureParams* a,
52                      const SyntheticPinchGestureParams* b) {
53    EXPECT_EQ(a->gesture_source_type, b->gesture_source_type);
54    EXPECT_EQ(a->scale_factor, b->scale_factor);
55    EXPECT_EQ(a->anchor, b->anchor);
56    EXPECT_EQ(a->relative_pointer_speed_in_pixels_s,
57              b->relative_pointer_speed_in_pixels_s);
58  }
59
60  static void Compare(const SyntheticTapGestureParams* a,
61                      const SyntheticTapGestureParams* b) {
62    EXPECT_EQ(a->gesture_source_type, b->gesture_source_type);
63    EXPECT_EQ(a->position, b->position);
64    EXPECT_EQ(a->duration_ms, b->duration_ms);
65  }
66
67  static void Compare(const SyntheticGesturePacket* a,
68                      const SyntheticGesturePacket* b) {
69    ASSERT_EQ(!!a, !!b);
70    if (!a) return;
71    ASSERT_EQ(!!a->gesture_params(), !!b->gesture_params());
72    if (!a->gesture_params()) return;
73    ASSERT_EQ(a->gesture_params()->GetGestureType(),
74              b->gesture_params()->GetGestureType());
75    switch (a->gesture_params()->GetGestureType()) {
76      case SyntheticGestureParams::SMOOTH_SCROLL_GESTURE:
77        Compare(SyntheticSmoothScrollGestureParams::Cast(a->gesture_params()),
78                SyntheticSmoothScrollGestureParams::Cast(b->gesture_params()));
79        break;
80      case SyntheticGestureParams::PINCH_GESTURE:
81        Compare(SyntheticPinchGestureParams::Cast(a->gesture_params()),
82                SyntheticPinchGestureParams::Cast(b->gesture_params()));
83        break;
84      case SyntheticGestureParams::TAP_GESTURE:
85        Compare(SyntheticTapGestureParams::Cast(a->gesture_params()),
86                SyntheticTapGestureParams::Cast(b->gesture_params()));
87        break;
88    }
89  }
90
91  static void Verify(const InputEvents& events_in) {
92    IPC::Message msg;
93    IPC::ParamTraits<InputEvents>::Write(&msg, events_in);
94
95    InputEvents events_out;
96    PickleIterator iter(msg);
97    EXPECT_TRUE(IPC::ParamTraits<InputEvents>::Read(&msg, &iter, &events_out));
98
99    Compare(&events_in, &events_out);
100
101    // Perform a sanity check that logging doesn't explode.
102    std::string events_in_string;
103    IPC::ParamTraits<InputEvents>::Log(events_in, &events_in_string);
104    std::string events_out_string;
105    IPC::ParamTraits<InputEvents>::Log(events_out, &events_out_string);
106    ASSERT_FALSE(events_in_string.empty());
107    EXPECT_EQ(events_in_string, events_out_string);
108  }
109
110  static void Verify(const SyntheticGesturePacket& packet_in) {
111    IPC::Message msg;
112    IPC::ParamTraits<SyntheticGesturePacket>::Write(&msg, packet_in);
113
114    SyntheticGesturePacket packet_out;
115    PickleIterator iter(msg);
116    EXPECT_TRUE(IPC::ParamTraits<SyntheticGesturePacket>::Read(&msg, &iter,
117                                                               &packet_out));
118
119    Compare(&packet_in, &packet_out);
120
121    // Perform a sanity check that logging doesn't explode.
122    std::string packet_in_string;
123    IPC::ParamTraits<SyntheticGesturePacket>::Log(packet_in, &packet_in_string);
124    std::string packet_out_string;
125    IPC::ParamTraits<SyntheticGesturePacket>::Log(packet_out,
126                                                  &packet_out_string);
127    ASSERT_FALSE(packet_in_string.empty());
128    EXPECT_EQ(packet_in_string, packet_out_string);
129  }
130};
131
132TEST_F(InputParamTraitsTest, UninitializedEvents) {
133  InputEvent event;
134
135  IPC::Message msg;
136  IPC::WriteParam(&msg, event);
137
138  InputEvent event_out;
139  PickleIterator iter(msg);
140  EXPECT_FALSE(IPC::ReadParam(&msg, &iter, &event_out));
141}
142
143TEST_F(InputParamTraitsTest, InitializedEvents) {
144  InputEvents events;
145
146  ui::LatencyInfo latency;
147
148  blink::WebKeyboardEvent key_event;
149  key_event.type = blink::WebInputEvent::RawKeyDown;
150  key_event.nativeKeyCode = 5;
151  events.push_back(new InputEvent(key_event, latency, false));
152
153  blink::WebMouseWheelEvent wheel_event;
154  wheel_event.type = blink::WebInputEvent::MouseWheel;
155  wheel_event.deltaX = 10;
156  latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 1, 1);
157  events.push_back(new InputEvent(wheel_event, latency, false));
158
159  blink::WebMouseEvent mouse_event;
160  mouse_event.type = blink::WebInputEvent::MouseDown;
161  mouse_event.x = 10;
162  latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 2, 2);
163  events.push_back(new InputEvent(mouse_event, latency, false));
164
165  blink::WebGestureEvent gesture_event;
166  gesture_event.type = blink::WebInputEvent::GestureScrollBegin;
167  gesture_event.x = -1;
168  events.push_back(new InputEvent(gesture_event, latency, false));
169
170  blink::WebTouchEvent touch_event;
171  touch_event.type = blink::WebInputEvent::TouchStart;
172  touch_event.touchesLength = 1;
173  touch_event.touches[0].radiusX = 1;
174  events.push_back(new InputEvent(touch_event, latency, false));
175
176  Verify(events);
177}
178
179TEST_F(InputParamTraitsTest, InvalidSyntheticGestureParams) {
180  IPC::Message msg;
181  // Write invalid value for SyntheticGestureParams::GestureType.
182  WriteParam(&msg, -3);
183
184  SyntheticGesturePacket packet_out;
185  PickleIterator iter(msg);
186  ASSERT_FALSE(
187      IPC::ParamTraits<SyntheticGesturePacket>::Read(&msg, &iter, &packet_out));
188}
189
190TEST_F(InputParamTraitsTest, SyntheticSmoothScrollGestureParams) {
191  scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
192      new SyntheticSmoothScrollGestureParams);
193  gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
194  gesture_params->anchor.SetPoint(234, 345);
195  gesture_params->distances.push_back(gfx::Vector2d(123, -789));
196  gesture_params->distances.push_back(gfx::Vector2d(-78, 43));
197  gesture_params->prevent_fling = false;
198  gesture_params->speed_in_pixels_s = 456;
199  ASSERT_EQ(SyntheticGestureParams::SMOOTH_SCROLL_GESTURE,
200            gesture_params->GetGestureType());
201  SyntheticGesturePacket packet_in;
202  packet_in.set_gesture_params(gesture_params.PassAs<SyntheticGestureParams>());
203
204  Verify(packet_in);
205}
206
207TEST_F(InputParamTraitsTest, SyntheticPinchGestureParams) {
208  scoped_ptr<SyntheticPinchGestureParams> gesture_params(
209      new SyntheticPinchGestureParams);
210  gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
211  gesture_params->scale_factor = 2.3f;
212  gesture_params->anchor.SetPoint(234, 345);
213  gesture_params->relative_pointer_speed_in_pixels_s = 456;
214  ASSERT_EQ(SyntheticGestureParams::PINCH_GESTURE,
215            gesture_params->GetGestureType());
216  SyntheticGesturePacket packet_in;
217  packet_in.set_gesture_params(gesture_params.PassAs<SyntheticGestureParams>());
218
219  Verify(packet_in);
220}
221
222TEST_F(InputParamTraitsTest, SyntheticTapGestureParams) {
223  scoped_ptr<SyntheticTapGestureParams> gesture_params(
224      new SyntheticTapGestureParams);
225  gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
226  gesture_params->position.SetPoint(798, 233);
227  gesture_params->duration_ms = 13;
228  ASSERT_EQ(SyntheticGestureParams::TAP_GESTURE,
229            gesture_params->GetGestureType());
230  SyntheticGesturePacket packet_in;
231  packet_in.set_gesture_params(gesture_params.PassAs<SyntheticGestureParams>());
232
233  Verify(packet_in);
234}
235
236}  // namespace
237}  // namespace content
238