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 virtual SyntheticGestureParams::GestureSourceType PointerSourceType() | |
48 const = 0; | |
49 | |
50 WebInputEvent::Type type() const { return type_; } | |
51 | |
52 protected: | |
53 WebInputEvent::Type type_; | |
54 }; | |
55 | |
56 class MockSyntheticPointerTouchActionTarget | |
57 : public MockSyntheticPointerActionTarget { | |
58 public: | |
59 MockSyntheticPointerTouchActionTarget() {} | |
60 ~MockSyntheticPointerTouchActionTarget() override {} | |
61 | |
62 void DispatchInputEventToPlatform(const WebInputEvent& event) override { | |
63 ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type)); | |
64 const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event); | |
65 type_ = touch_event.type; | |
66 for (size_t i = 0; i < touch_event.touchesLength; ++i) { | |
67 indexes_[i] = touch_event.touches[i].id; | |
68 positions_[i] = gfx::PointF(touch_event.touches[i].position); | |
69 states_[i] = touch_event.touches[i].state; | |
70 } | |
71 touch_length_ = touch_event.touchesLength; | |
72 } | |
73 | |
74 SyntheticGestureParams::GestureSourceType | |
75 GetDefaultSyntheticGestureSourceType() const override { | |
76 return SyntheticGestureParams::TOUCH_INPUT; | |
77 } | |
78 | |
79 SyntheticGestureParams::GestureSourceType PointerSourceType() const override { | |
lanwei
2016/06/16 07:54:24
I know it is confusing that these two functions ar
tdresser
2016/06/23 14:22:50
Could we just only use the default?
| |
80 return SyntheticGestureParams::TOUCH_INPUT; | |
81 } | |
82 | |
83 gfx::PointF positions(int index) const { return positions_[index]; } | |
84 int indexes(int index) const { return indexes_[index]; } | |
85 WebTouchPoint::State states(int index) { return states_[index]; } | |
86 unsigned touch_length() const { return touch_length_; } | |
87 | |
88 private: | |
89 gfx::PointF positions_[WebTouchEvent::touchesLengthCap]; | |
90 unsigned touch_length_; | |
91 int indexes_[WebTouchEvent::touchesLengthCap]; | |
92 WebTouchPoint::State states_[WebTouchEvent::touchesLengthCap]; | |
93 }; | |
94 | |
95 class SyntheticPointerActionTest : public testing::Test { | |
96 public: | |
97 SyntheticPointerActionTest() {} | |
98 ~SyntheticPointerActionTest() override {} | |
99 | |
100 protected: | |
101 template <typename MockGestureTarget> | |
102 void CreateSyntheticPointerAndTarget() { | |
103 target_.reset(new MockGestureTarget()); | |
104 synthetic_pointer_ = SyntheticPointer::Create(target_->PointerSourceType()); | |
105 } | |
106 | |
107 void SetUp() override { | |
108 num_success_ = 0; | |
109 num_failure_ = 0; | |
110 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
111 std::fill(index_map_.begin(), index_map_.end(), -1); | |
112 } | |
113 | |
114 void TearDown() override { | |
115 target_.reset(); | |
116 pointer_action_.reset(); | |
117 synthetic_pointer_.reset(); | |
118 action_param_list_.reset(); | |
119 } | |
120 | |
121 void ForwardSyntheticPointerAction() { | |
122 pointer_action_.reset(new SyntheticPointerAction( | |
123 std::move(action_param_list_), synthetic_pointer_.get(), &index_map_)); | |
124 | |
125 SyntheticGesture::Result result = pointer_action_->ForwardInputEvents( | |
126 base::TimeTicks::Now(), target_.get()); | |
127 | |
128 if (result == SyntheticGesture::GESTURE_FINISHED) | |
129 num_success_++; | |
130 else | |
131 num_failure_++; | |
132 } | |
133 | |
134 int num_success_; | |
135 int num_failure_; | |
136 std::unique_ptr<MockSyntheticPointerActionTarget> target_; | |
137 std::unique_ptr<SyntheticGesture> pointer_action_; | |
138 std::unique_ptr<SyntheticPointer> synthetic_pointer_; | |
139 std::unique_ptr<std::vector<SyntheticPointerActionParams>> action_param_list_; | |
140 SyntheticPointerAction::IndexMap index_map_; | |
141 }; | |
142 | |
143 TEST_F(SyntheticPointerActionTest, PointerTouchAction) { | |
144 CreateSyntheticPointerAndTarget<MockSyntheticPointerTouchActionTarget>(); | |
145 | |
146 // Send a touch press for one finger. | |
147 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
148 SyntheticPointerActionParams::PointerActionType::PRESS); | |
149 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
150 params0.set_index(0); | |
151 params0.set_position(gfx::PointF(54, 89)); | |
152 action_param_list_->push_back(params0); | |
153 ForwardSyntheticPointerAction(); | |
154 | |
155 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
156 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
157 EXPECT_EQ(1, num_success_); | |
158 EXPECT_EQ(0, num_failure_); | |
159 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
160 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
161 EXPECT_EQ(index_map_[0], 0); | |
162 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
163 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
164 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
165 | |
166 // Send a touch move for the first finger and a touch press for the second | |
167 // finger. | |
168 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
169 params0.set_pointer_action_type( | |
170 SyntheticPointerActionParams::PointerActionType::MOVE); | |
171 params0.set_position(gfx::PointF(133, 156)); | |
172 SyntheticPointerActionParams params1 = SyntheticPointerActionParams( | |
173 SyntheticPointerActionParams::PointerActionType::PRESS); | |
174 params1.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
175 params1.set_index(1); | |
176 params1.set_position(gfx::PointF(79, 132)); | |
177 action_param_list_->push_back(params0); | |
178 action_param_list_->push_back(params1); | |
179 ForwardSyntheticPointerAction(); | |
180 | |
181 pointer_touch_target = | |
182 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
183 EXPECT_EQ(2, num_success_); | |
184 EXPECT_EQ(0, num_failure_); | |
185 // The type of the SyntheticWebTouchEvent is the action of the last finger. | |
186 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
187 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
188 EXPECT_EQ(index_map_[0], 0); | |
189 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(133, 156)); | |
190 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StateMoved); | |
191 EXPECT_EQ(pointer_touch_target->indexes(1), 1); | |
192 EXPECT_EQ(index_map_[1], 1); | |
193 EXPECT_EQ(pointer_touch_target->positions(1), gfx::PointF(79, 132)); | |
194 EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StatePressed); | |
195 ASSERT_EQ(pointer_touch_target->touch_length(), 2U); | |
196 | |
197 // Send a touch move for the second finger. | |
198 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
199 params1.set_pointer_action_type( | |
200 SyntheticPointerActionParams::PointerActionType::MOVE); | |
201 params1.set_position(gfx::PointF(87, 253)); | |
202 action_param_list_->push_back(params1); | |
203 ForwardSyntheticPointerAction(); | |
204 | |
205 pointer_touch_target = | |
206 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
207 EXPECT_EQ(3, num_success_); | |
208 EXPECT_EQ(0, num_failure_); | |
209 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchMove); | |
210 EXPECT_EQ(pointer_touch_target->indexes(1), 1); | |
211 EXPECT_EQ(index_map_[1], 1); | |
212 EXPECT_EQ(pointer_touch_target->positions(1), gfx::PointF(87, 253)); | |
213 EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateMoved); | |
214 ASSERT_EQ(pointer_touch_target->touch_length(), 2U); | |
215 | |
216 // Send touch releases for both fingers. | |
217 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
218 params0.set_pointer_action_type( | |
219 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
220 params1.set_pointer_action_type( | |
221 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
222 action_param_list_->push_back(params0); | |
223 action_param_list_->push_back(params1); | |
224 ForwardSyntheticPointerAction(); | |
225 | |
226 EXPECT_EQ(4, num_success_); | |
227 EXPECT_EQ(0, num_failure_); | |
228 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchEnd); | |
229 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
230 EXPECT_EQ(index_map_[0], -1); | |
231 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StateReleased); | |
232 EXPECT_EQ(pointer_touch_target->indexes(1), 1); | |
233 EXPECT_EQ(index_map_[1], -1); | |
234 EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateReleased); | |
235 ASSERT_EQ(pointer_touch_target->touch_length(), 2U); | |
236 } | |
237 | |
238 TEST_F(SyntheticPointerActionTest, PointerTouchActionIndexInvalid) { | |
239 CreateSyntheticPointerAndTarget<MockSyntheticPointerTouchActionTarget>(); | |
240 | |
241 // Users sent a wrong index for the touch action. | |
242 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
243 SyntheticPointerActionParams::PointerActionType::PRESS); | |
244 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
245 params0.set_index(-1); | |
246 params0.set_position(gfx::PointF(54, 89)); | |
247 action_param_list_->push_back(params0); | |
248 ForwardSyntheticPointerAction(); | |
249 | |
250 EXPECT_EQ(0, num_success_); | |
251 EXPECT_EQ(1, num_failure_); | |
252 | |
253 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
254 params0.set_index(0); | |
255 action_param_list_->push_back(params0); | |
256 ForwardSyntheticPointerAction(); | |
257 | |
258 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
259 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
260 EXPECT_EQ(1, num_success_); | |
261 EXPECT_EQ(1, num_failure_); | |
262 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
263 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
264 EXPECT_EQ(index_map_[0], 0); | |
265 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
266 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
267 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
268 } | |
269 | |
270 TEST_F(SyntheticPointerActionTest, PointerTouchActionSourceTypeInvalid) { | |
271 CreateSyntheticPointerAndTarget<MockSyntheticPointerTouchActionTarget>(); | |
272 | |
273 // Users' gesture source type does not match with the touch action. | |
274 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
275 SyntheticPointerActionParams::PointerActionType::PRESS); | |
276 params0.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT; | |
277 params0.set_index(0); | |
278 params0.set_position(gfx::PointF(54, 89)); | |
279 action_param_list_->push_back(params0); | |
280 ForwardSyntheticPointerAction(); | |
281 | |
282 EXPECT_EQ(0, num_success_); | |
283 EXPECT_EQ(1, num_failure_); | |
284 | |
285 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
286 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
287 action_param_list_->push_back(params0); | |
288 ForwardSyntheticPointerAction(); | |
289 | |
290 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
291 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
292 EXPECT_EQ(1, num_success_); | |
293 EXPECT_EQ(1, num_failure_); | |
294 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
295 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
296 EXPECT_EQ(index_map_[0], 0); | |
297 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
298 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
299 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
300 } | |
301 | |
302 TEST_F(SyntheticPointerActionTest, PointerTouchActionTypeInvalid) { | |
303 CreateSyntheticPointerAndTarget<MockSyntheticPointerTouchActionTarget>(); | |
304 | |
305 // Cannot send a touch move or touch release without sending a touch press | |
306 // first. | |
307 SyntheticPointerActionParams params0 = SyntheticPointerActionParams( | |
308 SyntheticPointerActionParams::PointerActionType::MOVE); | |
309 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
310 params0.set_index(0); | |
311 params0.set_position(gfx::PointF(54, 89)); | |
312 action_param_list_->push_back(params0); | |
313 ForwardSyntheticPointerAction(); | |
314 | |
315 EXPECT_EQ(0, num_success_); | |
316 EXPECT_EQ(1, num_failure_); | |
317 | |
318 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
319 params0.set_pointer_action_type( | |
320 SyntheticPointerActionParams::PointerActionType::RELEASE); | |
321 action_param_list_->push_back(params0); | |
322 ForwardSyntheticPointerAction(); | |
323 | |
324 EXPECT_EQ(0, num_success_); | |
325 EXPECT_EQ(2, num_failure_); | |
326 | |
327 // Send a touch press for one finger. | |
328 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
329 params0.set_pointer_action_type( | |
330 SyntheticPointerActionParams::PointerActionType::PRESS); | |
331 action_param_list_->push_back(params0); | |
332 ForwardSyntheticPointerAction(); | |
333 | |
334 MockSyntheticPointerTouchActionTarget* pointer_touch_target = | |
335 static_cast<MockSyntheticPointerTouchActionTarget*>(target_.get()); | |
336 EXPECT_EQ(1, num_success_); | |
337 EXPECT_EQ(2, num_failure_); | |
338 EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart); | |
339 EXPECT_EQ(pointer_touch_target->indexes(0), 0); | |
340 EXPECT_EQ(index_map_[0], 0); | |
341 EXPECT_EQ(pointer_touch_target->positions(0), gfx::PointF(54, 89)); | |
342 EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed); | |
343 ASSERT_EQ(pointer_touch_target->touch_length(), 1U); | |
344 | |
345 // Cannot send a touch press again without releasing the finger. | |
346 action_param_list_.reset(new std::vector<SyntheticPointerActionParams>()); | |
347 params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; | |
348 params0.set_index(0); | |
349 params0.set_pointer_action_type( | |
350 SyntheticPointerActionParams::PointerActionType::PRESS); | |
351 action_param_list_->push_back(params0); | |
352 ForwardSyntheticPointerAction(); | |
353 | |
354 EXPECT_EQ(1, num_success_); | |
355 EXPECT_EQ(3, num_failure_); | |
356 } | |
357 | |
358 } // namespace | |
359 | |
360 } // namespace content | |
OLD | NEW |