1 // Copyright (c) 2012 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 "ui/events/event.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <memory>
11 
12 #include "base/stl_util.h"
13 #include "base/test/metrics/histogram_tester.h"
14 #include "build/build_config.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/base/ui_base_features.h"
17 #include "ui/events/event_constants.h"
18 #include "ui/events/event_utils.h"
19 #include "ui/events/keycodes/dom/dom_code.h"
20 #include "ui/events/keycodes/dom/keycode_converter.h"
21 #include "ui/events/keycodes/keyboard_code_conversion.h"
22 #include "ui/events/test/events_test_utils.h"
23 #include "ui/events/test/keyboard_layout.h"
24 #include "ui/events/test/test_event_target.h"
25 #include "ui/gfx/transform.h"
26 
27 namespace ui {
28 
TEST(EventTest,NoNativeEvent)29 TEST(EventTest, NoNativeEvent) {
30   KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
31   EXPECT_FALSE(keyev.HasNativeEvent());
32 }
33 
TEST(EventTest,NativeEvent)34 TEST(EventTest, NativeEvent) {
35 #if defined(OS_WIN)
36   MSG native_event = {nullptr, WM_KEYUP, VKEY_A, 0};
37   KeyEvent keyev(native_event);
38   EXPECT_TRUE(keyev.HasNativeEvent());
39 #endif
40 }
41 
TEST(EventTest,GetCharacter)42 TEST(EventTest, GetCharacter) {
43   ui::ScopedKeyboardLayout keyboard_layout(ui::KEYBOARD_LAYOUT_ENGLISH_US);
44 
45   // Check if Control+Enter returns 10.
46   KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
47   EXPECT_EQ(10, keyev1.GetCharacter());
48   // Check if Enter returns 13.
49   KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
50   EXPECT_EQ(13, keyev2.GetCharacter());
51 
52   // Check if expected Unicode character was returned for a key combination
53   // contains Control.
54   // e.g. Control+Shift+2 produces U+200C on "Persian" keyboard.
55   // http://crbug.com/582453
56   KeyEvent keyev5(0x200C, VKEY_UNKNOWN, ui::DomCode::NONE,
57                   EF_CONTROL_DOWN | EF_SHIFT_DOWN);
58   EXPECT_EQ(0x200C, keyev5.GetCharacter());
59 }
60 
TEST(EventTest,ClickCount)61 TEST(EventTest, ClickCount) {
62   const gfx::Point origin(0, 0);
63   MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
64   for (int i = 1; i <= 3; ++i) {
65     mouseev.SetClickCount(i);
66     EXPECT_EQ(i, mouseev.GetClickCount());
67   }
68 }
69 
TEST(EventTest,RepeatedClick)70 TEST(EventTest, RepeatedClick) {
71   const gfx::Point origin(0, 0);
72   MouseEvent event1(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
73   MouseEvent event2(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
74   LocatedEventTestApi test_event1(&event1);
75   LocatedEventTestApi test_event2(&event2);
76 
77   base::TimeTicks start = base::TimeTicks::Now();
78   base::TimeTicks soon = start + base::TimeDelta::FromMilliseconds(1);
79   base::TimeTicks later = start + base::TimeDelta::FromMilliseconds(1000);
80 
81   // Same time stamp (likely the same native event).
82   test_event1.set_location(gfx::Point(0, 0));
83   test_event2.set_location(gfx::Point(1, 0));
84   test_event1.set_time_stamp(start);
85   test_event2.set_time_stamp(start);
86   EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
87   MouseEvent mouse_ev3(event1);
88   EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, mouse_ev3));
89 
90   // Close point.
91   test_event1.set_location(gfx::Point(0, 0));
92   test_event2.set_location(gfx::Point(1, 0));
93   test_event1.set_time_stamp(start);
94   test_event2.set_time_stamp(soon);
95   EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(event1, event2));
96 
97   // Too far.
98   test_event1.set_location(gfx::Point(0, 0));
99   test_event2.set_location(gfx::Point(10, 0));
100   test_event1.set_time_stamp(start);
101   test_event2.set_time_stamp(soon);
102   EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
103 
104   // Too long a time between clicks.
105   test_event1.set_location(gfx::Point(0, 0));
106   test_event2.set_location(gfx::Point(0, 0));
107   test_event1.set_time_stamp(start);
108   test_event2.set_time_stamp(later);
109   EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
110 }
111 
TEST(EventTest,RepeatedKeyEvent)112 TEST(EventTest, RepeatedKeyEvent) {
113   base::TimeTicks start = base::TimeTicks::Now();
114   base::TimeTicks time1 = start + base::TimeDelta::FromMilliseconds(1);
115   base::TimeTicks time2 = start + base::TimeDelta::FromMilliseconds(2);
116   base::TimeTicks time3 = start + base::TimeDelta::FromMilliseconds(3);
117 
118   KeyEvent event1(ET_KEY_PRESSED, VKEY_A, 0, start);
119   KeyEvent event2(ET_KEY_PRESSED, VKEY_A, 0, time1);
120   KeyEvent event3(ET_KEY_PRESSED, VKEY_A, EF_LEFT_MOUSE_BUTTON, time2);
121   KeyEvent event4(ET_KEY_PRESSED, VKEY_A, 0, time3);
122 
123   event1.InitializeNative();
124   EXPECT_TRUE((event1.flags() & EF_IS_REPEAT) == 0);
125   event2.InitializeNative();
126   EXPECT_TRUE((event2.flags() & EF_IS_REPEAT) != 0);
127 
128   event3.InitializeNative();
129   EXPECT_TRUE((event3.flags() & EF_IS_REPEAT) != 0);
130 
131   event4.InitializeNative();
132   EXPECT_TRUE((event4.flags() & EF_IS_REPEAT) != 0);
133 }
134 
135 // Tests that re-processing the same mouse press event (detected by timestamp)
136 // does not yield a double click event: http://crbug.com/389162
TEST(EventTest,DoubleClickRequiresUniqueTimestamp)137 TEST(EventTest, DoubleClickRequiresUniqueTimestamp) {
138   const gfx::Point point(0, 0);
139   base::TimeTicks time1 = base::TimeTicks::Now();
140   base::TimeTicks time2 = time1 + base::TimeDelta::FromMilliseconds(1);
141 
142   // Re-processing the same press doesn't yield a double-click.
143   MouseEvent event(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
144   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
145   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
146   // Processing a press with the same timestamp doesn't yield a double-click.
147   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
148   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
149   // Processing a press with a later timestamp does yield a double-click.
150   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2, 0, 0);
151   EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
152   MouseEvent::ResetLastClickForTest();
153 
154   // Test processing a double press and release sequence with one timestamp.
155   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
156   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
157   event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
158   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
159   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
160   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
161   event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
162   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
163   MouseEvent::ResetLastClickForTest();
164 
165   // Test processing a double press and release sequence with two timestamps.
166   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
167   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
168   event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
169   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
170   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2, 0, 0);
171   EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
172   event = MouseEvent(ET_MOUSE_RELEASED, point, point, time2, 0, 0);
173   EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
174   MouseEvent::ResetLastClickForTest();
175 }
176 
177 // Tests that right clicking, then left clicking does not yield double clicks.
TEST(EventTest,SingleClickRightLeft)178 TEST(EventTest, SingleClickRightLeft) {
179   const gfx::Point point(0, 0);
180   base::TimeTicks time1 = base::TimeTicks::Now();
181   base::TimeTicks time2 = time1 + base::TimeDelta::FromMilliseconds(1);
182   base::TimeTicks time3 = time1 + base::TimeDelta::FromMilliseconds(2);
183 
184   MouseEvent event(ET_MOUSE_PRESSED, point, point, time1,
185                    ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON);
186   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
187   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2,
188                      ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
189   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
190   event = MouseEvent(ET_MOUSE_RELEASED, point, point, time2,
191                      ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
192   EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
193   event = MouseEvent(ET_MOUSE_PRESSED, point, point, time3,
194                      ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
195   EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
196   MouseEvent::ResetLastClickForTest();
197 }
198 
TEST(EventTest,KeyEvent)199 TEST(EventTest, KeyEvent) {
200   ui::ScopedKeyboardLayout keyboard_layout(ui::KEYBOARD_LAYOUT_ENGLISH_US);
201 
202   static const struct {
203     KeyboardCode key_code;
204     int flags;
205     uint16_t character;
206   } kTestData[] = {
207       {VKEY_A, 0, 'a'},
208       {VKEY_A, EF_SHIFT_DOWN, 'A'},
209       {VKEY_A, EF_CAPS_LOCK_ON, 'A'},
210       {VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, 'a'},
211       {VKEY_A, EF_CONTROL_DOWN, 0x01},
212       {VKEY_A, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x01'},
213       {VKEY_Z, 0, 'z'},
214       {VKEY_Z, EF_SHIFT_DOWN, 'Z'},
215       {VKEY_Z, EF_CAPS_LOCK_ON, 'Z'},
216       {VKEY_Z, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, 'z'},
217       {VKEY_Z, EF_CONTROL_DOWN, '\x1A'},
218       {VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1A'},
219 
220       {VKEY_2, EF_CONTROL_DOWN, '\x12'},
221       {VKEY_2, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0'},
222       {VKEY_6, EF_CONTROL_DOWN, '\x16'},
223       {VKEY_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1E'},
224       {VKEY_OEM_MINUS, EF_CONTROL_DOWN, '\x0D'},
225       {VKEY_OEM_MINUS, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1F'},
226       {VKEY_OEM_4, EF_CONTROL_DOWN, '\x1B'},
227       {VKEY_OEM_4, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1B'},
228       {VKEY_OEM_5, EF_CONTROL_DOWN, '\x1C'},
229       {VKEY_OEM_5, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1C'},
230       {VKEY_OEM_6, EF_CONTROL_DOWN, '\x1D'},
231       {VKEY_OEM_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1D'},
232       {VKEY_RETURN, EF_CONTROL_DOWN, '\x0A'},
233 
234       {VKEY_0, 0, '0'},
235       {VKEY_0, EF_SHIFT_DOWN, ')'},
236       {VKEY_0, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, ')'},
237       {VKEY_0, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x09'},
238 
239       {VKEY_9, 0, '9'},
240       {VKEY_9, EF_SHIFT_DOWN, '('},
241       {VKEY_9, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, '('},
242       {VKEY_9, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x08'},
243 
244       {VKEY_NUMPAD0, EF_CONTROL_DOWN, '\x10'},
245       {VKEY_NUMPAD0, EF_SHIFT_DOWN, '0'},
246 
247       {VKEY_NUMPAD9, EF_CONTROL_DOWN, '\x19'},
248       {VKEY_NUMPAD9, EF_SHIFT_DOWN, '9'},
249 
250       {VKEY_TAB, EF_NONE, '\t'},
251       {VKEY_TAB, EF_CONTROL_DOWN, '\t'},
252       {VKEY_TAB, EF_SHIFT_DOWN, '\t'},
253 
254       {VKEY_MULTIPLY, EF_CONTROL_DOWN, '\x0A'},
255       {VKEY_MULTIPLY, EF_SHIFT_DOWN, '*'},
256       {VKEY_ADD, EF_CONTROL_DOWN, '\x0B'},
257       {VKEY_ADD, EF_SHIFT_DOWN, '+'},
258       {VKEY_SUBTRACT, EF_CONTROL_DOWN, '\x0D'},
259       {VKEY_SUBTRACT, EF_SHIFT_DOWN, '-'},
260       {VKEY_DECIMAL, EF_CONTROL_DOWN, '\x0E'},
261       {VKEY_DECIMAL, EF_SHIFT_DOWN, '.'},
262       {VKEY_DIVIDE, EF_CONTROL_DOWN, '\x0F'},
263       {VKEY_DIVIDE, EF_SHIFT_DOWN, '/'},
264 
265       {VKEY_OEM_1, EF_CONTROL_DOWN, '\x1B'},
266       {VKEY_OEM_1, EF_SHIFT_DOWN, ':'},
267       {VKEY_OEM_PLUS, EF_CONTROL_DOWN, '\x1D'},
268       {VKEY_OEM_PLUS, EF_SHIFT_DOWN, '+'},
269       {VKEY_OEM_COMMA, EF_CONTROL_DOWN, '\x0C'},
270       {VKEY_OEM_COMMA, EF_SHIFT_DOWN, '<'},
271       {VKEY_OEM_PERIOD, EF_CONTROL_DOWN, '\x0E'},
272       {VKEY_OEM_PERIOD, EF_SHIFT_DOWN, '>'},
273       {VKEY_OEM_3, EF_CONTROL_DOWN, '\x0'},
274       {VKEY_OEM_3, EF_SHIFT_DOWN, '~'},
275   };
276 
277   for (size_t i = 0; i < base::size(kTestData); ++i) {
278     KeyEvent key(ET_KEY_PRESSED, kTestData[i].key_code, kTestData[i].flags);
279     EXPECT_EQ(kTestData[i].character, key.GetCharacter())
280         << " Index:" << i << " key_code:" << kTestData[i].key_code;
281   }
282 }
283 
TEST(EventTest,KeyEventDirectUnicode)284 TEST(EventTest, KeyEventDirectUnicode) {
285   KeyEvent key(0x1234U, ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_NONE);
286   EXPECT_EQ(0x1234U, key.GetCharacter());
287   EXPECT_EQ(ET_KEY_PRESSED, key.type());
288   EXPECT_TRUE(key.is_char());
289 }
290 
TEST(EventTest,NormalizeKeyEventFlags)291 TEST(EventTest, NormalizeKeyEventFlags) {
292   // Do not normalize flags for synthesized events without
293   // KeyEvent::NormalizeFlags called explicitly.
294   {
295     KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
296     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
297   }
298   {
299     KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
300     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
301     keyev.NormalizeFlags();
302     EXPECT_EQ(EF_NONE, keyev.flags());
303   }
304   {
305     KeyEvent keyev(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
306     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
307   }
308   {
309     KeyEvent keyev(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
310     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
311     keyev.NormalizeFlags();
312     EXPECT_EQ(EF_NONE, keyev.flags());
313   }
314   {
315     KeyEvent keyev(ET_KEY_PRESSED, VKEY_MENU, EF_ALT_DOWN);
316     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
317   }
318   {
319     KeyEvent keyev(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
320     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
321     keyev.NormalizeFlags();
322     EXPECT_EQ(EF_NONE, keyev.flags());
323   }
324 }
325 
TEST(EventTest,KeyEventCopy)326 TEST(EventTest, KeyEventCopy) {
327   KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE);
328   std::unique_ptr<KeyEvent> copied_key(new KeyEvent(key));
329   EXPECT_EQ(copied_key->type(), key.type());
330   EXPECT_EQ(copied_key->key_code(), key.key_code());
331 }
332 
TEST(EventTest,KeyEventCode)333 TEST(EventTest, KeyEventCode) {
334   const DomCode kDomCodeForSpace = DomCode::SPACE;
335   const char kCodeForSpace[] = "Space";
336   ASSERT_EQ(kDomCodeForSpace,
337             ui::KeycodeConverter::CodeStringToDomCode(kCodeForSpace));
338   const uint16_t kNativeCodeSpace =
339       ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace);
340   ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace);
341   ASSERT_EQ(kNativeCodeSpace,
342             ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace));
343 
344   {
345     KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kDomCodeForSpace, EF_NONE);
346     EXPECT_EQ(kCodeForSpace, key.GetCodeString());
347   }
348   {
349     // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be
350     // the specified value.
351     KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kDomCodeForSpace, EF_NONE);
352     EXPECT_EQ(kCodeForSpace, key.GetCodeString());
353   }
354   {
355     // If the synthetic event is initialized without code, the code is
356     // determined from the KeyboardCode assuming a US keyboard layout.
357     KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
358     EXPECT_EQ(kCodeForSpace, key.GetCodeString());
359   }
360 #if defined(OS_WIN)
361   {
362     // Test a non extended key.
363     ASSERT_EQ((kNativeCodeSpace & 0xFF), kNativeCodeSpace);
364 
365     const LPARAM lParam = GetLParamFromScanCode(kNativeCodeSpace);
366     MSG native_event = {nullptr, WM_KEYUP, VKEY_SPACE, lParam};
367     KeyEvent key(native_event);
368 
369     // KeyEvent converts from the native keycode (scan code) to the code.
370     EXPECT_EQ(kCodeForSpace, key.GetCodeString());
371   }
372   {
373     const char kCodeForHome[] = "Home";
374     const uint16_t kNativeCodeHome = 0xe047;
375 
376     // 'Home' is an extended key with 0xe000 bits.
377     ASSERT_NE((kNativeCodeHome & 0xFF), kNativeCodeHome);
378     const LPARAM lParam = GetLParamFromScanCode(kNativeCodeHome);
379 
380     MSG native_event = {nullptr, WM_KEYUP, VKEY_HOME, lParam};
381     KeyEvent key(native_event);
382 
383     // KeyEvent converts from the native keycode (scan code) to the code.
384     EXPECT_EQ(kCodeForHome, key.GetCodeString());
385   }
386 #endif  // OS_WIN
387 }
388 
TEST(EventTest,TouchEventRadiusDefaultsToOtherAxis)389 TEST(EventTest, TouchEventRadiusDefaultsToOtherAxis) {
390   const base::TimeTicks time = base::TimeTicks::Now();
391   const float non_zero_length1 = 30;
392   const float non_zero_length2 = 46;
393 
394   TouchEvent event1(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
395                     PointerDetails(ui::EventPointerType::kTouch,
396                                    /* pointer_id*/ 0,
397                                    /* radius_x */ non_zero_length1,
398                                    /* radius_y */ 0.0f,
399                                    /* force */ 0));
400   EXPECT_EQ(non_zero_length1, event1.pointer_details().radius_x);
401   EXPECT_EQ(non_zero_length1, event1.pointer_details().radius_y);
402 
403   TouchEvent event2(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
404                     PointerDetails(ui::EventPointerType::kTouch,
405                                    /* pointer_id*/ 0,
406                                    /* radius_x */ 0.0f,
407                                    /* radius_y */ non_zero_length2,
408                                    /* force */ 0));
409   EXPECT_EQ(non_zero_length2, event2.pointer_details().radius_x);
410   EXPECT_EQ(non_zero_length2, event2.pointer_details().radius_y);
411 }
412 
TEST(EventTest,TouchEventRotationAngleFixing)413 TEST(EventTest, TouchEventRotationAngleFixing) {
414   const base::TimeTicks time = base::TimeTicks::Now();
415   const float radius_x = 20;
416   const float radius_y = 10;
417 
418   {
419     const float angle_in_range = 0;
420     TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
421                      PointerDetails(ui::EventPointerType::kTouch,
422                                     /* pointer_id*/ 0, radius_x, radius_y,
423                                     /* force */ 0, angle_in_range),
424                      0);
425     EXPECT_FLOAT_EQ(angle_in_range, event.ComputeRotationAngle());
426   }
427 
428   {
429     const float angle_in_range = 179.9f;
430     TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
431                      PointerDetails(ui::EventPointerType::kTouch,
432                                     /* pointer_id*/ 0, radius_x, radius_y,
433                                     /* force */ 0, angle_in_range),
434                      0);
435     EXPECT_FLOAT_EQ(angle_in_range, event.ComputeRotationAngle());
436   }
437 
438   {
439     const float angle_negative = -0.1f;
440     TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
441                      PointerDetails(ui::EventPointerType::kTouch,
442                                     /* pointer_id*/ 0, radius_x, radius_y,
443                                     /* force */ 0, angle_negative),
444                      0);
445     EXPECT_FLOAT_EQ(180 - 0.1f, event.ComputeRotationAngle());
446   }
447 
448   {
449     const float angle_negative = -200;
450     TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
451                      PointerDetails(ui::EventPointerType::kTouch,
452                                     /* pointer_id*/ 0, radius_x, radius_y,
453                                     /* force */ 0, angle_negative),
454                      0);
455     EXPECT_FLOAT_EQ(360 - 200, event.ComputeRotationAngle());
456   }
457 
458   {
459     const float angle_too_big = 180;
460     TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
461                      PointerDetails(ui::EventPointerType::kTouch,
462                                     /* pointer_id*/ 0, radius_x, radius_y,
463                                     /* force */ 0, angle_too_big),
464                      0);
465     EXPECT_FLOAT_EQ(0, event.ComputeRotationAngle());
466   }
467 
468   {
469     const float angle_too_big = 400;
470     TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
471                      PointerDetails(ui::EventPointerType::kTouch,
472                                     /* pointer_id*/ 0, radius_x, radius_y,
473                                     /* force */ 0, angle_too_big),
474                      0);
475     EXPECT_FLOAT_EQ(400 - 360, event.ComputeRotationAngle());
476   }
477 }
478 
TEST(EventTest,PointerDetailsTouch)479 TEST(EventTest, PointerDetailsTouch) {
480   ui::TouchEvent touch_event_plain(
481       ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
482       PointerDetails(ui::EventPointerType::kTouch, 0));
483 
484   EXPECT_EQ(EventPointerType::kTouch,
485             touch_event_plain.pointer_details().pointer_type);
486   EXPECT_EQ(0.0f, touch_event_plain.pointer_details().radius_x);
487   EXPECT_EQ(0.0f, touch_event_plain.pointer_details().radius_y);
488   EXPECT_TRUE(std::isnan(touch_event_plain.pointer_details().force));
489   EXPECT_EQ(0.0f, touch_event_plain.pointer_details().tilt_x);
490   EXPECT_EQ(0.0f, touch_event_plain.pointer_details().tilt_y);
491 
492   ui::TouchEvent touch_event_with_details(
493       ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
494       PointerDetails(ui::EventPointerType::kTouch,
495                      /* pointer_id*/ 0,
496                      /* radius_x */ 10.0f,
497                      /* radius_y */ 5.0f,
498                      /* force */ 15.0f));
499 
500   EXPECT_EQ(EventPointerType::kTouch,
501             touch_event_with_details.pointer_details().pointer_type);
502   EXPECT_EQ(10.0f, touch_event_with_details.pointer_details().radius_x);
503   EXPECT_EQ(5.0f, touch_event_with_details.pointer_details().radius_y);
504   EXPECT_EQ(15.0f, touch_event_with_details.pointer_details().force);
505   EXPECT_EQ(0.0f, touch_event_with_details.pointer_details().tilt_x);
506   EXPECT_EQ(0.0f, touch_event_with_details.pointer_details().tilt_y);
507 
508   ui::TouchEvent touch_event_copy(touch_event_with_details);
509   EXPECT_EQ(touch_event_with_details.pointer_details(),
510             touch_event_copy.pointer_details());
511 }
512 
TEST(EventTest,PointerDetailsMouse)513 TEST(EventTest, PointerDetailsMouse) {
514   ui::MouseEvent mouse_event(ET_MOUSE_PRESSED, gfx::Point(0, 0),
515                              gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0);
516 
517   EXPECT_EQ(EventPointerType::kMouse,
518             mouse_event.pointer_details().pointer_type);
519   EXPECT_EQ(0.0f, mouse_event.pointer_details().radius_x);
520   EXPECT_EQ(0.0f, mouse_event.pointer_details().radius_y);
521   EXPECT_TRUE(std::isnan(mouse_event.pointer_details().force));
522   EXPECT_EQ(0.0f, mouse_event.pointer_details().tilt_x);
523   EXPECT_EQ(0.0f, mouse_event.pointer_details().tilt_y);
524 
525   ui::MouseEvent mouse_event_copy(mouse_event);
526   EXPECT_EQ(mouse_event.pointer_details(), mouse_event_copy.pointer_details());
527 }
528 
TEST(EventTest,PointerDetailsStylus)529 TEST(EventTest, PointerDetailsStylus) {
530   ui::PointerDetails pointer_details(EventPointerType::kPen,
531                                      /* pointer_id*/ 0,
532                                      /* radius_x */ 0.0f,
533                                      /* radius_y */ 0.0f,
534                                      /* force */ 21.0f,
535                                      /* twist */ 196,
536                                      /* tilt_x */ 45.0f,
537                                      /* tilt_y */ -45.0f,
538                                      /* tangential_pressure */ 0.7f);
539 
540   ui::MouseEvent stylus_event(ET_MOUSE_PRESSED, gfx::Point(0, 0),
541                               gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0,
542                               pointer_details);
543   EXPECT_EQ(EventPointerType::kPen,
544             stylus_event.pointer_details().pointer_type);
545   EXPECT_EQ(21.0f, stylus_event.pointer_details().force);
546   EXPECT_EQ(45.0f, stylus_event.pointer_details().tilt_x);
547   EXPECT_EQ(-45.0f, stylus_event.pointer_details().tilt_y);
548   EXPECT_EQ(0.0f, stylus_event.pointer_details().radius_x);
549   EXPECT_EQ(0.0f, stylus_event.pointer_details().radius_y);
550   EXPECT_EQ(0.7f, stylus_event.pointer_details().tangential_pressure);
551   EXPECT_EQ(196, stylus_event.pointer_details().twist);
552 
553   ui::MouseEvent stylus_event_copy(stylus_event);
554   EXPECT_EQ(stylus_event.pointer_details(),
555             stylus_event_copy.pointer_details());
556 }
557 
TEST(EventTest,PointerDetailsCustomTouch)558 TEST(EventTest, PointerDetailsCustomTouch) {
559   ui::TouchEvent touch_event(ET_TOUCH_PRESSED, gfx::Point(0, 0),
560                              ui::EventTimeForNow(),
561                              PointerDetails(ui::EventPointerType::kTouch, 0));
562 
563   EXPECT_EQ(EventPointerType::kTouch,
564             touch_event.pointer_details().pointer_type);
565   EXPECT_EQ(0.0f, touch_event.pointer_details().radius_x);
566   EXPECT_EQ(0.0f, touch_event.pointer_details().radius_y);
567   EXPECT_TRUE(std::isnan(touch_event.pointer_details().force));
568   EXPECT_EQ(0.0f, touch_event.pointer_details().tilt_x);
569   EXPECT_EQ(0.0f, touch_event.pointer_details().tilt_y);
570 
571   ui::PointerDetails pointer_details(EventPointerType::kPen,
572                                      /* pointer_id*/ 0,
573                                      /* radius_x */ 5.0f,
574                                      /* radius_y */ 6.0f,
575                                      /* force */ 21.0f,
576                                      /* twist */ 196,
577                                      /* tilt_x */ 45.0f,
578                                      /* tilt_y */ -45.0f,
579                                      /* tangential_pressure */ 0.7f);
580   touch_event.SetPointerDetailsForTest(pointer_details);
581 
582   EXPECT_EQ(EventPointerType::kPen, touch_event.pointer_details().pointer_type);
583   EXPECT_EQ(21.0f, touch_event.pointer_details().force);
584   EXPECT_EQ(45.0f, touch_event.pointer_details().tilt_x);
585   EXPECT_EQ(-45.0f, touch_event.pointer_details().tilt_y);
586   EXPECT_EQ(5.0f, touch_event.pointer_details().radius_x);
587   EXPECT_EQ(6.0f, touch_event.pointer_details().radius_y);
588   EXPECT_EQ(0.7f, touch_event.pointer_details().tangential_pressure);
589   EXPECT_EQ(196, touch_event.pointer_details().twist);
590 
591   ui::TouchEvent touch_event_copy(touch_event);
592   EXPECT_EQ(touch_event.pointer_details(), touch_event_copy.pointer_details());
593 }
594 
TEST(EventTest,MouseEventLatencyUIComponentExists)595 TEST(EventTest, MouseEventLatencyUIComponentExists) {
596   const gfx::Point origin(0, 0);
597   MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
598   EXPECT_TRUE(mouseev.latency()->FindLatency(
599       ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
600 }
601 
TEST(EventTest,MouseWheelEventLatencyUIComponentExists)602 TEST(EventTest, MouseWheelEventLatencyUIComponentExists) {
603   const gfx::Point origin(0, 0);
604   MouseWheelEvent mouseWheelev(gfx::Vector2d(), origin, origin,
605                                EventTimeForNow(), 0, 0);
606   EXPECT_TRUE(mouseWheelev.latency()->FindLatency(
607       ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
608 }
609 
TEST(EventTest,MouseWheelEventLinearTickCalculation)610 TEST(EventTest, MouseWheelEventLinearTickCalculation) {
611   const gfx::Point origin;
612   MouseWheelEvent mouse_wheel_ev(
613       gfx::Vector2d(-2 * MouseWheelEvent::kWheelDelta,
614                     MouseWheelEvent::kWheelDelta),
615       origin, origin, EventTimeForNow(), 0, 0);
616   EXPECT_EQ(mouse_wheel_ev.tick_120ths().x(), -240);
617   EXPECT_EQ(mouse_wheel_ev.tick_120ths().y(), 120);
618 }
619 
TEST(EventTest,OrdinalMotionConversion)620 TEST(EventTest, OrdinalMotionConversion) {
621   const gfx::Point origin(0, 0);
622   const gfx::Vector2dF movement(2.67, 3.14);
623 
624   // Model conversion depends on the class having a specific static method.
625   struct OrdinalMotionConversionModel {
626     static void ConvertPointToTarget(const OrdinalMotionConversionModel*,
627                                      const OrdinalMotionConversionModel*,
628                                      gfx::Point*) {
629       // Do nothing.
630     }
631   } src, dst;
632 
633   MouseEvent mouseev1(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0,
634                       0);
635   MouseEvent::DispatcherApi(&mouseev1).set_movement(movement);
636   EXPECT_EQ(mouseev1.movement(), movement);
637   EXPECT_TRUE(mouseev1.flags() & EF_UNADJUSTED_MOUSE);
638 
639   MouseEvent mouseev2(mouseev1, &src, &dst);
640   EXPECT_EQ(mouseev2.movement(), movement);
641   EXPECT_TRUE(mouseev2.flags() & EF_UNADJUSTED_MOUSE);
642 
643   // Setting the flags in construction should override the model's.
644   MouseEvent mouseev3(mouseev1, &src, &dst, EventType::ET_MOUSE_MOVED,
645                       /* flags */ 0);
646   EXPECT_EQ(mouseev3.movement(), movement);
647   EXPECT_FALSE(mouseev3.flags() & EF_UNADJUSTED_MOUSE);
648 }
649 
650 // Checks that Event.Latency.OS.MOUSE_WHEEL histogram is computed properly.
TEST(EventTest,EventLatencyOSMouseWheelHistogram)651 TEST(EventTest, EventLatencyOSMouseWheelHistogram) {
652 #if defined(OS_WIN)
653   base::HistogramTester histogram_tester;
654   MSG event = {nullptr, WM_MOUSEWHEEL, 0, 0};
655   MouseWheelEvent mouseWheelEvent(event);
656   histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1);
657 #endif
658 }
659 
TEST(EventTest,UpdateForRootTransformation)660 TEST(EventTest, UpdateForRootTransformation) {
661   gfx::Transform identity_transform;
662   const gfx::Point location(10, 10);
663   const gfx::Point root_location(20, 20);
664 
665   // A mouse event that is untargeted should reset the root location when
666   // transformed. Though the events start out with different locations and
667   // root_locations, they should be equal afterwards.
668   ui::MouseEvent untargeted(ET_MOUSE_PRESSED, location, root_location,
669                             EventTimeForNow(), 0, 0);
670   untargeted.UpdateForRootTransform(identity_transform, identity_transform);
671   EXPECT_EQ(location, untargeted.location());
672   EXPECT_EQ(location, untargeted.root_location());
673 
674   ui::test::TestEventTarget target;
675 
676   // A mouse event that is targeted should not set the root location to the
677   // local location. They start with different locations and should stay
678   // unequal after a transform is applied.
679   {
680     ui::MouseEvent targeted(ET_MOUSE_PRESSED, location, root_location,
681                             EventTimeForNow(), 0, 0);
682     Event::DispatcherApi(&targeted).set_target(&target);
683     targeted.UpdateForRootTransform(identity_transform, identity_transform);
684     EXPECT_EQ(location, targeted.location());
685     EXPECT_EQ(root_location, targeted.root_location());
686   }
687 
688   {
689     // Targeted event with 2x and 3x scales.
690     gfx::Transform transform2x;
691     transform2x.Scale(2, 2);
692     gfx::Transform transform3x;
693     transform3x.Scale(3, 3);
694     ui::MouseEvent targeted(ET_MOUSE_PRESSED, location, root_location,
695                             EventTimeForNow(), 0, 0);
696     Event::DispatcherApi(&targeted).set_target(&target);
697     targeted.UpdateForRootTransform(transform2x, transform3x);
698     EXPECT_EQ(gfx::Point(30, 30), targeted.location());
699     EXPECT_EQ(gfx::Point(40, 40), targeted.root_location());
700   }
701 }
702 
TEST(EventTest,OperatorEqual)703 TEST(EventTest, OperatorEqual) {
704   MouseEvent m1(ET_MOUSE_PRESSED, gfx::Point(1, 2), gfx::Point(2, 3),
705                 EventTimeForNow(), EF_LEFT_MOUSE_BUTTON, EF_RIGHT_MOUSE_BUTTON);
706   base::flat_map<std::string, std::vector<uint8_t>> properties;
707   properties["a"] = {1u};
708   m1.SetProperties(properties);
709   EXPECT_EQ(properties, *(m1.properties()));
710   MouseEvent m2(ET_MOUSE_RELEASED, gfx::Point(11, 21), gfx::Point(2, 2),
711                 EventTimeForNow(), EF_RIGHT_MOUSE_BUTTON, EF_LEFT_MOUSE_BUTTON);
712   m2 = m1;
713   ASSERT_TRUE(m2.properties());
714   EXPECT_EQ(properties, *(m2.properties()));
715 }
716 
717 // Verifies that ToString() generates something and doesn't crash. The specific
718 // format isn't important.
TEST(EventTest,ToStringNotEmpty)719 TEST(EventTest, ToStringNotEmpty) {
720   MouseEvent mouse_event(ET_MOUSE_PRESSED, gfx::Point(1, 2), gfx::Point(2, 3),
721                          EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
722                          EF_RIGHT_MOUSE_BUTTON);
723   EXPECT_FALSE(mouse_event.ToString().empty());
724 
725   ScrollEvent scroll_event(ET_SCROLL, gfx::Point(1, 2), EventTimeForNow(),
726                            EF_NONE, 1.f, 2.f, 3.f, 4.f, 1);
727   EXPECT_FALSE(scroll_event.ToString().empty());
728 }
729 
730 #if defined(OS_WIN)
731 namespace {
732 
733 const struct AltGraphEventTestCase {
734   KeyboardCode key_code;
735   KeyboardLayout layout;
736   std::vector<KeyboardCode> modifier_key_codes;
737   int expected_flags;
738 } kAltGraphEventTestCases[] = {
739     // US English -> AltRight never behaves as AltGraph.
740     {VKEY_C,
741      KEYBOARD_LAYOUT_ENGLISH_US,
742      {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
743      EF_ALT_DOWN | EF_CONTROL_DOWN},
744     {VKEY_E,
745      KEYBOARD_LAYOUT_ENGLISH_US,
746      {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
747      EF_ALT_DOWN | EF_CONTROL_DOWN},
748 
749     // French -> Always expect AltGraph if VKEY_RMENU is pressed.
750     {VKEY_C,
751      KEYBOARD_LAYOUT_FRENCH,
752      {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
753      EF_ALTGR_DOWN},
754     {VKEY_E,
755      KEYBOARD_LAYOUT_FRENCH,
756      {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
757      EF_ALTGR_DOWN},
758 
759     // French -> Expect Control+Alt is AltGraph on AltGraph-shifted keys.
760     {VKEY_C,
761      KEYBOARD_LAYOUT_FRENCH,
762      {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
763      EF_ALT_DOWN | EF_CONTROL_DOWN},
764     {VKEY_E,
765      KEYBOARD_LAYOUT_FRENCH,
766      {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
767      EF_ALTGR_DOWN},
768 };
769 
770 class AltGraphEventTest
771     : public testing::TestWithParam<std::tuple<UINT, AltGraphEventTestCase>> {
772  public:
AltGraphEventTest()773   AltGraphEventTest()
774       : msg_({nullptr, message_type(),
775               static_cast<WPARAM>(test_case().key_code)}) {
776     // Save the current keyboard layout and state, to restore later.
777     CHECK(GetKeyboardState(original_keyboard_state_));
778     original_keyboard_layout_ = GetKeyboardLayout(0);
779 
780     // Configure specified layout, and update keyboard state for specified
781     // modifier keys.
782     CHECK(ActivateKeyboardLayout(GetPlatformKeyboardLayout(test_case().layout),
783                                  0));
784     BYTE test_keyboard_state[256] = {};
785     for (const auto& key_code : test_case().modifier_key_codes)
786       test_keyboard_state[key_code] = 0x80;
787     CHECK(SetKeyboardState(test_keyboard_state));
788   }
789 
~AltGraphEventTest()790   ~AltGraphEventTest() {
791     // Restore the original keyboard layout & key states.
792     CHECK(ActivateKeyboardLayout(original_keyboard_layout_, 0));
793     CHECK(SetKeyboardState(original_keyboard_state_));
794   }
795 
796  protected:
message_type() const797   UINT message_type() const { return std::get<0>(GetParam()); }
test_case() const798   const AltGraphEventTestCase& test_case() const {
799     return std::get<1>(GetParam());
800   }
801 
802   const MSG msg_;
803   BYTE original_keyboard_state_[256] = {};
804   HKL original_keyboard_layout_ = nullptr;
805 };
806 
807 }  // namespace
808 
TEST_P(AltGraphEventTest,KeyEventAltGraphModifer)809 TEST_P(AltGraphEventTest, KeyEventAltGraphModifer) {
810   KeyEvent event(msg_);
811   if (message_type() == WM_CHAR) {
812     // By definition, if we receive a WM_CHAR message when Control and Alt are
813     // pressed, it indicates AltGraph.
814     EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
815               EF_ALTGR_DOWN);
816   } else {
817     EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
818               test_case().expected_flags);
819   }
820 }
821 
822 INSTANTIATE_TEST_SUITE_P(
823     WM_KEY,
824     AltGraphEventTest,
825     ::testing::Combine(::testing::Values(WM_KEYDOWN, WM_KEYUP),
826                        ::testing::ValuesIn(kAltGraphEventTestCases)));
827 INSTANTIATE_TEST_SUITE_P(
828     WM_CHAR,
829     AltGraphEventTest,
830     ::testing::Combine(::testing::Values(WM_CHAR),
831                        ::testing::ValuesIn(kAltGraphEventTestCases)));
832 
833 #endif  // defined(OS_WIN)
834 
835 }  // namespace ui
836