OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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/time/time.h" | |
7 #include "content/browser/renderer_host/input/synthetic_gesture.h" | |
8 #include "content/browser/renderer_host/input/synthetic_gesture_target.h" | |
9 #include "content/browser/renderer_host/input/synthetic_pointer_action.h" | |
10 #include "content/browser/renderer_host/input/synthetic_touch_pointer.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
13 #include "ui/gfx/geometry/point.h" | |
14 #include "ui/gfx/geometry/point_f.h" | |
15 | |
16 using blink::WebInputEvent; | |
17 using blink::WebTouchEvent; | |
18 using blink::WebTouchPoint; | |
19 | |
20 namespace content { | |
21 | |
22 namespace { | |
23 | |
24 class MockSyntheticPointerActionTarget : public SyntheticGestureTarget { | |
25 public: | |
26 MockSyntheticPointerActionTarget() {} | |
27 ~MockSyntheticPointerActionTarget() override {} | |
28 | |
29 // SyntheticGestureTarget: | |
30 void SetNeedsFlush() override { NOTIMPLEMENTED(); } | |
31 | |
32 base::TimeDelta PointerAssumedStoppedTime() const override { | |
33 NOTIMPLEMENTED(); | |
34 return base::TimeDelta(); | |
35 } | |
36 | |
37 float GetTouchSlopInDips() const override { | |
38 NOTIMPLEMENTED(); | |
39 return 0.0f; | |
40 } | |
41 | |
42 float GetMinScalingSpanInDips() const override { | |
43 NOTIMPLEMENTED(); | |
44 return 0.0f; | |
45 } | |
46 | |
47 WebInputEvent::Type type() const { return type_; } | |
48 | |
49 protected: | |
50 WebInputEvent::Type type_; | |
51 }; | |
52 | |
53 class MockSyntheticPointerTouchActionTarget | |
54 : public MockSyntheticPointerActionTarget { | |
55 public: | |
56 MockSyntheticPointerTouchActionTarget() {} | |
57 ~MockSyntheticPointerTouchActionTarget() override {} | |
58 | |
59 void DispatchInputEventToPlatform(const WebInputEvent& event) override { | |
60 ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type)); | |
61 const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event); | |
62 type_ = touch_event.type; | |
63 for (size_t i = 0; i < touch_event.touchesLength; ++i) { | |
64 indexes_[i] = touch_event.touches[i].id; | |
65 positions_[i] = gfx::PointF(touch_event.touches[i].position); | |
66 states_[i] = touch_event.touches[i].state; | |
67 } | |
68 touch_length_ = touch_event.touchesLength; | |
69 } | |
70 | |
71 SyntheticGestureParams::GestureSourceType | |
72 GetDefaultSyntheticGestureSourceType() const override { | |
73 return SyntheticGestureParams::TOUCH_INPUT; | |
74 } | |
75 | |
76 gfx::PointF positions(int index) const { return positions_[index]; } | |
77 int indexes(int index) const { return indexes_[index]; } | |
78 WebTouchPoint::State states(int index) { return states_[index]; } | |
79 unsigned touch_length() const { return touch_length_; } | |
80 | |
81 private: | |
82 gfx::PointF positions_[WebTouchEvent::touchesLengthCap]; | |
83 unsigned touch_length_; | |
84 int indexes_[WebTouchEvent::touchesLengthCap]; | |
85 WebTouchPoint::State states_[WebTouchEvent::touchesLengthCap]; | |
86 }; | |
87 | |
88 class SyntheticPointerActionTest : public testing::Test { | |
89 public: | |
90 SyntheticPointerActionTest() {} | |
91 ~SyntheticPointerActionTest() override {} | |
92 | |
93 protected: | |
94 void SetUp() override { | |
tdresser
2016/07/08 12:22:14
Prefer code in the constructor to code in SetUp.
lanwei
2016/07/14 17:05:53
Done.
| |
95 target_.reset(new MockSyntheticPointerTouchActionTarget()); | |
96 synthetic_pointer_ = | |
97 SyntheticPointer::Create(SyntheticGestureParams::TOUCH_INPUT); | |
98 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
99 std::fill(index_map_.begin(), index_map_.end(), -1); | |
100 num_success_ = 0; | |
101 num_failure_ = 0; | |
102 } | |
103 | |
104 void TearDown() override { | |
105 target_.reset(); | |
106 synthetic_pointer_.reset(); | |
107 action_param_list_.reset(); | |
108 pointer_action_.reset(); | |
tdresser
2016/07/08 12:22:14
These resets shouldn't be necessary.
lanwei
2016/07/14 17:05:53
Done.
| |
109 } | |
110 | |
111 void ForwardSyntheticPointerAction() { | |
112 pointer_action_.reset(new SyntheticPointerAction( | |
113 std::move(action_param_list_), synthetic_pointer_.get(), &index_map_)); | |
114 | |
115 SyntheticGesture::Result result = pointer_action_->ForwardInputEvents( | |
116 base::TimeTicks::Now(), target_.get()); | |
117 | |
118 if (result == SyntheticGesture::GESTURE_FINISHED) | |
119 num_success_++; | |
120 else | |
121 num_failure_++; | |
122 } | |
123 | |
124 int num_success_; | |
125 int num_failure_; | |
126 std::unique_ptr<MockSyntheticPointerActionTarget> target_; | |
127 std::unique_ptr<SyntheticGesture> pointer_action_; | |
128 std::unique_ptr<SyntheticPointer> synthetic_pointer_; | |
129 std::unique_ptr<std::vector<SyntheticPointerActionParams>> action_param_list_; | |
130 SyntheticPointerAction::IndexMap index_map_; | |
131 }; | |
132 | |
133 TEST_F(SyntheticPointerActionTest, PointerTouchAction) { | |
134 // Send a touch press for one finger. | |
135 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
136 SyntheticPointerActionParams::PointerActionType::PRESS); | |
137 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
138 params0.set_index(0); | |
139 params0.set_position(gfx::PointF(54, 89)); | |
140 action_param_list_->push_back(params0); | |
141 ForwardSyntheticPointerAction(); | |
142 | |
143 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
144 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
145 EXPECT_EQ(1, num_success_); | |
146 EXPECT_EQ(0, num_failure_); | |
147 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
148 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
149 EXPECT_EQ(index_map_[0], 0); | |
150 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
151 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
152 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
153 | |
154 // Send a touch move for the first finger and a touch press for the second | |
155 // finger. | |
156 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
157 params0.set_pointer_action_type( | |
158 SyntheticPointerActionParams::PointerActionType::MOVE); | |
159 params0.set_position(gfx::PointF(133, 156)); | |
160 SyntheticPointerActionParams params1 = SyntheticPointerActionParams( | |
161 SyntheticPointerActionParams::PointerActionType::PRESS); | |
162 params1.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
163 params1.set_index(1); | |
164 params1.set_position(gfx::PointF(79, 132)); | |
165 action_param_list_->push_back(params0); | |
166 action_param_list_->push_back(params1); | |
167 ForwardSyntheticPointerAction(); | |
168 | |
169 pointer_touch_target = | |
170 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
171 EXPECT_EQ(2, num_success_); | |
172 EXPECT_EQ(0, num_failure_); | |
173 // The type of the SyntheticWebTouchEvent is the action of the last finger. | |
174 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
175 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
176 EXPECT_EQ(index_map_[0], 0); | |
177 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(133, 156)); | |
178 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StateMoved); | |
179 EXPECT_EQ(pointer_touch_target->indexes(1), 1); | |
180 EXPECT_EQ(index_map_[1], 1); | |
181 EXPECT_EQ(pointer_touch_target->positions(1), gfx::PointF(79, 132)); | |
182 EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StatePressed); | |
183 ASSERT_EQ(pointer_touch_target->touch_length(), 2U); | |
184 | |
185 // Send a touch move for the second finger. | |
186 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
187 params1.set_pointer_action_type( | |
188 SyntheticPointerActionParams::PointerActionType::MOVE); | |
189 params1.set_position(gfx::PointF(87, 253)); | |
190 action_param_list_->push_back(params1); | |
191 ForwardSyntheticPointerAction(); | |
192 | |
193 pointer_touch_target = | |
194 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
195 EXPECT_EQ(3, num_success_); | |
196 EXPECT_EQ(0, num_failure_); | |
197 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchMove); | |
198 EXPECT_EQ(pointer_touch_target->indexes(1), 1); | |
199 EXPECT_EQ(index_map_[1], 1); | |
200 EXPECT_EQ(pointer_touch_target->positions(1), gfx::PointF(87, 253)); | |
201 EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateMoved); | |
202 ASSERT_EQ(pointer_touch_target->touch_length(), 2U); | |
203 | |
204 // Send touch releases for both fingers. | |
205 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
206 params0.set_pointer_action_type( | |
207 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
208 params1.set_pointer_action_type( | |
209 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
210 action_param_list_->push_back(params0); | |
211 action_param_list_->push_back(params1); | |
212 ForwardSyntheticPointerAction(); | |
213 | |
214 EXPECT_EQ(4, num_success_); | |
215 EXPECT_EQ(0, num_failure_); | |
216 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchEnd); | |
217 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
218 EXPECT_EQ(index_map_[0], -1); | |
219 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StateReleased); | |
220 EXPECT_EQ(pointer_touch_target->indexes(1), 1); | |
221 EXPECT_EQ(index_map_[1], -1); | |
222 EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateReleased); | |
223 ASSERT_EQ(pointer_touch_target->touch_length(), 2U); | |
224 } | |
225 | |
226 TEST_F(SyntheticPointerActionTest, PointerTouchActionIndexInvalid) { | |
227 // Users sent a wrong index for the touch action. | |
228 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
229 SyntheticPointerActionParams::PointerActionType::PRESS); | |
230 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
231 params0.set_index(-1); | |
232 params0.set_position(gfx::PointF(54, 89)); | |
233 action_param_list_->push_back(params0); | |
234 ForwardSyntheticPointerAction(); | |
235 | |
236 EXPECT_EQ(0, num_success_); | |
237 EXPECT_EQ(1, num_failure_); | |
238 | |
239 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
240 params0.set_index(0); | |
241 action_param_list_->push_back(params0); | |
242 ForwardSyntheticPointerAction(); | |
243 | |
244 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
245 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
246 EXPECT_EQ(1, num_success_); | |
247 EXPECT_EQ(1, num_failure_); | |
248 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
249 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
250 EXPECT_EQ(index_map_[0], 0); | |
251 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
252 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
253 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
254 } | |
255 | |
256 TEST_F(SyntheticPointerActionTest, PointerTouchActionSourceTypeInvalid) { | |
257 // Users' gesture source type does not match with the touch action. | |
258 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
259 SyntheticPointerActionParams::PointerActionType::PRESS); | |
260 params0.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT; | |
261 params0.set_index(0); | |
262 params0.set_position(gfx::PointF(54, 89)); | |
263 action_param_list_->push_back(params0); | |
264 ForwardSyntheticPointerAction(); | |
265 | |
266 EXPECT_EQ(0, num_success_); | |
267 EXPECT_EQ(1, num_failure_); | |
268 | |
269 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
270 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
271 action_param_list_->push_back(params0); | |
272 ForwardSyntheticPointerAction(); | |
273 | |
274 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
275 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
276 EXPECT_EQ(1, num_success_); | |
277 EXPECT_EQ(1, num_failure_); | |
278 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
279 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
280 EXPECT_EQ(index_map_[0], 0); | |
281 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
282 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
283 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
284 } | |
285 | |
286 TEST_F(SyntheticPointerActionTest, PointerTouchActionTypeInvalid) { | |
287 // Cannot send a touch move or touch release without sending a touch press | |
288 // first. | |
289 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
290 SyntheticPointerActionParams::PointerActionType::MOVE); | |
291 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
292 params0.set_index(0); | |
293 params0.set_position(gfx::PointF(54, 89)); | |
294 action_param_list_->push_back(params0); | |
295 ForwardSyntheticPointerAction(); | |
296 | |
297 EXPECT_EQ(0, num_success_); | |
298 EXPECT_EQ(1, num_failure_); | |
299 | |
300 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
301 params0.set_pointer_action_type( | |
302 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
303 action_param_list_->push_back(params0); | |
304 ForwardSyntheticPointerAction(); | |
305 | |
306 EXPECT_EQ(0, num_success_); | |
307 EXPECT_EQ(2, num_failure_); | |
308 | |
309 // Send a touch press for one finger. | |
310 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
311 params0.set_pointer_action_type( | |
312 SyntheticPointerActionParams::PointerActionType::PRESS); | |
313 action_param_list_->push_back(params0); | |
314 ForwardSyntheticPointerAction(); | |
315 | |
316 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
317 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
318 EXPECT_EQ(1, num_success_); | |
319 EXPECT_EQ(2, num_failure_); | |
320 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
321 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
322 EXPECT_EQ(index_map_[0], 0); | |
323 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
324 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
325 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
326 | |
327 // Cannot send a touch press again without releasing the finger. | |
328 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
329 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
330 params0.set_index(0); | |
331 params0.set_pointer_action_type( | |
332 SyntheticPointerActionParams::PointerActionType::PRESS); | |
333 action_param_list_->push_back(params0); | |
334 ForwardSyntheticPointerAction(); | |
335 | |
336 EXPECT_EQ(1, num_success_); | |
337 EXPECT_EQ(3, num_failure_); | |
338 } | |
339 | |
340 } // namespace | |
341 | |
342 } // namespace content | |
OLD | NEW |