1 // Copyright 2015 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 "third_party/blink/renderer/core/events/pointer_event_factory.h"
6
7 #include <gtest/gtest.h>
8
9 #include <limits>
10
11 #include "base/time/time.h"
12 #include "third_party/blink/public/common/input/web_pointer_properties.h"
13 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
14 #include "third_party/blink/renderer/core/page/page.h"
15
16 namespace blink {
17
18 namespace {
19
PointerTypeNameForWebPointPointerType(WebPointerProperties::PointerType type)20 const char* PointerTypeNameForWebPointPointerType(
21 WebPointerProperties::PointerType type) {
22 switch (type) {
23 case WebPointerProperties::PointerType::kUnknown:
24 return "";
25 case WebPointerProperties::PointerType::kTouch:
26 return "touch";
27 case WebPointerProperties::PointerType::kPen:
28 case WebPointerProperties::PointerType::kEraser:
29 return "pen";
30 case WebPointerProperties::PointerType::kMouse:
31 return "mouse";
32 default:
33 NOTREACHED();
34 return "";
35 }
36 }
37 }
38
39 class PointerEventFactoryTest : public testing::Test {
40 protected:
41 void SetUp() override;
42 PointerEvent* CreateAndCheckPointerCancel(WebPointerProperties::PointerType,
43 int raw_id,
44 int unique_id,
45 bool is_primary);
CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType pointer_type,int raw_id,int unique_id,bool is_primary,bool hovering,WebInputEvent::Modifiers modifiers=WebInputEvent::kNoModifiers,WebInputEvent::Type type=WebInputEvent::Type::kPointerDown,WebPointerProperties::Button button=WebPointerProperties::Button::kNoButton,wtf_size_t coalesced_event_count=0,wtf_size_t predicted_event_count=0)46 PointerEvent* CreateAndCheckWebPointerEvent(
47 WebPointerProperties::PointerType pointer_type,
48 int raw_id,
49 int unique_id,
50 bool is_primary,
51 bool hovering,
52 WebInputEvent::Modifiers modifiers = WebInputEvent::kNoModifiers,
53 WebInputEvent::Type type = WebInputEvent::Type::kPointerDown,
54 WebPointerProperties::Button button =
55 WebPointerProperties::Button::kNoButton,
56 wtf_size_t coalesced_event_count = 0,
57 wtf_size_t predicted_event_count = 0) {
58 WebPointerEvent web_pointer_event;
59 web_pointer_event.pointer_type = pointer_type;
60 web_pointer_event.id = raw_id;
61 web_pointer_event.SetType(type);
62 web_pointer_event.SetTimeStamp(WebInputEvent::GetStaticTimeStampForTests());
63 web_pointer_event.SetModifiers(modifiers);
64 web_pointer_event.force = 1.0;
65 web_pointer_event.hovering = hovering;
66 web_pointer_event.button = button;
67 web_pointer_event.SetPositionInScreen(100, 100);
68 Vector<WebPointerEvent> coalesced_events;
69 for (wtf_size_t i = 0; i < coalesced_event_count; i++) {
70 coalesced_events.push_back(web_pointer_event);
71 }
72 Vector<WebPointerEvent> predicted_events;
73 for (wtf_size_t i = 0; i < predicted_event_count; i++) {
74 predicted_events.push_back(web_pointer_event);
75 }
76 PointerEvent* pointer_event = pointer_event_factory_.Create(
77 web_pointer_event, coalesced_events, predicted_events, nullptr);
78 EXPECT_EQ(unique_id, pointer_event->pointerId());
79 EXPECT_EQ(is_primary, pointer_event->isPrimary());
80 EXPECT_EQ(WebInputEvent::GetStaticTimeStampForTests(),
81 pointer_event->PlatformTimeStamp());
82 const char* expected_pointer_type =
83 PointerTypeNameForWebPointPointerType(pointer_type);
84 EXPECT_EQ(expected_pointer_type, pointer_event->pointerType());
85
86 EXPECT_EQ(!!(modifiers & WebInputEvent::kControlKey),
87 pointer_event->ctrlKey());
88 EXPECT_EQ(!!(modifiers & WebInputEvent::kShiftKey),
89 pointer_event->shiftKey());
90 EXPECT_EQ(!!(modifiers & WebInputEvent::kAltKey), pointer_event->altKey());
91 EXPECT_EQ(!!(modifiers & WebInputEvent::kMetaKey),
92 pointer_event->metaKey());
93
94 if (type == WebInputEvent::Type::kPointerMove) {
95 EXPECT_EQ(coalesced_event_count,
96 pointer_event->getCoalescedEvents().size());
97 EXPECT_EQ(predicted_event_count,
98 pointer_event->getPredictedEvents().size());
99 for (wtf_size_t i = 0; i < coalesced_event_count; i++) {
100 EXPECT_EQ(unique_id,
101 pointer_event->getCoalescedEvents()[i]->pointerId());
102 EXPECT_EQ(is_primary,
103 pointer_event->getCoalescedEvents()[i]->isPrimary());
104 EXPECT_EQ(expected_pointer_type, pointer_event->pointerType());
105 EXPECT_EQ(WebInputEvent::GetStaticTimeStampForTests(),
106 pointer_event->PlatformTimeStamp());
107 }
108 for (wtf_size_t i = 0; i < predicted_event_count; i++) {
109 EXPECT_EQ(unique_id,
110 pointer_event->getPredictedEvents()[i]->pointerId());
111 EXPECT_EQ(is_primary,
112 pointer_event->getPredictedEvents()[i]->isPrimary());
113 EXPECT_EQ(expected_pointer_type, pointer_event->pointerType());
114 EXPECT_EQ(WebInputEvent::GetStaticTimeStampForTests(),
115 pointer_event->PlatformTimeStamp());
116 }
117 } else {
118 EXPECT_EQ(0u, pointer_event->getCoalescedEvents().size());
119 EXPECT_EQ(0u, pointer_event->getPredictedEvents().size());
120 }
121 EXPECT_EQ(
122 pointer_event_factory_.GetLastPointerPosition(
123 pointer_event->pointerId(),
124 WebPointerProperties(1, WebPointerProperties::PointerType::kUnknown,
125 WebPointerProperties::Button::kNoButton,
126 gfx::PointF(50, 50), gfx::PointF(20, 20)),
127 type),
128 FloatPoint(100, 100));
129 return pointer_event;
130 }
131 void CreateAndCheckPointerTransitionEvent(PointerEvent*, const AtomicString&);
132 void CheckNonHoveringPointers(const HashSet<int>& expected);
133
134 PointerEventFactory pointer_event_factory_;
135 int expected_mouse_id_;
136 int mapped_id_start_;
137
138 };
139
SetUp()140 void PointerEventFactoryTest::SetUp() {
141 expected_mouse_id_ = 1;
142 mapped_id_start_ = 2;
143 }
144
CreateAndCheckPointerCancel(WebPointerProperties::PointerType pointer_type,int raw_id,int unique_id,bool is_primary)145 PointerEvent* PointerEventFactoryTest::CreateAndCheckPointerCancel(
146 WebPointerProperties::PointerType pointer_type,
147 int raw_id,
148 int unique_id,
149 bool is_primary) {
150 PointerEvent* pointer_event = pointer_event_factory_.CreatePointerCancelEvent(
151 unique_id, WebInputEvent::GetStaticTimeStampForTests());
152 EXPECT_EQ("pointercancel", pointer_event->type());
153 EXPECT_EQ(unique_id, pointer_event->pointerId());
154 EXPECT_EQ(is_primary, pointer_event->isPrimary());
155 EXPECT_EQ(PointerTypeNameForWebPointPointerType(pointer_type),
156 pointer_event->pointerType());
157 EXPECT_EQ(WebInputEvent::GetStaticTimeStampForTests(),
158 pointer_event->PlatformTimeStamp());
159
160 return pointer_event;
161 }
162
CreateAndCheckPointerTransitionEvent(PointerEvent * pointer_event,const AtomicString & type)163 void PointerEventFactoryTest::CreateAndCheckPointerTransitionEvent(
164 PointerEvent* pointer_event,
165 const AtomicString& type) {
166 PointerEvent* clone_pointer_event =
167 pointer_event_factory_.CreatePointerBoundaryEvent(pointer_event, type,
168 nullptr);
169 EXPECT_EQ(clone_pointer_event->pointerType(), pointer_event->pointerType());
170 EXPECT_EQ(clone_pointer_event->pointerId(), pointer_event->pointerId());
171 EXPECT_EQ(clone_pointer_event->isPrimary(), pointer_event->isPrimary());
172 EXPECT_EQ(clone_pointer_event->type(), type);
173
174 EXPECT_EQ(clone_pointer_event->ctrlKey(), pointer_event->ctrlKey());
175 EXPECT_EQ(clone_pointer_event->shiftKey(), pointer_event->shiftKey());
176 EXPECT_EQ(clone_pointer_event->altKey(), pointer_event->altKey());
177 EXPECT_EQ(clone_pointer_event->metaKey(), pointer_event->metaKey());
178 }
179
CheckNonHoveringPointers(const HashSet<int> & expected_pointers)180 void PointerEventFactoryTest::CheckNonHoveringPointers(
181 const HashSet<int>& expected_pointers) {
182 Vector<int> pointers =
183 pointer_event_factory_.GetPointerIdsOfNonHoveringPointers();
184 EXPECT_EQ(pointers.size(), expected_pointers.size());
185 for (int p : pointers) {
186 EXPECT_TRUE(expected_pointers.find(p) != expected_pointers.end());
187 }
188 }
189
TEST_F(PointerEventFactoryTest,MousePointer)190 TEST_F(PointerEventFactoryTest, MousePointer) {
191 EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
192 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
193
194 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
195 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
196 true /* isprimary */, true /* hovering */);
197 PointerEvent* pointer_event2 = CreateAndCheckWebPointerEvent(
198 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
199 true /* isprimary */, true /* hovering */,
200 WebInputEvent::kLeftButtonDown);
201
202 CreateAndCheckPointerTransitionEvent(pointer_event1,
203 event_type_names::kPointerout);
204
205 EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
206 EXPECT_TRUE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
207
208 pointer_event_factory_.Remove(pointer_event1->pointerId());
209
210 EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
211 EXPECT_TRUE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
212
213 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, 0,
214 expected_mouse_id_, true /* isprimary */,
215 true /* hovering */);
216
217 EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
218 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
219
220 pointer_event_factory_.Remove(pointer_event1->pointerId());
221 pointer_event_factory_.Remove(pointer_event2->pointerId());
222
223 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, 1,
224 expected_mouse_id_, true /* isprimary */,
225 true /* hovering */);
226 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, 20,
227 expected_mouse_id_, true /* isprimary */,
228 true /* hovering */);
229
230 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, 0,
231 expected_mouse_id_, true /* isprimary */,
232 true /* hovering */,
233 WebInputEvent::kLeftButtonDown);
234
235 EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
236 EXPECT_TRUE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
237
238 CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kMouse, 0,
239 expected_mouse_id_, true);
240
241 EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
242 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
243 }
244
TEST_F(PointerEventFactoryTest,TouchPointerPrimaryRemovedWhileAnotherIsThere)245 TEST_F(PointerEventFactoryTest, TouchPointerPrimaryRemovedWhileAnotherIsThere) {
246 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
247 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
248 true /* isprimary */, false /* hovering */);
249 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 1,
250 mapped_id_start_ + 1, false /* isprimary */,
251 false /* hovering */);
252
253 pointer_event_factory_.Remove(pointer_event1->pointerId());
254
255 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 2,
256 mapped_id_start_ + 2, false /* isprimary */,
257 false /* hovering */);
258 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 1,
259 mapped_id_start_ + 1, false /* isprimary */,
260 false /* hovering */);
261 }
262
TEST_F(PointerEventFactoryTest,TouchPointerReleasedAndPressedAgain)263 TEST_F(PointerEventFactoryTest, TouchPointerReleasedAndPressedAgain) {
264 EXPECT_FALSE(pointer_event_factory_.IsActive(mapped_id_start_));
265 EXPECT_FALSE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
266 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(mapped_id_start_));
267 EXPECT_FALSE(
268 pointer_event_factory_.IsActiveButtonsState(mapped_id_start_ + 1));
269
270 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
271 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
272 true /* isprimary */, false /* hovering */);
273 PointerEvent* pointer_event2 = CreateAndCheckWebPointerEvent(
274 WebPointerProperties::PointerType::kTouch, 1, mapped_id_start_ + 1,
275 false /* isprimary */, false /* hovering */);
276
277 CreateAndCheckPointerTransitionEvent(pointer_event1,
278 event_type_names::kPointerleave);
279 CreateAndCheckPointerTransitionEvent(pointer_event2,
280 event_type_names::kPointerenter);
281
282 EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_));
283 EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
284 EXPECT_TRUE(pointer_event_factory_.IsActiveButtonsState(mapped_id_start_));
285 EXPECT_TRUE(
286 pointer_event_factory_.IsActiveButtonsState(mapped_id_start_ + 1));
287
288 pointer_event_factory_.Remove(pointer_event1->pointerId());
289 pointer_event_factory_.Remove(pointer_event2->pointerId());
290
291 EXPECT_FALSE(pointer_event_factory_.IsActive(mapped_id_start_));
292 EXPECT_FALSE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
293 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(mapped_id_start_));
294 EXPECT_FALSE(
295 pointer_event_factory_.IsActiveButtonsState(mapped_id_start_ + 1));
296
297 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 1,
298 mapped_id_start_ + 2, true /* isprimary */,
299 false /* hovering */);
300 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 0,
301 mapped_id_start_ + 3, false /* isprimary */,
302 false /* hovering */);
303
304 pointer_event_factory_.Clear();
305
306 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 10,
307 mapped_id_start_, true /* isprimary */,
308 false /* hovering */);
309 }
310
TEST_F(PointerEventFactoryTest,TouchAndDrag)311 TEST_F(PointerEventFactoryTest, TouchAndDrag) {
312 EXPECT_FALSE(pointer_event_factory_.IsActive(mapped_id_start_));
313 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(mapped_id_start_));
314
315 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
316 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
317 true /* isprimary */, false /* hovering */);
318 PointerEvent* pointer_event2 = CreateAndCheckWebPointerEvent(
319 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
320 true /* isprimary */, false /* hovering */);
321
322 EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_));
323 EXPECT_TRUE(pointer_event_factory_.IsActiveButtonsState(mapped_id_start_));
324
325 CreateAndCheckWebPointerEvent(
326 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
327 true /* isprimary */, false /* hovering */, WebInputEvent::kNoModifiers,
328 WebInputEvent::Type::kPointerUp);
329
330 EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_));
331 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(mapped_id_start_));
332
333 pointer_event_factory_.Remove(pointer_event1->pointerId());
334 pointer_event_factory_.Remove(pointer_event2->pointerId());
335
336 EXPECT_FALSE(pointer_event_factory_.IsActive(mapped_id_start_));
337 EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(mapped_id_start_));
338
339 EXPECT_FALSE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
340 EXPECT_FALSE(
341 pointer_event_factory_.IsActiveButtonsState(mapped_id_start_ + 1));
342
343 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 0,
344 mapped_id_start_ + 1, true /* isprimary */,
345 false /* hovering */);
346 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 0,
347 mapped_id_start_ + 1, true /* isprimary */,
348 false /* hovering */);
349
350 // Remove an obsolete (i.e. already removed) pointer event which should have
351 // no effect.
352 pointer_event_factory_.Remove(pointer_event1->pointerId());
353
354 EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
355 EXPECT_TRUE(
356 pointer_event_factory_.IsActiveButtonsState(mapped_id_start_ + 1));
357
358 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 0,
359 mapped_id_start_ + 1, true /* isprimary */,
360 false /* hovering */);
361 CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kTouch, 0,
362 mapped_id_start_ + 1, true);
363
364 EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
365 EXPECT_FALSE(
366 pointer_event_factory_.IsActiveButtonsState(mapped_id_start_ + 1));
367
368 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 0,
369 mapped_id_start_ + 1, true /* isprimary */,
370 false /* hovering */);
371
372 EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
373 EXPECT_TRUE(
374 pointer_event_factory_.IsActiveButtonsState(mapped_id_start_ + 1));
375 }
376
TEST_F(PointerEventFactoryTest,MouseAndTouchAndPen)377 TEST_F(PointerEventFactoryTest, MouseAndTouchAndPen) {
378 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, 0,
379 expected_mouse_id_, true /* isprimary */,
380 true /* hovering */);
381 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
382 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
383 true /* isprimary */, false /* hovering */);
384 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
385 mapped_id_start_ + 1, true /* isprimary */,
386 false /* hovering */);
387
388 PointerEvent* pointer_event2 = CreateAndCheckWebPointerEvent(
389 WebPointerProperties::PointerType::kTouch, 1, mapped_id_start_ + 2,
390 false /* isprimary */, false /* hovering */);
391 PointerEvent* pointer_event3 = CreateAndCheckWebPointerEvent(
392 WebPointerProperties::PointerType::kTouch, 2, mapped_id_start_ + 3,
393 false /* isprimary */, false /* hovering */);
394 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
395 mapped_id_start_ + 1, true /* isprimary */,
396 false /* hovering */);
397 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 47213,
398 mapped_id_start_ + 4, false /* isprimary */,
399 false /* hovering */);
400
401 pointer_event_factory_.Remove(pointer_event1->pointerId());
402 pointer_event_factory_.Remove(pointer_event2->pointerId());
403 pointer_event_factory_.Remove(pointer_event3->pointerId());
404
405 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 100,
406 mapped_id_start_ + 5, true /* isprimary */,
407 false /* hovering */);
408
409 pointer_event_factory_.Clear();
410
411 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, 0,
412 expected_mouse_id_, true /* isprimary */,
413 true /* hovering */);
414 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 0,
415 mapped_id_start_, true /* isprimary */,
416 false /* hovering */);
417 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
418 mapped_id_start_ + 1, true /* isprimary */,
419 false /* hovering */);
420 }
421
TEST_F(PointerEventFactoryTest,NonHoveringPointers)422 TEST_F(PointerEventFactoryTest, NonHoveringPointers) {
423 CheckNonHoveringPointers({});
424
425 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, 0,
426 expected_mouse_id_, true /* isprimary */,
427 true /* hovering */);
428 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
429 WebPointerProperties::PointerType::kPen, 0, mapped_id_start_,
430 true /* isprimary */, true /* hovering */);
431 CheckNonHoveringPointers({});
432
433 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
434 mapped_id_start_, true /* isprimary */,
435 false /* hovering */);
436 CheckNonHoveringPointers({mapped_id_start_});
437
438 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 0,
439 mapped_id_start_ + 1, true /* isprimary */,
440 false /* hovering */);
441 CheckNonHoveringPointers({mapped_id_start_, mapped_id_start_ + 1});
442
443 pointer_event_factory_.Remove(pointer_event1->pointerId());
444 CheckNonHoveringPointers({mapped_id_start_ + 1});
445
446 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 1,
447 mapped_id_start_ + 2, false /* isprimary */,
448 false /* hovering */);
449
450 CheckNonHoveringPointers({mapped_id_start_ + 1, mapped_id_start_ + 2});
451
452 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, 1,
453 mapped_id_start_ + 2, false /* isprimary */,
454 true /* hovering */);
455
456 CheckNonHoveringPointers({mapped_id_start_ + 1});
457
458 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
459 mapped_id_start_ + 3, true /* isprimary */,
460 false /* hovering */);
461
462 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 1,
463 mapped_id_start_ + 4, false /* isprimary */,
464 false /* hovering */);
465
466 CheckNonHoveringPointers(
467 {mapped_id_start_ + 1, mapped_id_start_ + 3, mapped_id_start_ + 4});
468
469 pointer_event_factory_.Clear();
470 CheckNonHoveringPointers({});
471 }
472
TEST_F(PointerEventFactoryTest,PenAsTouchAndMouseEvent)473 TEST_F(PointerEventFactoryTest, PenAsTouchAndMouseEvent) {
474 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
475 WebPointerProperties::PointerType::kPen, 0, mapped_id_start_,
476 true /* isprimary */, true /* hovering */);
477 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 1,
478 mapped_id_start_ + 1, false /* isprimary */,
479 true /* hovering */);
480 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 2,
481 mapped_id_start_ + 2, false /* isprimary */,
482 true /* hovering */);
483 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
484 mapped_id_start_, true /* isprimary */,
485 true /* hovering */);
486 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 1,
487 mapped_id_start_ + 1, false /* isprimary */,
488 true /* hovering */);
489 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
490 mapped_id_start_, true /* isprimary */,
491 false /* hovering */);
492 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 1,
493 mapped_id_start_ + 1, false /* isprimary */,
494 false /* hovering */);
495
496 pointer_event_factory_.Remove(pointer_event1->pointerId());
497
498 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
499 mapped_id_start_ + 3, false /* isprimary */,
500 false /* hovering */);
501 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
502 mapped_id_start_ + 3, false /* isprimary */,
503 true /* hovering */);
504 CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kPen, 0,
505 mapped_id_start_ + 3, false);
506
507 pointer_event_factory_.Clear();
508
509 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 1,
510 mapped_id_start_, true /* isprimary */,
511 false /* hovering */);
512 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
513 mapped_id_start_ + 1, false /* isprimary */,
514 false /* hovering */);
515 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 1,
516 mapped_id_start_, true /* isprimary */,
517 true /* hovering */);
518 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kPen, 0,
519 mapped_id_start_ + 1, false /* isprimary */,
520 true /* hovering */);
521 CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kPen, 1,
522 mapped_id_start_, true);
523 CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kPen, 0,
524 mapped_id_start_ + 1, false);
525 }
526
TEST_F(PointerEventFactoryTest,OutOfRange)527 TEST_F(PointerEventFactoryTest, OutOfRange) {
528 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
529 WebPointerProperties::PointerType::kUnknown, 0, mapped_id_start_,
530 true /* isprimary */, true /* hovering */);
531 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kUnknown, 1,
532 mapped_id_start_ + 1, false /* isprimary */,
533 true /* hovering */);
534 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kUnknown, 2,
535 mapped_id_start_ + 2, false /* isprimary */,
536 true /* hovering */);
537 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kUnknown, 0,
538 mapped_id_start_, true /* isprimary */,
539 false /* hovering */);
540 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kUnknown, 3,
541 mapped_id_start_ + 3, false /* isprimary */,
542 false /* hovering */);
543 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kUnknown, 2,
544 mapped_id_start_ + 2, false /* isprimary */,
545 true /* hovering */);
546 CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kUnknown, 3,
547 mapped_id_start_ + 3, false);
548
549 pointer_event_factory_.Remove(pointer_event1->pointerId());
550
551 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kUnknown, 0,
552 mapped_id_start_ + 4, false /* isprimary */,
553 false /* hovering */);
554 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kUnknown,
555 std::numeric_limits<int>::max(),
556 mapped_id_start_ + 5, false /* isprimary */,
557 false /* hovering */);
558
559 pointer_event_factory_.Clear();
560
561 for (int i = 0; i < 100; ++i) {
562 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kTouch, i,
563 mapped_id_start_ + i, i == 0 /* isprimary */,
564 true /* hovering */);
565 }
566
567 for (int i = 0; i < 100; ++i) {
568 CreateAndCheckWebPointerEvent(WebPointerProperties::PointerType::kMouse, i,
569 expected_mouse_id_, true /* isprimary */,
570 false /* hovering */);
571 }
572 CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kMouse, 0,
573 expected_mouse_id_, true);
574
575 EXPECT_EQ(pointer_event_factory_.IsActive(0), false);
576 EXPECT_EQ(pointer_event_factory_.IsActive(-1), false);
577 EXPECT_EQ(
578 pointer_event_factory_.IsActive(std::numeric_limits<PointerId>::max()),
579 false);
580 }
581
TEST_F(PointerEventFactoryTest,LastPointerPosition)582 TEST_F(PointerEventFactoryTest, LastPointerPosition) {
583 CreateAndCheckWebPointerEvent(
584 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
585 true /* isprimary */, true /* hovering */, WebInputEvent::kNoModifiers,
586 WebInputEvent::Type::kPointerMove,
587 WebPointerProperties::Button::kNoButton, 4);
588 pointer_event_factory_.RemoveLastPosition(expected_mouse_id_);
589 EXPECT_EQ(
590 pointer_event_factory_.GetLastPointerPosition(
591 expected_mouse_id_,
592 WebPointerProperties(1, WebPointerProperties::PointerType::kUnknown,
593 WebPointerProperties::Button::kNoButton,
594 gfx::PointF(50, 50), gfx::PointF(20, 20)),
595 WebInputEvent::Type::kPointerMove),
596 FloatPoint(20, 20));
597 }
598
TEST_F(PointerEventFactoryTest,CoalescedEvents)599 TEST_F(PointerEventFactoryTest, CoalescedEvents) {
600 CreateAndCheckWebPointerEvent(
601 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
602 true /* isprimary */, true /* hovering */, WebInputEvent::kNoModifiers,
603 WebInputEvent::Type::kPointerMove,
604 WebPointerProperties::Button::kNoButton, 4);
605 CreateAndCheckWebPointerEvent(
606 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
607 true /* isprimary */, false /* hovering */, WebInputEvent::kNoModifiers,
608 WebInputEvent::Type::kPointerMove,
609 WebPointerProperties::Button::kNoButton, 3);
610 }
611
TEST_F(PointerEventFactoryTest,PredictedEvents)612 TEST_F(PointerEventFactoryTest, PredictedEvents) {
613 CreateAndCheckWebPointerEvent(
614 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
615 true /* isprimary */, true /* hovering */, WebInputEvent::kNoModifiers,
616 WebInputEvent::Type::kPointerMove,
617 WebPointerProperties::Button::kNoButton, 0 /* coalesced_count */,
618 4 /* predicted_count */);
619 CreateAndCheckWebPointerEvent(
620 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
621 true /* isprimary */, false /* hovering */, WebInputEvent::kNoModifiers,
622 WebInputEvent::Type::kPointerMove,
623 WebPointerProperties::Button::kNoButton, 0 /* coalesced_count */,
624 3 /* predicted_count */);
625
626 // Check predicted_event_count when type != kPointerMove
627 CreateAndCheckWebPointerEvent(
628 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
629 true /* isprimary */, true /* hovering */, WebInputEvent::kNoModifiers,
630 WebInputEvent::Type::kPointerDown,
631 WebPointerProperties::Button::kNoButton, 0 /* coalesced_count */,
632 4 /* predicted_count */);
633 CreateAndCheckWebPointerEvent(
634 WebPointerProperties::PointerType::kTouch, 0, mapped_id_start_,
635 true /* isprimary */, false /* hovering */, WebInputEvent::kNoModifiers,
636 WebInputEvent::Type::kPointerUp, WebPointerProperties::Button::kNoButton,
637 0 /* coalesced_count */, 3 /* predicted_count */);
638 }
639
TEST_F(PointerEventFactoryTest,PenEraserButton)640 TEST_F(PointerEventFactoryTest, PenEraserButton) {
641 // Send the pointerdown event when pressing the eraser button on the tablet.
642 PointerEvent* first_pointerdown_event = CreateAndCheckWebPointerEvent(
643 WebPointerProperties::PointerType::kEraser, 0, mapped_id_start_,
644 true /* isprimary */, false /* hovering */,
645 WebInputEvent::kLeftButtonDown, WebInputEvent::Type::kPointerDown,
646 WebPointerProperties::Button::kLeft);
647 EXPECT_EQ(event_type_names::kPointerdown, first_pointerdown_event->type());
648
649 // Send the pointermove event when pressing any other button while the eraser
650 // button is still pressed on the tablet.
651 WebInputEvent::Modifiers modifiers = static_cast<WebInputEvent::Modifiers>(
652 WebInputEvent::kLeftButtonDown | WebInputEvent::kRightButtonDown);
653 PointerEvent* second_pointerdown_event = CreateAndCheckWebPointerEvent(
654 WebPointerProperties::PointerType::kEraser, 1, mapped_id_start_ + 1,
655 false /* isprimary */, false /* hovering */, modifiers,
656 WebInputEvent::Type::kPointerDown, WebPointerProperties::Button::kRight);
657 EXPECT_EQ(event_type_names::kPointermove, second_pointerdown_event->type());
658
659 // Send the pointermove event when releasing any other button while the
660 // eraser button is still pressed on the tablet.
661 PointerEvent* first_pointerup_event = CreateAndCheckWebPointerEvent(
662 WebPointerProperties::PointerType::kEraser, 1, mapped_id_start_ + 1,
663 false /* isprimary */, true /* hovering */,
664 WebInputEvent::kLeftButtonDown, WebInputEvent::Type::kPointerUp,
665 WebPointerProperties::Button::kRight);
666 EXPECT_EQ(event_type_names::kPointermove, first_pointerup_event->type());
667
668 // Send the pointerup event when releasing the eraser button from the tablet.
669 PointerEvent* last_pointerup_event = CreateAndCheckWebPointerEvent(
670 WebPointerProperties::PointerType::kEraser, 0, mapped_id_start_,
671 true /* isprimary */, true /* hovering */, WebInputEvent::kNoModifiers,
672 WebInputEvent::Type::kPointerUp, WebPointerProperties::Button::kLeft);
673 EXPECT_EQ(event_type_names::kPointerup, last_pointerup_event->type());
674 }
675
TEST_F(PointerEventFactoryTest,MousePointerKeyStates)676 TEST_F(PointerEventFactoryTest, MousePointerKeyStates) {
677 WebInputEvent::Modifiers modifiers = static_cast<WebInputEvent::Modifiers>(
678 WebInputEvent::kControlKey | WebInputEvent::kMetaKey);
679
680 PointerEvent* pointer_event1 = CreateAndCheckWebPointerEvent(
681 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
682 true /* isprimary */, true /* hovering */, modifiers,
683 WebInputEvent::Type::kPointerMove);
684
685 CreateAndCheckPointerTransitionEvent(pointer_event1,
686 event_type_names::kPointerout);
687
688 modifiers = static_cast<WebInputEvent::Modifiers>(WebInputEvent::kAltKey |
689 WebInputEvent::kShiftKey);
690 PointerEvent* pointer_event2 = CreateAndCheckWebPointerEvent(
691 WebPointerProperties::PointerType::kMouse, 0, expected_mouse_id_,
692 true /* isprimary */, true /* hovering */, modifiers,
693 WebInputEvent::Type::kPointerMove);
694
695 CreateAndCheckPointerTransitionEvent(pointer_event2,
696 event_type_names::kPointerover);
697 }
698
699 } // namespace blink
700