event_unittest.cc 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  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. #include "ui/events/event.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <limits>
  8. #include <memory>
  9. #include <string>
  10. #include "base/callback_helpers.h"
  11. #include "base/strings/strcat.h"
  12. #include "base/test/metrics/histogram_tester.h"
  13. #include "base/test/simple_test_tick_clock.h"
  14. #include "base/test/task_environment.h"
  15. #include "build/build_config.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. #include "ui/base/ui_base_features.h"
  18. #include "ui/events/event_constants.h"
  19. #include "ui/events/event_utils.h"
  20. #include "ui/events/keycodes/dom/dom_code.h"
  21. #include "ui/events/keycodes/dom/keycode_converter.h"
  22. #include "ui/events/keycodes/keyboard_code_conversion.h"
  23. #include "ui/events/test/events_test_utils.h"
  24. #include "ui/events/test/keyboard_layout.h"
  25. #include "ui/events/test/test_event_target.h"
  26. #include "ui/gfx/geometry/transform.h"
  27. #if BUILDFLAG(IS_WIN)
  28. #include "ui/events/win/events_win_utils.h"
  29. #endif
  30. namespace ui {
  31. TEST(EventTest, NoNativeEvent) {
  32. KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
  33. EXPECT_FALSE(keyev.HasNativeEvent());
  34. }
  35. TEST(EventTest, NativeEvent) {
  36. #if BUILDFLAG(IS_WIN)
  37. CHROME_MSG native_event = {nullptr, WM_KEYUP, VKEY_A, 0};
  38. KeyEvent keyev(native_event);
  39. EXPECT_TRUE(keyev.HasNativeEvent());
  40. #endif
  41. }
  42. TEST(EventTest, GetCharacter) {
  43. ui::ScopedKeyboardLayout keyboard_layout(ui::KEYBOARD_LAYOUT_ENGLISH_US);
  44. // Check if Control+Enter returns 10.
  45. KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
  46. EXPECT_EQ(10, keyev1.GetCharacter());
  47. // Check if Enter returns 13.
  48. KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
  49. EXPECT_EQ(13, keyev2.GetCharacter());
  50. // Check if expected Unicode character was returned for a key combination
  51. // contains Control.
  52. // e.g. Control+Shift+2 produces U+200C on "Persian" keyboard.
  53. // http://crbug.com/582453
  54. KeyEvent keyev5(0x200C, VKEY_UNKNOWN, ui::DomCode::NONE,
  55. EF_CONTROL_DOWN | EF_SHIFT_DOWN);
  56. EXPECT_EQ(0x200C, keyev5.GetCharacter());
  57. }
  58. TEST(EventTest, ClickCount) {
  59. const gfx::Point origin(0, 0);
  60. MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  61. for (int i = 1; i <= 3; ++i) {
  62. mouseev.SetClickCount(i);
  63. EXPECT_EQ(i, mouseev.GetClickCount());
  64. }
  65. }
  66. TEST(EventTest, RepeatedClick) {
  67. const gfx::Point origin(0, 0);
  68. MouseEvent event1(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  69. MouseEvent event2(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  70. LocatedEventTestApi test_event1(&event1);
  71. LocatedEventTestApi test_event2(&event2);
  72. base::TimeTicks start = base::TimeTicks::Now();
  73. base::TimeTicks soon = start + base::Milliseconds(1);
  74. base::TimeTicks later = start + base::Milliseconds(1000);
  75. // Same time stamp (likely the same native event).
  76. test_event1.set_location(gfx::Point(0, 0));
  77. test_event2.set_location(gfx::Point(1, 0));
  78. test_event1.set_time_stamp(start);
  79. test_event2.set_time_stamp(start);
  80. EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
  81. MouseEvent mouse_ev3(event1);
  82. EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, mouse_ev3));
  83. // Close point.
  84. test_event1.set_location(gfx::Point(0, 0));
  85. test_event2.set_location(gfx::Point(1, 0));
  86. test_event1.set_time_stamp(start);
  87. test_event2.set_time_stamp(soon);
  88. EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(event1, event2));
  89. // Too far.
  90. test_event1.set_location(gfx::Point(0, 0));
  91. test_event2.set_location(gfx::Point(10, 0));
  92. test_event1.set_time_stamp(start);
  93. test_event2.set_time_stamp(soon);
  94. EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
  95. // Too long a time between clicks.
  96. test_event1.set_location(gfx::Point(0, 0));
  97. test_event2.set_location(gfx::Point(0, 0));
  98. test_event1.set_time_stamp(start);
  99. test_event2.set_time_stamp(later);
  100. EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
  101. }
  102. // Automatic repeat flag setting is disabled on Lacros,
  103. // because the repeated event is generated inside ui/ozone/platform/wayland
  104. // and reliable.
  105. TEST(EventTest, RepeatedKeyEvent) {
  106. base::TimeTicks start = base::TimeTicks::Now();
  107. base::TimeTicks time1 = start + base::Milliseconds(1);
  108. base::TimeTicks time2 = start + base::Milliseconds(2);
  109. base::TimeTicks time3 = start + base::Milliseconds(3);
  110. KeyEvent event1(ET_KEY_PRESSED, VKEY_A, 0, start);
  111. KeyEvent event2(ET_KEY_PRESSED, VKEY_A, 0, time1);
  112. KeyEvent event3(ET_KEY_PRESSED, VKEY_A, EF_LEFT_MOUSE_BUTTON, time2);
  113. KeyEvent event4(ET_KEY_PRESSED, VKEY_A, 0, time3);
  114. event1.InitializeNative();
  115. EXPECT_EQ(event1.flags() & EF_IS_REPEAT, 0);
  116. event2.InitializeNative();
  117. EXPECT_NE(event2.flags() & EF_IS_REPEAT, 0);
  118. event3.InitializeNative();
  119. EXPECT_NE(event3.flags() & EF_IS_REPEAT, 0);
  120. event4.InitializeNative();
  121. EXPECT_NE(event4.flags() & EF_IS_REPEAT, 0);
  122. }
  123. TEST(EventTest, NoRepeatedKeyEvent) {
  124. // Temporarily set the global synthesize_key_repeat_enabled to false.
  125. base::ScopedClosureRunner runner(base::BindOnce(
  126. [](bool old_value) {
  127. KeyEvent::SetSynthesizeKeyRepeatEnabled(old_value);
  128. },
  129. KeyEvent::IsSynthesizeKeyRepeatEnabled()));
  130. KeyEvent::SetSynthesizeKeyRepeatEnabled(false);
  131. base::TimeTicks start = base::TimeTicks::Now();
  132. base::TimeTicks time1 = start + base::Milliseconds(1);
  133. base::TimeTicks time2 = start + base::Milliseconds(2);
  134. base::TimeTicks time3 = start + base::Milliseconds(3);
  135. KeyEvent event1(ET_KEY_PRESSED, VKEY_A, 0, start);
  136. KeyEvent event2(ET_KEY_PRESSED, VKEY_A, 0, time1);
  137. KeyEvent event3(ET_KEY_PRESSED, VKEY_A, EF_LEFT_MOUSE_BUTTON, time2);
  138. KeyEvent event4(ET_KEY_PRESSED, VKEY_A, 0, time3);
  139. event1.InitializeNative();
  140. EXPECT_EQ(event1.flags() & EF_IS_REPEAT, 0);
  141. event2.InitializeNative();
  142. EXPECT_EQ(event2.flags() & EF_IS_REPEAT, 0);
  143. event3.InitializeNative();
  144. EXPECT_EQ(event3.flags() & EF_IS_REPEAT, 0);
  145. event4.InitializeNative();
  146. EXPECT_EQ(event4.flags() & EF_IS_REPEAT, 0);
  147. }
  148. // Tests that re-processing the same mouse press event (detected by timestamp)
  149. // does not yield a double click event: http://crbug.com/389162
  150. TEST(EventTest, DoubleClickRequiresUniqueTimestamp) {
  151. const gfx::Point point(0, 0);
  152. base::TimeTicks time1 = base::TimeTicks::Now();
  153. base::TimeTicks time2 = time1 + base::Milliseconds(1);
  154. // Re-processing the same press doesn't yield a double-click.
  155. MouseEvent event(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  156. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  157. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  158. // Processing a press with the same timestamp doesn't yield a double-click.
  159. event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  160. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  161. // Processing a press with a later timestamp does yield a double-click.
  162. event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2, 0, 0);
  163. EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  164. MouseEvent::ResetLastClickForTest();
  165. // Test processing a double press and release sequence with one timestamp.
  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, time1, 0, 0);
  171. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  172. event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
  173. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  174. MouseEvent::ResetLastClickForTest();
  175. // Test processing a double press and release sequence with two timestamps.
  176. event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  177. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  178. event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
  179. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  180. event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2, 0, 0);
  181. EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  182. event = MouseEvent(ET_MOUSE_RELEASED, point, point, time2, 0, 0);
  183. EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  184. MouseEvent::ResetLastClickForTest();
  185. }
  186. // Tests that right clicking, then left clicking does not yield double clicks.
  187. TEST(EventTest, SingleClickRightLeft) {
  188. const gfx::Point point(0, 0);
  189. base::TimeTicks time1 = base::TimeTicks::Now();
  190. base::TimeTicks time2 = time1 + base::Milliseconds(1);
  191. base::TimeTicks time3 = time1 + base::Milliseconds(2);
  192. MouseEvent event(ET_MOUSE_PRESSED, point, point, time1,
  193. ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON);
  194. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  195. event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2,
  196. ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
  197. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  198. event = MouseEvent(ET_MOUSE_RELEASED, point, point, time2,
  199. ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
  200. EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  201. event = MouseEvent(ET_MOUSE_PRESSED, point, point, time3,
  202. ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
  203. EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  204. MouseEvent::ResetLastClickForTest();
  205. }
  206. TEST(EventTest, KeyEvent) {
  207. ui::ScopedKeyboardLayout keyboard_layout(ui::KEYBOARD_LAYOUT_ENGLISH_US);
  208. static const struct {
  209. KeyboardCode key_code;
  210. int flags;
  211. uint16_t character;
  212. } kTestData[] = {
  213. {VKEY_A, 0, 'a'},
  214. {VKEY_A, EF_SHIFT_DOWN, 'A'},
  215. {VKEY_A, EF_CAPS_LOCK_ON, 'A'},
  216. {VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, 'a'},
  217. {VKEY_A, EF_CONTROL_DOWN, 0x01},
  218. {VKEY_A, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x01'},
  219. {VKEY_Z, 0, 'z'},
  220. {VKEY_Z, EF_SHIFT_DOWN, 'Z'},
  221. {VKEY_Z, EF_CAPS_LOCK_ON, 'Z'},
  222. {VKEY_Z, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, 'z'},
  223. {VKEY_Z, EF_CONTROL_DOWN, '\x1A'},
  224. {VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1A'},
  225. {VKEY_2, EF_CONTROL_DOWN, '\x12'},
  226. {VKEY_2, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0'},
  227. {VKEY_6, EF_CONTROL_DOWN, '\x16'},
  228. {VKEY_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1E'},
  229. {VKEY_OEM_MINUS, EF_CONTROL_DOWN, '\x0D'},
  230. {VKEY_OEM_MINUS, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1F'},
  231. {VKEY_OEM_4, EF_CONTROL_DOWN, '\x1B'},
  232. {VKEY_OEM_4, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1B'},
  233. {VKEY_OEM_5, EF_CONTROL_DOWN, '\x1C'},
  234. {VKEY_OEM_5, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1C'},
  235. {VKEY_OEM_6, EF_CONTROL_DOWN, '\x1D'},
  236. {VKEY_OEM_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1D'},
  237. {VKEY_RETURN, EF_CONTROL_DOWN, '\x0A'},
  238. {VKEY_0, 0, '0'},
  239. {VKEY_0, EF_SHIFT_DOWN, ')'},
  240. {VKEY_0, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, ')'},
  241. {VKEY_0, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x09'},
  242. {VKEY_9, 0, '9'},
  243. {VKEY_9, EF_SHIFT_DOWN, '('},
  244. {VKEY_9, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, '('},
  245. {VKEY_9, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x08'},
  246. {VKEY_NUMPAD0, EF_CONTROL_DOWN, '\x10'},
  247. {VKEY_NUMPAD0, EF_SHIFT_DOWN, '0'},
  248. {VKEY_NUMPAD9, EF_CONTROL_DOWN, '\x19'},
  249. {VKEY_NUMPAD9, EF_SHIFT_DOWN, '9'},
  250. {VKEY_TAB, EF_NONE, '\t'},
  251. {VKEY_TAB, EF_CONTROL_DOWN, '\t'},
  252. {VKEY_TAB, EF_SHIFT_DOWN, '\t'},
  253. {VKEY_MULTIPLY, EF_CONTROL_DOWN, '\x0A'},
  254. {VKEY_MULTIPLY, EF_SHIFT_DOWN, '*'},
  255. {VKEY_ADD, EF_CONTROL_DOWN, '\x0B'},
  256. {VKEY_ADD, EF_SHIFT_DOWN, '+'},
  257. {VKEY_SUBTRACT, EF_CONTROL_DOWN, '\x0D'},
  258. {VKEY_SUBTRACT, EF_SHIFT_DOWN, '-'},
  259. {VKEY_DECIMAL, EF_CONTROL_DOWN, '\x0E'},
  260. {VKEY_DECIMAL, EF_SHIFT_DOWN, '.'},
  261. {VKEY_DIVIDE, EF_CONTROL_DOWN, '\x0F'},
  262. {VKEY_DIVIDE, EF_SHIFT_DOWN, '/'},
  263. {VKEY_OEM_1, EF_CONTROL_DOWN, '\x1B'},
  264. {VKEY_OEM_1, EF_SHIFT_DOWN, ':'},
  265. {VKEY_OEM_PLUS, EF_CONTROL_DOWN, '\x1D'},
  266. {VKEY_OEM_PLUS, EF_SHIFT_DOWN, '+'},
  267. {VKEY_OEM_COMMA, EF_CONTROL_DOWN, '\x0C'},
  268. {VKEY_OEM_COMMA, EF_SHIFT_DOWN, '<'},
  269. {VKEY_OEM_PERIOD, EF_CONTROL_DOWN, '\x0E'},
  270. {VKEY_OEM_PERIOD, EF_SHIFT_DOWN, '>'},
  271. {VKEY_OEM_3, EF_CONTROL_DOWN, '\x0'},
  272. {VKEY_OEM_3, EF_SHIFT_DOWN, '~'},
  273. };
  274. for (size_t i = 0; i < std::size(kTestData); ++i) {
  275. KeyEvent key(ET_KEY_PRESSED, kTestData[i].key_code, kTestData[i].flags);
  276. EXPECT_EQ(kTestData[i].character, key.GetCharacter())
  277. << " Index:" << i << " key_code:" << kTestData[i].key_code;
  278. }
  279. }
  280. TEST(EventTest, KeyEventDirectUnicode) {
  281. KeyEvent key(0x1234U, ui::VKEY_UNKNOWN, ui::DomCode::NONE, ui::EF_NONE);
  282. EXPECT_EQ(0x1234U, key.GetCharacter());
  283. EXPECT_EQ(ET_KEY_PRESSED, key.type());
  284. EXPECT_TRUE(key.is_char());
  285. }
  286. TEST(EventTest, NormalizeKeyEventFlags) {
  287. // Do not normalize flags for synthesized events without
  288. // KeyEvent::NormalizeFlags called explicitly.
  289. {
  290. KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
  291. EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
  292. }
  293. {
  294. KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
  295. EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
  296. keyev.NormalizeFlags();
  297. EXPECT_EQ(EF_NONE, keyev.flags());
  298. }
  299. {
  300. KeyEvent keyev(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
  301. EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
  302. }
  303. {
  304. KeyEvent keyev(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
  305. EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
  306. keyev.NormalizeFlags();
  307. EXPECT_EQ(EF_NONE, keyev.flags());
  308. }
  309. {
  310. KeyEvent keyev(ET_KEY_PRESSED, VKEY_MENU, EF_ALT_DOWN);
  311. EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
  312. }
  313. {
  314. KeyEvent keyev(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
  315. EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
  316. keyev.NormalizeFlags();
  317. EXPECT_EQ(EF_NONE, keyev.flags());
  318. }
  319. }
  320. TEST(EventTest, KeyEventCopy) {
  321. KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE);
  322. std::unique_ptr<KeyEvent> copied_key(new KeyEvent(key));
  323. EXPECT_EQ(copied_key->type(), key.type());
  324. EXPECT_EQ(copied_key->key_code(), key.key_code());
  325. }
  326. TEST(EventTest, KeyEventCode) {
  327. const DomCode kDomCodeForSpace = DomCode::SPACE;
  328. const char kCodeForSpace[] = "Space";
  329. ASSERT_EQ(kDomCodeForSpace,
  330. ui::KeycodeConverter::CodeStringToDomCode(kCodeForSpace));
  331. const int kNativeCodeSpace =
  332. ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace);
  333. ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace);
  334. ASSERT_EQ(kNativeCodeSpace,
  335. ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace));
  336. {
  337. KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kDomCodeForSpace, EF_NONE);
  338. EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  339. }
  340. {
  341. // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be
  342. // the specified value.
  343. KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kDomCodeForSpace, EF_NONE);
  344. EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  345. }
  346. {
  347. // If the synthetic event is initialized without code, the code is
  348. // determined from the KeyboardCode assuming a US keyboard layout.
  349. KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
  350. EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  351. }
  352. #if BUILDFLAG(IS_WIN)
  353. {
  354. // Test a non extended key.
  355. ASSERT_EQ((kNativeCodeSpace & 0xFF), kNativeCodeSpace);
  356. const LPARAM lParam = GetLParamFromScanCode(kNativeCodeSpace);
  357. CHROME_MSG native_event = {nullptr, WM_KEYUP, VKEY_SPACE, lParam};
  358. KeyEvent key(native_event);
  359. // KeyEvent converts from the native keycode (scan code) to the code.
  360. EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  361. }
  362. {
  363. const char kCodeForHome[] = "Home";
  364. const uint16_t kNativeCodeHome = 0xe047;
  365. // 'Home' is an extended key with 0xe000 bits.
  366. ASSERT_NE((kNativeCodeHome & 0xFF), kNativeCodeHome);
  367. const LPARAM lParam = GetLParamFromScanCode(kNativeCodeHome);
  368. CHROME_MSG native_event = {nullptr, WM_KEYUP, VKEY_HOME, lParam};
  369. KeyEvent key(native_event);
  370. // KeyEvent converts from the native keycode (scan code) to the code.
  371. EXPECT_EQ(kCodeForHome, key.GetCodeString());
  372. }
  373. #endif // BUILDFLAG(IS_WIN)
  374. }
  375. TEST(EventTest, TouchEventRadiusDefaultsToOtherAxis) {
  376. const base::TimeTicks time = base::TimeTicks::Now();
  377. const float non_zero_length1 = 30;
  378. const float non_zero_length2 = 46;
  379. TouchEvent event1(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
  380. PointerDetails(ui::EventPointerType::kTouch,
  381. /* pointer_id*/ 0,
  382. /* radius_x */ non_zero_length1,
  383. /* radius_y */ 0.0f,
  384. /* force */ 0));
  385. EXPECT_EQ(non_zero_length1, event1.pointer_details().radius_x);
  386. EXPECT_EQ(non_zero_length1, event1.pointer_details().radius_y);
  387. TouchEvent event2(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
  388. PointerDetails(ui::EventPointerType::kTouch,
  389. /* pointer_id*/ 0,
  390. /* radius_x */ 0.0f,
  391. /* radius_y */ non_zero_length2,
  392. /* force */ 0));
  393. EXPECT_EQ(non_zero_length2, event2.pointer_details().radius_x);
  394. EXPECT_EQ(non_zero_length2, event2.pointer_details().radius_y);
  395. }
  396. TEST(EventTest, TouchEventRotationAngleFixing) {
  397. const base::TimeTicks time = base::TimeTicks::Now();
  398. const float radius_x = 20;
  399. const float radius_y = 10;
  400. {
  401. const float angle_in_range = 0;
  402. TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
  403. PointerDetails(ui::EventPointerType::kTouch,
  404. /* pointer_id*/ 0, radius_x, radius_y,
  405. /* force */ 0, angle_in_range),
  406. 0);
  407. EXPECT_FLOAT_EQ(angle_in_range, event.ComputeRotationAngle());
  408. }
  409. {
  410. const float angle_in_range = 179.9f;
  411. TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
  412. PointerDetails(ui::EventPointerType::kTouch,
  413. /* pointer_id*/ 0, radius_x, radius_y,
  414. /* force */ 0, angle_in_range),
  415. 0);
  416. EXPECT_FLOAT_EQ(angle_in_range, event.ComputeRotationAngle());
  417. }
  418. {
  419. const float angle_negative = -0.1f;
  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_negative),
  424. 0);
  425. EXPECT_FLOAT_EQ(180 - 0.1f, event.ComputeRotationAngle());
  426. }
  427. {
  428. const float angle_negative = -200;
  429. TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
  430. PointerDetails(ui::EventPointerType::kTouch,
  431. /* pointer_id*/ 0, radius_x, radius_y,
  432. /* force */ 0, angle_negative),
  433. 0);
  434. EXPECT_FLOAT_EQ(360 - 200, event.ComputeRotationAngle());
  435. }
  436. {
  437. const float angle_too_big = 180;
  438. TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
  439. PointerDetails(ui::EventPointerType::kTouch,
  440. /* pointer_id*/ 0, radius_x, radius_y,
  441. /* force */ 0, angle_too_big),
  442. 0);
  443. EXPECT_FLOAT_EQ(0, event.ComputeRotationAngle());
  444. }
  445. {
  446. const float angle_too_big = 400;
  447. TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
  448. PointerDetails(ui::EventPointerType::kTouch,
  449. /* pointer_id*/ 0, radius_x, radius_y,
  450. /* force */ 0, angle_too_big),
  451. 0);
  452. EXPECT_FLOAT_EQ(400 - 360, event.ComputeRotationAngle());
  453. }
  454. }
  455. TEST(EventTest, PointerDetailsTouch) {
  456. ui::TouchEvent touch_event_plain(
  457. ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
  458. PointerDetails(ui::EventPointerType::kTouch, 0));
  459. EXPECT_EQ(EventPointerType::kTouch,
  460. touch_event_plain.pointer_details().pointer_type);
  461. EXPECT_EQ(0.0f, touch_event_plain.pointer_details().radius_x);
  462. EXPECT_EQ(0.0f, touch_event_plain.pointer_details().radius_y);
  463. EXPECT_TRUE(std::isnan(touch_event_plain.pointer_details().force));
  464. EXPECT_EQ(0.0f, touch_event_plain.pointer_details().tilt_x);
  465. EXPECT_EQ(0.0f, touch_event_plain.pointer_details().tilt_y);
  466. ui::TouchEvent touch_event_with_details(
  467. ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
  468. PointerDetails(ui::EventPointerType::kTouch,
  469. /* pointer_id*/ 0,
  470. /* radius_x */ 10.0f,
  471. /* radius_y */ 5.0f,
  472. /* force */ 15.0f));
  473. EXPECT_EQ(EventPointerType::kTouch,
  474. touch_event_with_details.pointer_details().pointer_type);
  475. EXPECT_EQ(10.0f, touch_event_with_details.pointer_details().radius_x);
  476. EXPECT_EQ(5.0f, touch_event_with_details.pointer_details().radius_y);
  477. EXPECT_EQ(15.0f, touch_event_with_details.pointer_details().force);
  478. EXPECT_EQ(0.0f, touch_event_with_details.pointer_details().tilt_x);
  479. EXPECT_EQ(0.0f, touch_event_with_details.pointer_details().tilt_y);
  480. ui::TouchEvent touch_event_copy(touch_event_with_details);
  481. EXPECT_EQ(touch_event_with_details.pointer_details(),
  482. touch_event_copy.pointer_details());
  483. }
  484. TEST(EventTest, PointerDetailsMouse) {
  485. ui::MouseEvent mouse_event(ET_MOUSE_PRESSED, gfx::Point(0, 0),
  486. gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0);
  487. EXPECT_EQ(EventPointerType::kMouse,
  488. mouse_event.pointer_details().pointer_type);
  489. EXPECT_EQ(0.0f, mouse_event.pointer_details().radius_x);
  490. EXPECT_EQ(0.0f, mouse_event.pointer_details().radius_y);
  491. EXPECT_TRUE(std::isnan(mouse_event.pointer_details().force));
  492. EXPECT_EQ(0.0f, mouse_event.pointer_details().tilt_x);
  493. EXPECT_EQ(0.0f, mouse_event.pointer_details().tilt_y);
  494. ui::MouseEvent mouse_event_copy(mouse_event);
  495. EXPECT_EQ(mouse_event.pointer_details(), mouse_event_copy.pointer_details());
  496. }
  497. TEST(EventTest, PointerDetailsStylus) {
  498. ui::PointerDetails pointer_details(EventPointerType::kPen,
  499. /* pointer_id*/ 0,
  500. /* radius_x */ 0.0f,
  501. /* radius_y */ 0.0f,
  502. /* force */ 21.0f,
  503. /* twist */ 196,
  504. /* tilt_x */ 45.0f,
  505. /* tilt_y */ -45.0f,
  506. /* tangential_pressure */ 0.7f);
  507. ui::MouseEvent stylus_event(ET_MOUSE_PRESSED, gfx::Point(0, 0),
  508. gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0,
  509. pointer_details);
  510. EXPECT_EQ(EventPointerType::kPen,
  511. stylus_event.pointer_details().pointer_type);
  512. EXPECT_EQ(21.0f, stylus_event.pointer_details().force);
  513. EXPECT_EQ(45.0f, stylus_event.pointer_details().tilt_x);
  514. EXPECT_EQ(-45.0f, stylus_event.pointer_details().tilt_y);
  515. EXPECT_EQ(0.0f, stylus_event.pointer_details().radius_x);
  516. EXPECT_EQ(0.0f, stylus_event.pointer_details().radius_y);
  517. EXPECT_EQ(0.7f, stylus_event.pointer_details().tangential_pressure);
  518. EXPECT_EQ(196, stylus_event.pointer_details().twist);
  519. ui::MouseEvent stylus_event_copy(stylus_event);
  520. EXPECT_EQ(stylus_event.pointer_details(),
  521. stylus_event_copy.pointer_details());
  522. }
  523. TEST(EventTest, PointerDetailsCustomTouch) {
  524. ui::TouchEvent touch_event(ET_TOUCH_PRESSED, gfx::Point(0, 0),
  525. ui::EventTimeForNow(),
  526. PointerDetails(ui::EventPointerType::kTouch, 0));
  527. EXPECT_EQ(EventPointerType::kTouch,
  528. touch_event.pointer_details().pointer_type);
  529. EXPECT_EQ(0.0f, touch_event.pointer_details().radius_x);
  530. EXPECT_EQ(0.0f, touch_event.pointer_details().radius_y);
  531. EXPECT_TRUE(std::isnan(touch_event.pointer_details().force));
  532. EXPECT_EQ(0.0f, touch_event.pointer_details().tilt_x);
  533. EXPECT_EQ(0.0f, touch_event.pointer_details().tilt_y);
  534. ui::PointerDetails pointer_details(EventPointerType::kPen,
  535. /* pointer_id*/ 0,
  536. /* radius_x */ 5.0f,
  537. /* radius_y */ 6.0f,
  538. /* force */ 21.0f,
  539. /* twist */ 196,
  540. /* tilt_x */ 45.0f,
  541. /* tilt_y */ -45.0f,
  542. /* tangential_pressure */ 0.7f);
  543. touch_event.SetPointerDetailsForTest(pointer_details);
  544. EXPECT_EQ(EventPointerType::kPen, touch_event.pointer_details().pointer_type);
  545. EXPECT_EQ(21.0f, touch_event.pointer_details().force);
  546. EXPECT_EQ(45.0f, touch_event.pointer_details().tilt_x);
  547. EXPECT_EQ(-45.0f, touch_event.pointer_details().tilt_y);
  548. EXPECT_EQ(5.0f, touch_event.pointer_details().radius_x);
  549. EXPECT_EQ(6.0f, touch_event.pointer_details().radius_y);
  550. EXPECT_EQ(0.7f, touch_event.pointer_details().tangential_pressure);
  551. EXPECT_EQ(196, touch_event.pointer_details().twist);
  552. ui::TouchEvent touch_event_copy(touch_event);
  553. EXPECT_EQ(touch_event.pointer_details(), touch_event_copy.pointer_details());
  554. }
  555. TEST(EventTest, MouseEventLatencyUIComponentExists) {
  556. const gfx::Point origin(0, 0);
  557. MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  558. EXPECT_TRUE(mouseev.latency()->FindLatency(
  559. ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
  560. }
  561. TEST(EventTest, MouseWheelEventLatencyUIComponentExists) {
  562. const gfx::Point origin(0, 0);
  563. MouseWheelEvent mouseWheelev(gfx::Vector2d(), origin, origin,
  564. EventTimeForNow(), 0, 0);
  565. EXPECT_TRUE(mouseWheelev.latency()->FindLatency(
  566. ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
  567. }
  568. TEST(EventTest, MouseWheelEventLinearTickCalculation) {
  569. const gfx::Point origin;
  570. MouseWheelEvent mouse_wheel_ev(
  571. gfx::Vector2d(-2 * MouseWheelEvent::kWheelDelta,
  572. MouseWheelEvent::kWheelDelta),
  573. origin, origin, EventTimeForNow(), 0, 0);
  574. EXPECT_EQ(mouse_wheel_ev.tick_120ths().x(), -240);
  575. EXPECT_EQ(mouse_wheel_ev.tick_120ths().y(), 120);
  576. }
  577. TEST(EventTest, OrdinalMotionConversion) {
  578. const gfx::Point origin(0, 0);
  579. const gfx::Vector2dF movement(2.67, 3.14);
  580. // Model conversion depends on the class having a specific static method.
  581. struct OrdinalMotionConversionModel {
  582. static void ConvertPointToTarget(const OrdinalMotionConversionModel*,
  583. const OrdinalMotionConversionModel*,
  584. gfx::Point*) {
  585. // Do nothing.
  586. }
  587. } src, dst;
  588. MouseEvent mouseev1(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0,
  589. 0);
  590. MouseEvent::DispatcherApi(&mouseev1).set_movement(movement);
  591. EXPECT_EQ(mouseev1.movement(), movement);
  592. EXPECT_TRUE(mouseev1.flags() & EF_UNADJUSTED_MOUSE);
  593. MouseEvent mouseev2(mouseev1, &src, &dst);
  594. EXPECT_EQ(mouseev2.movement(), movement);
  595. EXPECT_TRUE(mouseev2.flags() & EF_UNADJUSTED_MOUSE);
  596. // Setting the flags in construction should override the model's.
  597. MouseEvent mouseev3(mouseev1, &src, &dst, EventType::ET_MOUSE_MOVED,
  598. /* flags */ 0);
  599. EXPECT_EQ(mouseev3.movement(), movement);
  600. EXPECT_FALSE(mouseev3.flags() & EF_UNADJUSTED_MOUSE);
  601. }
  602. // Checks that Event.Latency.OS2.MOUSE_WHEEL histogram is computed properly.
  603. TEST(EventTest, EventLatencyOSMouseWheelHistogram) {
  604. #if BUILDFLAG(IS_WIN)
  605. base::HistogramTester histogram_tester;
  606. CHROME_MSG event = {nullptr, WM_MOUSEWHEEL, 0, 0};
  607. MouseWheelEvent mouseWheelEvent(event);
  608. histogram_tester.ExpectTotalCount("Event.Latency.OS2.MOUSE_WHEEL", 1);
  609. #endif
  610. }
  611. TEST(EventTest, UpdateForRootTransformation) {
  612. gfx::Transform identity_transform;
  613. const gfx::Point location(10, 10);
  614. const gfx::Point root_location(20, 20);
  615. const gfx::PointF f_location(10, 10);
  616. const gfx::PointF f_root_location(20, 20);
  617. // A mouse event that is untargeted should reset the root location when
  618. // transformed. Though the events start out with different locations and
  619. // root_locations, they should be equal afterwards.
  620. ui::MouseEvent untargeted(ET_MOUSE_PRESSED, location, root_location,
  621. EventTimeForNow(), 0, 0);
  622. untargeted.UpdateForRootTransform(identity_transform, identity_transform);
  623. EXPECT_EQ(location, untargeted.location());
  624. EXPECT_EQ(location, untargeted.root_location());
  625. ui::test::TestEventTarget target;
  626. // A touch event should behave the same way as others.
  627. {
  628. PointerDetails pointer_details(EventPointerType::kTouch, 0 /* pointer id */,
  629. 3, 4, 50, 0 /* twist */, 0, 0);
  630. ui::TouchEvent targeted(ET_TOUCH_PRESSED, f_location, f_root_location,
  631. EventTimeForNow(), pointer_details);
  632. targeted.UpdateForRootTransform(identity_transform, identity_transform);
  633. EXPECT_EQ(location, targeted.location());
  634. EXPECT_EQ(location, targeted.root_location());
  635. EXPECT_EQ(pointer_details, targeted.pointer_details());
  636. }
  637. // A touch event should scale the same way as others.
  638. {
  639. // Targeted event with 2x and 3x scales.
  640. gfx::Transform transform2x;
  641. transform2x.Scale(2, 2);
  642. gfx::Transform transform3x;
  643. transform3x.Scale(3, 3);
  644. PointerDetails pointer_details(EventPointerType::kTouch, 0 /* pointer id */,
  645. 3, 4, 50, 0 /* twist */, 17.2 /* tilt_x */,
  646. -28.3 /* tilt_y */);
  647. ui::TouchEvent targeted(ET_TOUCH_PRESSED, f_location, f_root_location,
  648. EventTimeForNow(), pointer_details);
  649. targeted.UpdateForRootTransform(transform2x, transform3x);
  650. auto updated_location = ScalePoint(f_location, 2.0f);
  651. EXPECT_EQ(updated_location, targeted.location_f());
  652. EXPECT_EQ(updated_location, targeted.root_location_f());
  653. auto updated_pointer_details(pointer_details);
  654. updated_pointer_details.radius_x *= 2;
  655. updated_pointer_details.radius_y *= 2;
  656. EXPECT_EQ(updated_pointer_details, targeted.pointer_details())
  657. << " orig: " << pointer_details.ToString() << " vs "
  658. << targeted.pointer_details().ToString();
  659. }
  660. // A touch event should rotate appropriately.
  661. {
  662. // Rotate by 90 degrees, then scale by a half or 0.75 (depending on axis),
  663. // and then offset by 720/1080. Note that the offset should have no impact
  664. // on vectors, i.e. radius.
  665. // The scale happens after rotation, so x should be 0.75 * the y.
  666. gfx::Transform rotate90;
  667. rotate90.Rotate(90.0f);
  668. rotate90.Translate(gfx::Vector2dF(720.0f, 1080.0f));
  669. rotate90.Scale(0.5, 0.75);
  670. gfx::Transform transform3x;
  671. transform3x.Scale(3, 3);
  672. PointerDetails pointer_details(EventPointerType::kTouch, 0 /* pointer id */,
  673. 3, 4, 50, 0 /* twist */, -17.4 /* tilt_x */,
  674. 31.2 /* tilt_y */);
  675. ui::TouchEvent targeted(ET_TOUCH_PRESSED, f_location, f_root_location,
  676. EventTimeForNow(), pointer_details);
  677. Event::DispatcherApi(&targeted).set_target(&target);
  678. targeted.UpdateForRootTransform(rotate90, transform3x);
  679. auto updated_pointer_details(pointer_details);
  680. updated_pointer_details.radius_x = pointer_details.radius_y * 0.75;
  681. updated_pointer_details.radius_y = pointer_details.radius_x * 0.5;
  682. updated_pointer_details.tilt_x = -31.2;
  683. updated_pointer_details.tilt_y = -17.4;
  684. EXPECT_EQ(updated_pointer_details, targeted.pointer_details())
  685. << " orig: " << updated_pointer_details.ToString() << " vs "
  686. << targeted.pointer_details().ToString();
  687. }
  688. // A mouse event that is targeted should not set the root location to the
  689. // local location. They start with different locations and should stay
  690. // unequal after a transform is applied.
  691. {
  692. ui::MouseEvent targeted(ET_MOUSE_PRESSED, location, root_location,
  693. EventTimeForNow(), 0, 0);
  694. Event::DispatcherApi(&targeted).set_target(&target);
  695. targeted.UpdateForRootTransform(identity_transform, identity_transform);
  696. EXPECT_EQ(location, targeted.location());
  697. EXPECT_EQ(root_location, targeted.root_location());
  698. }
  699. {
  700. // Targeted event with 2x and 3x scales.
  701. gfx::Transform transform2x;
  702. transform2x.Scale(2, 2);
  703. gfx::Transform transform3x;
  704. transform3x.Scale(3, 3);
  705. ui::MouseEvent targeted(ET_MOUSE_PRESSED, location, root_location,
  706. EventTimeForNow(), 0, 0);
  707. Event::DispatcherApi(&targeted).set_target(&target);
  708. targeted.UpdateForRootTransform(transform2x, transform3x);
  709. EXPECT_EQ(gfx::Point(30, 30), targeted.location());
  710. EXPECT_EQ(gfx::Point(40, 40), targeted.root_location());
  711. }
  712. }
  713. TEST(EventTest, OperatorEqual) {
  714. MouseEvent m1(ET_MOUSE_PRESSED, gfx::Point(1, 2), gfx::Point(2, 3),
  715. EventTimeForNow(), EF_LEFT_MOUSE_BUTTON, EF_RIGHT_MOUSE_BUTTON);
  716. base::flat_map<std::string, std::vector<uint8_t>> properties;
  717. properties["a"] = {1u};
  718. m1.SetProperties(properties);
  719. EXPECT_EQ(properties, *(m1.properties()));
  720. MouseEvent m2(ET_MOUSE_RELEASED, gfx::Point(11, 21), gfx::Point(2, 2),
  721. EventTimeForNow(), EF_RIGHT_MOUSE_BUTTON, EF_LEFT_MOUSE_BUTTON);
  722. m2 = m1;
  723. ASSERT_TRUE(m2.properties());
  724. EXPECT_EQ(properties, *(m2.properties()));
  725. }
  726. // Verifies that ToString() generates something and doesn't crash. The specific
  727. // format isn't important.
  728. TEST(EventTest, ToStringNotEmpty) {
  729. MouseEvent mouse_event(ET_MOUSE_PRESSED, gfx::Point(1, 2), gfx::Point(2, 3),
  730. EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
  731. EF_RIGHT_MOUSE_BUTTON);
  732. EXPECT_FALSE(mouse_event.ToString().empty());
  733. ScrollEvent scroll_event(ET_SCROLL, gfx::Point(1, 2), EventTimeForNow(),
  734. EF_NONE, 1.f, 2.f, 3.f, 4.f, 1);
  735. EXPECT_FALSE(scroll_event.ToString().empty());
  736. }
  737. #if BUILDFLAG(IS_WIN)
  738. namespace {
  739. const struct AltGraphEventTestCase {
  740. KeyboardCode key_code;
  741. KeyboardLayout layout;
  742. std::vector<KeyboardCode> modifier_key_codes;
  743. int expected_flags;
  744. } kAltGraphEventTestCases[] = {
  745. // US English -> AltRight never behaves as AltGraph.
  746. {VKEY_C,
  747. KEYBOARD_LAYOUT_ENGLISH_US,
  748. {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
  749. EF_ALT_DOWN | EF_CONTROL_DOWN},
  750. {VKEY_E,
  751. KEYBOARD_LAYOUT_ENGLISH_US,
  752. {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
  753. EF_ALT_DOWN | EF_CONTROL_DOWN},
  754. // French -> Always expect AltGraph if VKEY_RMENU is pressed.
  755. {VKEY_C,
  756. KEYBOARD_LAYOUT_FRENCH,
  757. {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
  758. EF_ALTGR_DOWN},
  759. {VKEY_E,
  760. KEYBOARD_LAYOUT_FRENCH,
  761. {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
  762. EF_ALTGR_DOWN},
  763. // French -> Expect Control+Alt is AltGraph on AltGraph-shifted keys.
  764. {VKEY_C,
  765. KEYBOARD_LAYOUT_FRENCH,
  766. {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
  767. EF_ALT_DOWN | EF_CONTROL_DOWN},
  768. {VKEY_E,
  769. KEYBOARD_LAYOUT_FRENCH,
  770. {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
  771. EF_ALTGR_DOWN},
  772. };
  773. class AltGraphEventTest
  774. : public testing::TestWithParam<std::tuple<UINT, AltGraphEventTestCase>> {
  775. public:
  776. AltGraphEventTest()
  777. : msg_({nullptr, message_type(),
  778. static_cast<WPARAM>(test_case().key_code)}) {
  779. // Save the current keyboard layout and state, to restore later.
  780. CHECK(GetKeyboardState(original_keyboard_state_));
  781. original_keyboard_layout_ = GetKeyboardLayout(0);
  782. // Configure specified layout, and update keyboard state for specified
  783. // modifier keys.
  784. CHECK(ActivateKeyboardLayout(GetPlatformKeyboardLayout(test_case().layout),
  785. 0));
  786. BYTE test_keyboard_state[256] = {};
  787. for (const auto& key_code : test_case().modifier_key_codes)
  788. test_keyboard_state[key_code] = 0x80;
  789. CHECK(SetKeyboardState(test_keyboard_state));
  790. }
  791. ~AltGraphEventTest() {
  792. // Restore the original keyboard layout & key states.
  793. CHECK(ActivateKeyboardLayout(original_keyboard_layout_, 0));
  794. CHECK(SetKeyboardState(original_keyboard_state_));
  795. }
  796. protected:
  797. UINT message_type() const { return std::get<0>(GetParam()); }
  798. const AltGraphEventTestCase& test_case() const {
  799. return std::get<1>(GetParam());
  800. }
  801. const CHROME_MSG msg_;
  802. BYTE original_keyboard_state_[256] = {};
  803. HKL original_keyboard_layout_ = nullptr;
  804. };
  805. } // namespace
  806. TEST_P(AltGraphEventTest, KeyEventAltGraphModifer) {
  807. KeyEvent event(msg_);
  808. if (message_type() == WM_CHAR) {
  809. // By definition, if we receive a WM_CHAR message when Control and Alt are
  810. // pressed, it indicates AltGraph.
  811. EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
  812. EF_ALTGR_DOWN);
  813. } else {
  814. EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
  815. test_case().expected_flags);
  816. }
  817. }
  818. INSTANTIATE_TEST_SUITE_P(
  819. WM_KEY,
  820. AltGraphEventTest,
  821. ::testing::Combine(::testing::Values(WM_KEYDOWN, WM_KEYUP),
  822. ::testing::ValuesIn(kAltGraphEventTestCases)));
  823. INSTANTIATE_TEST_SUITE_P(
  824. WM_CHAR,
  825. AltGraphEventTest,
  826. ::testing::Combine(::testing::Values(WM_CHAR),
  827. ::testing::ValuesIn(kAltGraphEventTestCases)));
  828. // Tests for ComputeEventLatencyOS variants.
  829. class EventLatencyTest : public ::testing::Test {
  830. public:
  831. EventLatencyTest() { SetEventLatencyTickClockForTesting(&tick_clock_); }
  832. ~EventLatencyTest() override { SetEventLatencyTickClockForTesting(nullptr); }
  833. protected:
  834. void UpdateTickClock(DWORD timestamp) {
  835. tick_clock_.SetNowTicks(base::TimeTicks() + base::Milliseconds(timestamp));
  836. }
  837. base::test::TaskEnvironment task_environment_{
  838. base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  839. // |task_environment_| mocks the base::TimeTicks clock while |tick_clock_|
  840. // mocks ::GetTickCount.
  841. base::SimpleTestTickClock tick_clock_;
  842. };
  843. TEST_F(EventLatencyTest, ComputeEventLatencyOSFromTickCount) {
  844. // Create events whose timestamps are very close to the max range of
  845. // ::GetTickCount.
  846. constexpr DWORD timestamp_msec = std::numeric_limits<DWORD>::max() - 10;
  847. constexpr TOUCHINPUT touch_input = {
  848. .dwTime = timestamp_msec,
  849. };
  850. constexpr POINTER_INFO pointer_info = {
  851. .dwTime = timestamp_msec,
  852. .PerformanceCount = 0UL,
  853. };
  854. // This test will create several events with the same timestamp, and change
  855. // the mocked result of ::GetTickCount for each measurement. This makes it
  856. // easier to test the edge case when the 32-bit ::GetTickCount overflows.
  857. // Measure the latency of an event that's processed not long after the OS
  858. // timestamp.
  859. UpdateTickClock(timestamp_msec + 5);
  860. {
  861. base::HistogramTester histogram_tester;
  862. ComputeEventLatencyOSFromTOUCHINPUT(ET_TOUCH_PRESSED, touch_input,
  863. base::TimeTicks::Now());
  864. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  865. base::TimeTicks::Now());
  866. histogram_tester.ExpectUniqueTimeSample("Event.Latency.OS2.TOUCH_PRESSED",
  867. base::Milliseconds(5), 2);
  868. }
  869. // Simulate ::GetTickCount advancing 15 msec, which wraps around past 0.
  870. constexpr DWORD wrapped_timestamp_msec = timestamp_msec + 15;
  871. static_assert(wrapped_timestamp_msec == 4,
  872. "timestamp should have wrapped around");
  873. UpdateTickClock(wrapped_timestamp_msec);
  874. {
  875. base::HistogramTester histogram_tester;
  876. ComputeEventLatencyOSFromTOUCHINPUT(ET_TOUCH_PRESSED, touch_input,
  877. base::TimeTicks::Now());
  878. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  879. base::TimeTicks::Now());
  880. histogram_tester.ExpectUniqueTimeSample("Event.Latency.OS2.TOUCH_PRESSED",
  881. base::Milliseconds(15), 2);
  882. }
  883. // Simulate an event with a bogus timestamp. The delta should be recorded as
  884. // 0.
  885. UpdateTickClock(timestamp_msec - 1000);
  886. {
  887. base::HistogramTester histogram_tester;
  888. ComputeEventLatencyOSFromTOUCHINPUT(ET_TOUCH_PRESSED, touch_input,
  889. base::TimeTicks::Now());
  890. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  891. base::TimeTicks::Now());
  892. histogram_tester.ExpectUniqueTimeSample("Event.Latency.OS2.TOUCH_PRESSED",
  893. base::TimeDelta(), 2);
  894. }
  895. }
  896. TEST_F(EventLatencyTest, ComputeEventLatencyOSFromPerformanceCounter) {
  897. // Make sure there's enough time before Now() to create an event that's
  898. // several minutes old.
  899. task_environment_.AdvanceClock(base::Minutes(5));
  900. // Convert the current time to units directly compatible with the Performance
  901. // Counter.
  902. LARGE_INTEGER ticks_per_sec = {};
  903. if (!::QueryPerformanceFrequency(&ticks_per_sec) ||
  904. ticks_per_sec.QuadPart <= 0 || !base::TimeTicks::IsHighResolution()) {
  905. // Skip this test when the performance counter is unavailable or
  906. // unreliable. (It's unlikely, but possible, that IsHighResolution is false
  907. // even if the performance counter works - see InitializeNowFunctionPointer
  908. // in time_win.cc - so also skip the test in this case.)
  909. return;
  910. }
  911. const auto ticks_per_second = ticks_per_sec.QuadPart;
  912. UINT64 current_timestamp =
  913. base::TimeTicks::Now().since_origin().InSecondsF() * ticks_per_second;
  914. // Event created shortly before now.
  915. {
  916. const POINTER_INFO pointer_info = {
  917. .dwTime = 0U,
  918. .PerformanceCount = current_timestamp - ticks_per_second,
  919. };
  920. base::HistogramTester histogram_tester;
  921. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  922. base::TimeTicks::Now());
  923. histogram_tester.ExpectUniqueTimeSample("Event.Latency.OS2.TOUCH_PRESSED",
  924. base::Seconds(1), 1);
  925. }
  926. // Event created several minutes before now (IsValidTimebase should return
  927. // false). The delta should be recorded as 0.
  928. {
  929. const POINTER_INFO pointer_info = {
  930. .dwTime = 0U,
  931. .PerformanceCount = current_timestamp - 5 * 60 * ticks_per_second,
  932. };
  933. base::HistogramTester histogram_tester;
  934. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  935. base::TimeTicks::Now());
  936. histogram_tester.ExpectUniqueTimeSample("Event.Latency.OS2.TOUCH_PRESSED",
  937. base::TimeDelta(), 1);
  938. }
  939. // Event created in the future (IsValidTimebase should return false). The
  940. // delta should be recorded as 0.
  941. {
  942. const POINTER_INFO pointer_info = {
  943. .dwTime = 0U,
  944. .PerformanceCount = current_timestamp + ticks_per_second,
  945. };
  946. base::HistogramTester histogram_tester;
  947. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  948. base::TimeTicks::Now());
  949. histogram_tester.ExpectUniqueTimeSample("Event.Latency.OS2.TOUCH_PRESSED",
  950. base::TimeDelta(), 1);
  951. }
  952. // Invalid event with no timestamp.
  953. {
  954. const POINTER_INFO pointer_info = {
  955. .dwTime = 0U,
  956. .PerformanceCount = 0UL,
  957. };
  958. base::HistogramTester histogram_tester;
  959. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  960. base::TimeTicks::Now());
  961. histogram_tester.ExpectTotalCount("Event.Latency.OS2.TOUCH_PRESSED", 0);
  962. }
  963. // Invalid event with 2 timestamps should take the higher-precision one.
  964. {
  965. const DWORD now_msec = 1000;
  966. UpdateTickClock(now_msec);
  967. const POINTER_INFO pointer_info = {
  968. // 10 milliseconds ago.
  969. .dwTime = now_msec - 10,
  970. // 1 second ago.
  971. .PerformanceCount = current_timestamp - ticks_per_second,
  972. };
  973. base::HistogramTester histogram_tester;
  974. ComputeEventLatencyOSFromPOINTER_INFO(ET_TOUCH_PRESSED, pointer_info,
  975. base::TimeTicks::Now());
  976. histogram_tester.ExpectUniqueTimeSample("Event.Latency.OS2.TOUCH_PRESSED",
  977. base::Seconds(1), 1);
  978. }
  979. }
  980. #endif // BUILDFLAG(IS_WIN)
  981. // Verifies that copied events never copy target_.
  982. TEST(EventTest, NeverCopyTarget) {
  983. const gfx::Point location(10, 10);
  984. const gfx::Point root_location(20, 20);
  985. ui::test::TestEventTarget target;
  986. ui::MouseEvent targeted(ET_MOUSE_PRESSED, location, root_location,
  987. EventTimeForNow(), 0, 0);
  988. Event::DispatcherApi(&targeted).set_target(&target);
  989. ui::MouseEvent targeted_copy1(targeted);
  990. EXPECT_EQ(nullptr, targeted_copy1.target());
  991. ui::MouseEvent targeted_copy2 = targeted;
  992. EXPECT_EQ(nullptr, targeted_copy2.target());
  993. }
  994. } // namespace ui