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 <stddef.h>
6 #include <stdint.h>
7 
8 #include <cstring>
9 #include <memory>
10 #include <set>
11 #include <utility>
12 
13 #include "base/stl_util.h"
14 #include "base/test/metrics/histogram_tester.h"
15 #include "base/test/simple_test_tick_clock.h"
16 #include "build/build_config.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/events/devices/x11/device_data_manager_x11.h"
19 #include "ui/events/devices/x11/touch_factory_x11.h"
20 #include "ui/events/event.h"
21 #include "ui/events/event_constants.h"
22 #include "ui/events/event_utils.h"
23 #include "ui/events/keycodes/dom/dom_code.h"
24 #include "ui/events/keycodes/dom/keycode_converter.h"
25 #include "ui/events/test/events_test_utils.h"
26 #include "ui/events/test/events_test_utils_x11.h"
27 #include "ui/events/test/keyboard_layout.h"
28 #include "ui/events/test/scoped_event_test_tick_clock.h"
29 #include "ui/events/types/event_type.h"
30 #include "ui/events/x/events_x_utils.h"
31 #include "ui/events/x/x11_event_translation.h"
32 #include "ui/gfx/geometry/point.h"
33 #include "ui/gfx/x/connection.h"
34 #include "ui/gfx/x/event.h"
35 #include "ui/gfx/x/xproto.h"
36 
37 namespace ui {
38 
39 namespace {
40 
41 // Initializes the passed-in event.
InitButtonEvent(x11::Event * event,bool is_press,const gfx::Point & location,int button,x11::KeyButMask state)42 void InitButtonEvent(x11::Event* event,
43                      bool is_press,
44                      const gfx::Point& location,
45                      int button,
46                      x11::KeyButMask state) {
47   *event = x11::Event(x11::ButtonEvent{
48       .opcode = is_press ? x11::ButtonEvent::Press : x11::ButtonEvent::Release,
49       .detail = static_cast<x11::Button>(button),
50       .event_x = location.x(),
51       .event_y = location.y(),
52       .state = state,
53   });
54 }
55 
56 #if !defined(OS_CHROMEOS)
57 // Initializes the passed-in x11::Event.
InitKeyEvent(x11::Event * event,bool is_press,int keycode,x11::KeyButMask state)58 void InitKeyEvent(x11::Event* event,
59                   bool is_press,
60                   int keycode,
61                   x11::KeyButMask state) {
62   // We don't bother setting fields that the event code doesn't use, such as
63   // x_root/y_root and window/root/subwindow.
64   *event = x11::Event(x11::KeyEvent{
65       .opcode = is_press ? x11::KeyEvent::Press : x11::KeyEvent::Release,
66       .detail = static_cast<x11::KeyCode>(keycode),
67       .state = state,
68   });
69 }
70 #endif
71 
ComputeRotationAngle(float twist)72 float ComputeRotationAngle(float twist) {
73   float rotation_angle = twist;
74   while (rotation_angle < 0)
75     rotation_angle += 180.f;
76   while (rotation_angle >= 180)
77     rotation_angle -= 180.f;
78   return rotation_angle;
79 }
80 
FlooredEventLocationString(const x11::Event & xev)81 std::string FlooredEventLocationString(const x11::Event& xev) {
82   return gfx::ToFlooredPoint(gfx::PointF(ui::EventLocationFromXEvent(xev)))
83       .ToString();
84 }
85 
86 }  // namespace
87 
88 class EventsXTest : public testing::Test {
89  public:
90   EventsXTest() = default;
91   ~EventsXTest() override = default;
92 
SetUp()93   void SetUp() override {
94     DeviceDataManagerX11::CreateInstance();
95     ui::TouchFactory::GetInstance()->ResetForTest();
96     ResetTimestampRolloverCountersForTesting();
97   }
TearDown()98   void TearDown() override { ResetTimestampRolloverCountersForTesting(); }
99 
100  private:
101   DISALLOW_COPY_AND_ASSIGN(EventsXTest);
102 };
103 
TEST_F(EventsXTest,ButtonEvents)104 TEST_F(EventsXTest, ButtonEvents) {
105   x11::Event event;
106   gfx::Point location(5, 10);
107   gfx::Vector2d offset;
108 
109   InitButtonEvent(&event, true, location, 1, {});
110   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromXEvent(event));
111   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, ui::EventFlagsFromXEvent(event));
112   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON,
113             ui::GetChangedMouseButtonFlagsFromXEvent(event));
114   EXPECT_EQ(location, ui::EventLocationFromXEvent(event));
115 
116   InitButtonEvent(&event, true, location, 2,
117                   x11::KeyButMask::Button1 | x11::KeyButMask::Shift);
118   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromXEvent(event));
119   EXPECT_EQ(
120       ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_SHIFT_DOWN,
121       ui::EventFlagsFromXEvent(event));
122   EXPECT_EQ(ui::EF_MIDDLE_MOUSE_BUTTON,
123             ui::GetChangedMouseButtonFlagsFromXEvent(event));
124   EXPECT_EQ(location, ui::EventLocationFromXEvent(event));
125 
126   InitButtonEvent(&event, false, location, 3, {});
127   EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromXEvent(event));
128   EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromXEvent(event));
129   EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON,
130             ui::GetChangedMouseButtonFlagsFromXEvent(event));
131   EXPECT_EQ(location, ui::EventLocationFromXEvent(event));
132 
133   // Scroll up.
134   InitButtonEvent(&event, true, location, 4, {});
135   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromXEvent(event));
136   EXPECT_EQ(0, ui::EventFlagsFromXEvent(event));
137   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromXEvent(event));
138   EXPECT_EQ(location, ui::EventLocationFromXEvent(event));
139   offset = ui::GetMouseWheelOffsetFromXEvent(event);
140   EXPECT_GT(offset.y(), 0);
141   EXPECT_EQ(0, offset.x());
142 
143   // Scroll down.
144   InitButtonEvent(&event, true, location, 5, {});
145   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromXEvent(event));
146   EXPECT_EQ(0, ui::EventFlagsFromXEvent(event));
147   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromXEvent(event));
148   EXPECT_EQ(location, ui::EventLocationFromXEvent(event));
149   offset = ui::GetMouseWheelOffsetFromXEvent(event);
150   EXPECT_LT(offset.y(), 0);
151   EXPECT_EQ(0, offset.x());
152 
153   // Scroll left.
154   InitButtonEvent(&event, true, location, 6, {});
155   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromXEvent(event));
156   EXPECT_EQ(0, ui::EventFlagsFromXEvent(event));
157   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromXEvent(event));
158   EXPECT_EQ(location, ui::EventLocationFromXEvent(event));
159   offset = ui::GetMouseWheelOffsetFromXEvent(event);
160   EXPECT_EQ(0, offset.y());
161   EXPECT_GT(offset.x(), 0);
162 
163   // Scroll right.
164   InitButtonEvent(&event, true, location, 7, {});
165   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromXEvent(event));
166   EXPECT_EQ(0, ui::EventFlagsFromXEvent(event));
167   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromXEvent(event));
168   EXPECT_EQ(location, ui::EventLocationFromXEvent(event));
169   offset = ui::GetMouseWheelOffsetFromXEvent(event);
170   EXPECT_EQ(0, offset.y());
171   EXPECT_LT(offset.x(), 0);
172 
173   // TODO(derat): Test XInput code.
174 }
175 
TEST_F(EventsXTest,AvoidExtraEventsOnWheelRelease)176 TEST_F(EventsXTest, AvoidExtraEventsOnWheelRelease) {
177   x11::Event event;
178   gfx::Point location(5, 10);
179 
180   InitButtonEvent(&event, true, location, 4, {});
181   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromXEvent(event));
182 
183   // We should return ET_UNKNOWN for the release event instead of returning
184   // ET_MOUSEWHEEL; otherwise we'll scroll twice for each scrollwheel step.
185   InitButtonEvent(&event, false, location, 4, {});
186   EXPECT_EQ(ui::ET_UNKNOWN, ui::EventTypeFromXEvent(event));
187 
188   // TODO(derat): Test XInput code.
189 }
190 
TEST_F(EventsXTest,EnterLeaveEvent)191 TEST_F(EventsXTest, EnterLeaveEvent) {
192   x11::Event event(x11::CrossingEvent{
193       .opcode = x11::CrossingEvent::EnterNotify,
194       .root_x = 110,
195       .root_y = 120,
196       .event_x = 10,
197       .event_y = 20,
198   });
199 
200   // Mouse enter events are converted to mouse move events to be consistent with
201   // the way views handle mouse enter. See comments for EnterNotify case in
202   // ui::EventTypeFromXEvent for more details.
203   EXPECT_EQ(ui::ET_MOUSE_MOVED, ui::EventTypeFromXEvent(event));
204   EXPECT_TRUE(ui::EventFlagsFromXEvent(event) & ui::EF_IS_SYNTHESIZED);
205   EXPECT_EQ("10,20", ui::EventLocationFromXEvent(event).ToString());
206   EXPECT_EQ("110,120", ui::EventSystemLocationFromXEvent(event).ToString());
207 
208   event = x11::Event(x11::CrossingEvent{
209       .opcode = x11::CrossingEvent::LeaveNotify,
210       .root_x = 230,
211       .root_y = 240,
212       .event_x = 30,
213       .event_y = 40,
214   });
215   EXPECT_EQ(ui::ET_MOUSE_EXITED, ui::EventTypeFromXEvent(event));
216   EXPECT_EQ("30,40", ui::EventLocationFromXEvent(event).ToString());
217   EXPECT_EQ("230,240", ui::EventSystemLocationFromXEvent(event).ToString());
218 }
219 
TEST_F(EventsXTest,ClickCount)220 TEST_F(EventsXTest, ClickCount) {
221   x11::Event event;
222   gfx::Point location(5, 10);
223 
224   base::TimeDelta time_stamp = base::TimeTicks::Now().since_origin() -
225                                base::TimeDelta::FromMilliseconds(10);
226   for (int i = 1; i <= 3; ++i) {
227     InitButtonEvent(&event, true, location, 1, {});
228     {
229       uint32_t time = time_stamp.InMilliseconds() & UINT32_MAX;
230       event.As<x11::ButtonEvent>()->time = static_cast<x11::Time>(time);
231       auto mouseev = ui::BuildMouseEventFromXEvent(event);
232       EXPECT_EQ(ui::ET_MOUSE_PRESSED, mouseev->type());
233       EXPECT_EQ(i, mouseev->GetClickCount());
234     }
235 
236     InitButtonEvent(&event, false, location, 1, {});
237     {
238       uint32_t time = time_stamp.InMilliseconds() & UINT32_MAX;
239       event.As<x11::ButtonEvent>()->time = static_cast<x11::Time>(time);
240       auto mouseev = ui::BuildMouseEventFromXEvent(event);
241       EXPECT_EQ(ui::ET_MOUSE_RELEASED, mouseev->type());
242       EXPECT_EQ(i, mouseev->GetClickCount());
243     }
244     time_stamp += base::TimeDelta::FromMilliseconds(1);
245   }
246 }
247 
TEST_F(EventsXTest,TouchEventBasic)248 TEST_F(EventsXTest, TouchEventBasic) {
249   std::vector<int> devices;
250   devices.push_back(0);
251   ui::SetUpTouchDevicesForTest(devices);
252   std::vector<Valuator> valuators;
253 
254   // Init touch begin with tracking id 5, touch id 0.
255   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_MAJOR, 20);
256   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_ORIENTATION, 0.3f);
257   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_PRESSURE, 100);
258   ui::ScopedXI2Event scoped_xevent;
259   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchBegin, 5,
260                                gfx::Point(10, 10), valuators);
261   EXPECT_EQ(ui::ET_TOUCH_PRESSED, ui::EventTypeFromXEvent(*scoped_xevent));
262   EXPECT_EQ("10,10", FlooredEventLocationString(*scoped_xevent));
263   EXPECT_EQ(GetTouchIdFromXEvent(*scoped_xevent), 0);
264   PointerDetails pointer_details =
265       GetTouchPointerDetailsFromXEvent(*scoped_xevent);
266   EXPECT_FLOAT_EQ(ComputeRotationAngle(pointer_details.twist), 0.15f);
267   EXPECT_FLOAT_EQ(pointer_details.radius_x, 10.0f);
268   EXPECT_FLOAT_EQ(pointer_details.force, 0.1f);
269 
270   // Touch update, with new orientation info.
271   valuators.clear();
272   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_ORIENTATION, 0.5f);
273   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchUpdate, 5,
274                                gfx::Point(20, 20), valuators);
275   EXPECT_EQ(ui::ET_TOUCH_MOVED, ui::EventTypeFromXEvent(*scoped_xevent));
276   EXPECT_EQ("20,20", FlooredEventLocationString(*scoped_xevent));
277   EXPECT_EQ(GetTouchIdFromXEvent(*scoped_xevent), 0);
278   pointer_details = GetTouchPointerDetailsFromXEvent(*scoped_xevent);
279   EXPECT_FLOAT_EQ(ComputeRotationAngle(pointer_details.twist), 0.25f);
280   EXPECT_FLOAT_EQ(pointer_details.radius_x, 10.0f);
281   EXPECT_FLOAT_EQ(pointer_details.force, 0.1f);
282 
283   // Another touch with tracking id 6, touch id 1.
284   valuators.clear();
285   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_MAJOR, 100);
286   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_ORIENTATION, 0.9f);
287   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_PRESSURE, 500);
288   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchBegin, 6,
289                                gfx::Point(200, 200), valuators);
290   EXPECT_EQ(ui::ET_TOUCH_PRESSED, ui::EventTypeFromXEvent(*scoped_xevent));
291   EXPECT_EQ("200,200", FlooredEventLocationString(*scoped_xevent));
292   EXPECT_EQ(GetTouchIdFromXEvent(*scoped_xevent), 1);
293   pointer_details = GetTouchPointerDetailsFromXEvent(*scoped_xevent);
294   EXPECT_FLOAT_EQ(ComputeRotationAngle(pointer_details.twist), 0.45f);
295   EXPECT_FLOAT_EQ(pointer_details.radius_x, 50.0f);
296   EXPECT_FLOAT_EQ(pointer_details.force, 0.5f);
297 
298   // Touch with tracking id 5 should have old radius/angle value and new pressue
299   // value.
300   valuators.clear();
301   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_PRESSURE, 50);
302   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchEnd, 5,
303                                gfx::Point(30, 30), valuators);
304   EXPECT_EQ(ui::ET_TOUCH_RELEASED, ui::EventTypeFromXEvent(*scoped_xevent));
305   EXPECT_EQ("30,30", FlooredEventLocationString(*scoped_xevent));
306   EXPECT_EQ(GetTouchIdFromXEvent(*scoped_xevent), 0);
307   pointer_details = GetTouchPointerDetailsFromXEvent(*scoped_xevent);
308   EXPECT_FLOAT_EQ(ComputeRotationAngle(pointer_details.twist), 0.25f);
309   EXPECT_FLOAT_EQ(pointer_details.radius_x, 10.0f);
310   EXPECT_FLOAT_EQ(pointer_details.force, 0.f);
311 
312   // Touch with tracking id 6 should have old angle/pressure value and new
313   // radius value.
314   valuators.clear();
315   valuators.emplace_back(DeviceDataManagerX11::DT_TOUCH_MAJOR, 50);
316   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchEnd, 6,
317                                gfx::Point(200, 200), valuators);
318   EXPECT_EQ(ui::ET_TOUCH_RELEASED, ui::EventTypeFromXEvent(*scoped_xevent));
319   EXPECT_EQ("200,200", FlooredEventLocationString(*scoped_xevent));
320   EXPECT_EQ(GetTouchIdFromXEvent(*scoped_xevent), 1);
321   pointer_details = GetTouchPointerDetailsFromXEvent(*scoped_xevent);
322   EXPECT_FLOAT_EQ(ComputeRotationAngle(pointer_details.twist), 0.45f);
323   EXPECT_FLOAT_EQ(pointer_details.radius_x, 25.0f);
324   EXPECT_FLOAT_EQ(pointer_details.force, 0.f);
325 }
326 
GetTouchIdForTrackingId(uint32_t tracking_id)327 int GetTouchIdForTrackingId(uint32_t tracking_id) {
328   int slot = 0;
329   bool success =
330       TouchFactory::GetInstance()->QuerySlotForTrackingID(tracking_id, &slot);
331   if (success)
332     return slot;
333   return -1;
334 }
335 
TEST_F(EventsXTest,TouchEventNotRemovingFromNativeMapping)336 TEST_F(EventsXTest, TouchEventNotRemovingFromNativeMapping) {
337   const int kTrackingId = 5;
338   const int kDeviceId = 0;
339 
340   std::vector<int> devices{kDeviceId};
341   ui::SetUpTouchDevicesForTest(devices);
342   std::vector<Valuator> valuators;
343 
344   // Two touch presses with the same tracking id.
345   ui::ScopedXI2Event xpress0;
346   xpress0.InitTouchEvent(kDeviceId, x11::Input::DeviceEvent::TouchBegin,
347                          kTrackingId, gfx::Point(10, 10), valuators);
348   auto upress0 = ui::BuildTouchEventFromXEvent(*xpress0);
349   EXPECT_EQ(kDeviceId, GetTouchIdForTrackingId(kTrackingId));
350 
351   ui::ScopedXI2Event xpress1;
352   xpress1.InitTouchEvent(kDeviceId, x11::Input::DeviceEvent::TouchBegin,
353                          kTrackingId, gfx::Point(20, 20), valuators);
354   auto upress1 = ui::BuildTouchEventFromXEvent(*xpress1);
355   EXPECT_EQ(kDeviceId, GetTouchIdForTrackingId(kTrackingId));
356 
357   // The second touch release should clear the mapping from the
358   // tracking id.
359   ui::ScopedXI2Event xrelease1;
360   xrelease1.InitTouchEvent(kDeviceId, x11::Input::DeviceEvent::TouchEnd,
361                            kTrackingId, gfx::Point(10, 10), valuators);
362   { auto urelease1 = ui::BuildTouchEventFromXEvent(*xrelease1); }
363   EXPECT_EQ(-1, GetTouchIdForTrackingId(kTrackingId));
364 }
365 
366 // Copied events should not remove native touch id mappings, as this causes a
367 // crash (crbug.com/467102). Copied events do not contain a proper
368 // PlatformEvent and should not attempt to access it.
TEST_F(EventsXTest,CopiedTouchEventNotRemovingFromXEventMapping)369 TEST_F(EventsXTest, CopiedTouchEventNotRemovingFromXEventMapping) {
370   std::vector<int> devices;
371   devices.push_back(0);
372   ui::SetUpTouchDevicesForTest(devices);
373   std::vector<Valuator> valuators;
374 
375   // Create a release event which has a native touch id mapping.
376   ui::ScopedXI2Event xrelease0;
377   xrelease0.InitTouchEvent(0, x11::Input::DeviceEvent::TouchEnd, 0,
378                            gfx::Point(10, 10), valuators);
379   auto urelease0 = ui::BuildTouchEventFromXEvent(*xrelease0);
380   {
381     // When the copy is destructed it should not attempt to remove the mapping.
382     // Exiting this scope should not cause a crash.
383     TouchEvent copy = *urelease0;
384   }
385 }
386 
387 // Verifies that the type of events from a disabled keyboard is ET_UNKNOWN, but
388 // that an exception list of keys can still be processed.
TEST_F(EventsXTest,DisableKeyboard)389 TEST_F(EventsXTest, DisableKeyboard) {
390   DeviceDataManagerX11* device_data_manager =
391       static_cast<DeviceDataManagerX11*>(DeviceDataManager::GetInstance());
392   int blocked_device_id = 1;
393   auto blocked_device = static_cast<x11::Input::DeviceId>(blocked_device_id);
394   int other_device_id = 2;
395   int master_device_id = 3;
396   device_data_manager->DisableDevice(blocked_device);
397 
398   std::unique_ptr<std::set<KeyboardCode>> excepted_keys(
399       new std::set<KeyboardCode>);
400   excepted_keys->insert(VKEY_B);
401   device_data_manager->SetDisabledKeyboardAllowedKeys(std::move(excepted_keys));
402 
403   ScopedXI2Event xev;
404   // A is not allowed on the blocked keyboard, and should return ET_UNKNOWN.
405   xev.InitGenericKeyEvent(master_device_id, blocked_device_id,
406                           ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
407   EXPECT_EQ(ui::ET_UNKNOWN, ui::EventTypeFromXEvent(*xev));
408 
409   // The B key is allowed as an exception, and should return KEY_PRESSED.
410   xev.InitGenericKeyEvent(master_device_id, blocked_device_id,
411                           ui::ET_KEY_PRESSED, ui::VKEY_B, 0);
412   EXPECT_EQ(ui::ET_KEY_PRESSED, ui::EventTypeFromXEvent(*xev));
413 
414   // Both A and B are allowed on an unblocked keyboard device.
415   xev.InitGenericKeyEvent(master_device_id, other_device_id, ui::ET_KEY_PRESSED,
416                           ui::VKEY_A, 0);
417   EXPECT_EQ(ui::ET_KEY_PRESSED, ui::EventTypeFromXEvent(*xev));
418   xev.InitGenericKeyEvent(master_device_id, other_device_id, ui::ET_KEY_PRESSED,
419                           ui::VKEY_B, 0);
420   EXPECT_EQ(ui::ET_KEY_PRESSED, ui::EventTypeFromXEvent(*xev));
421 
422   device_data_manager->EnableDevice(blocked_device);
423   device_data_manager->SetDisabledKeyboardAllowedKeys(nullptr);
424 
425   // A key returns KEY_PRESSED as per usual now that keyboard was re-enabled.
426   xev.InitGenericKeyEvent(master_device_id, blocked_device_id,
427                           ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
428   EXPECT_EQ(ui::ET_KEY_PRESSED, ui::EventTypeFromXEvent(*xev));
429 }
430 
431 // Verifies that the type of events from a disabled mouse is ET_UNKNOWN.
TEST_F(EventsXTest,DisableMouse)432 TEST_F(EventsXTest, DisableMouse) {
433   DeviceDataManagerX11* device_data_manager =
434       static_cast<DeviceDataManagerX11*>(DeviceDataManager::GetInstance());
435   int blocked_device_id = 1;
436   auto blocked_device = static_cast<x11::Input::DeviceId>(blocked_device_id);
437   int other_device_id = 2;
438   std::vector<int> device_list;
439   device_list.push_back(blocked_device_id);
440   device_list.push_back(other_device_id);
441   TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
442 
443   device_data_manager->DisableDevice(blocked_device);
444 
445   ScopedXI2Event xev;
446   xev.InitGenericButtonEvent(blocked_device_id, ET_MOUSE_PRESSED, gfx::Point(),
447                              EF_LEFT_MOUSE_BUTTON);
448   EXPECT_EQ(ui::ET_UNKNOWN, ui::EventTypeFromXEvent(*xev));
449 
450   xev.InitGenericButtonEvent(other_device_id, ET_MOUSE_PRESSED, gfx::Point(),
451                              EF_LEFT_MOUSE_BUTTON);
452   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromXEvent(*xev));
453 
454   device_data_manager->EnableDevice(blocked_device);
455 
456   xev.InitGenericButtonEvent(blocked_device_id, ET_MOUSE_PRESSED, gfx::Point(),
457                              EF_LEFT_MOUSE_BUTTON);
458   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromXEvent(*xev));
459 }
460 
461 #if !defined(OS_CHROMEOS)
TEST_F(EventsXTest,ImeFabricatedKeyEvents)462 TEST_F(EventsXTest, ImeFabricatedKeyEvents) {
463   x11::KeyButMask state_to_be_fabricated[] = {
464       {},
465       x11::KeyButMask::Shift,
466       x11::KeyButMask::Lock,
467       x11::KeyButMask::Shift | x11::KeyButMask::Lock,
468   };
469   for (auto state : state_to_be_fabricated) {
470     for (int is_char = 0; is_char < 2; ++is_char) {
471       x11::Event x_event;
472       InitKeyEvent(&x_event, true, 0, state);
473       auto key_event = ui::BuildKeyEventFromXEvent(x_event);
474       if (is_char) {
475         KeyEventTestApi test_event(key_event.get());
476         test_event.set_is_char(true);
477       }
478       EXPECT_TRUE(key_event->flags() & ui::EF_IME_FABRICATED_KEY);
479     }
480   }
481 
482   x11::KeyButMask state_to_be_not_fabricated[] = {
483       x11::KeyButMask::Control,
484       x11::KeyButMask::Mod1,
485       x11::KeyButMask::Mod2,
486       x11::KeyButMask::Shift | x11::KeyButMask::Control,
487   };
488   for (auto state : state_to_be_not_fabricated) {
489     for (int is_char = 0; is_char < 2; ++is_char) {
490       x11::Event x_event;
491       InitKeyEvent(&x_event, true, 0, state);
492       auto key_event = ui::BuildKeyEventFromXEvent(x_event);
493       if (is_char) {
494         KeyEventTestApi test_event(key_event.get());
495         test_event.set_is_char(true);
496       }
497       EXPECT_FALSE(key_event->flags() & ui::EF_IME_FABRICATED_KEY);
498     }
499   }
500 }
501 #endif
502 
TEST_F(EventsXTest,IgnoresMotionEventForMouseWheelScroll)503 TEST_F(EventsXTest, IgnoresMotionEventForMouseWheelScroll) {
504   int device_id = 1;
505   std::vector<int> devices;
506   devices.push_back(device_id);
507   ui::SetUpPointerDevicesForTest(devices);
508 
509   ScopedXI2Event xev;
510   xev.InitScrollEvent(device_id, 1, 2, 3, 4, 1);
511   // We shouldn't produce a mouse move event on a mouse wheel
512   // scroll. These events are only produced for some mice.
513   EXPECT_EQ(ui::ET_UNKNOWN, ui::EventTypeFromXEvent(*xev));
514 }
515 
516 namespace {
517 
518 // Returns a fake TimeTicks based on the given millisecond offset.
TimeTicksFromMillis(int64_t millis)519 base::TimeTicks TimeTicksFromMillis(int64_t millis) {
520   return base::TimeTicks() + base::TimeDelta::FromMilliseconds(millis);
521 }
522 
523 }  // namespace
524 
TEST_F(EventsXTest,TimestampRolloverAndAdjustWhenDecreasing)525 TEST_F(EventsXTest, TimestampRolloverAndAdjustWhenDecreasing) {
526   x11::Event event;
527   InitButtonEvent(&event, true, gfx::Point(5, 10), 1, {});
528 
529   test::ScopedEventTestTickClock clock;
530   clock.SetNowTicks(TimeTicksFromMillis(0x100000001));
531   ResetTimestampRolloverCountersForTesting();
532 
533   event.As<x11::ButtonEvent>()->time = static_cast<x11::Time>(0xFFFFFFFF);
534   EXPECT_EQ(TimeTicksFromMillis(0xFFFFFFFF), ui::EventTimeFromXEvent(event));
535 
536   clock.SetNowTicks(TimeTicksFromMillis(0x100000007));
537   ResetTimestampRolloverCountersForTesting();
538 
539   event.As<x11::ButtonEvent>()->time = static_cast<x11::Time>(3);
540   EXPECT_EQ(TimeTicksFromMillis(0x100000000 + 3),
541             ui::EventTimeFromXEvent(event));
542 }
543 
TEST_F(EventsXTest,NoTimestampRolloverWhenMonotonicIncreasing)544 TEST_F(EventsXTest, NoTimestampRolloverWhenMonotonicIncreasing) {
545   x11::Event event;
546   InitButtonEvent(&event, true, gfx::Point(5, 10), 1, {});
547 
548   test::ScopedEventTestTickClock clock;
549   clock.SetNowTicks(TimeTicksFromMillis(10));
550   ResetTimestampRolloverCountersForTesting();
551 
552   event.As<x11::ButtonEvent>()->time = static_cast<x11::Time>(6);
553   EXPECT_EQ(TimeTicksFromMillis(6), ui::EventTimeFromXEvent(event));
554   event.As<x11::ButtonEvent>()->time = static_cast<x11::Time>(7);
555   EXPECT_EQ(TimeTicksFromMillis(7), ui::EventTimeFromXEvent(event));
556 
557   clock.SetNowTicks(TimeTicksFromMillis(0x100000005));
558   ResetTimestampRolloverCountersForTesting();
559 
560   event.As<x11::ButtonEvent>()->time = static_cast<x11::Time>(0xFFFFFFFF);
561   EXPECT_EQ(TimeTicksFromMillis(0xFFFFFFFF), ui::EventTimeFromXEvent(event));
562 }
563 
564 // Moved from event_unittest.cc
565 
TEST_F(EventsXTest,NativeEvent)566 TEST_F(EventsXTest, NativeEvent) {
567   ScopedXI2Event event;
568   event.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, EF_NONE);
569   auto keyev = ui::BuildKeyEventFromXEvent(*event);
570   EXPECT_FALSE(keyev->HasNativeEvent());
571 }
572 
TEST_F(EventsXTest,GetCharacter)573 TEST_F(EventsXTest, GetCharacter) {
574   ui::ScopedKeyboardLayout keyboard_layout(ui::KEYBOARD_LAYOUT_ENGLISH_US);
575 
576   // For X11, test the functions with native_event() as well. crbug.com/107837
577   ScopedXI2Event event;
578   event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
579   auto keyev3 = ui::BuildKeyEventFromXEvent(*event);
580   EXPECT_EQ(10, keyev3->GetCharacter());
581 
582   event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
583   auto keyev4 = ui::BuildKeyEventFromXEvent(*event);
584   EXPECT_EQ(13, keyev4->GetCharacter());
585 }
586 
TEST_F(EventsXTest,NormalizeKeyEventFlags)587 TEST_F(EventsXTest, NormalizeKeyEventFlags) {
588   // Normalize flags when KeyEvent is created from XEvent.
589   ScopedXI2Event event;
590   {
591     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
592     auto keyev = ui::BuildKeyEventFromXEvent(*event);
593     EXPECT_EQ(EF_SHIFT_DOWN, keyev->flags());
594   }
595   {
596     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
597     auto keyev = ui::BuildKeyEventFromXEvent(*event);
598     EXPECT_EQ(EF_NONE, keyev->flags());
599   }
600   {
601     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
602     auto keyev = ui::BuildKeyEventFromXEvent(*event);
603     EXPECT_EQ(EF_CONTROL_DOWN, keyev->flags());
604   }
605   {
606     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
607     auto keyev = ui::BuildKeyEventFromXEvent(*event);
608     EXPECT_EQ(EF_NONE, keyev->flags());
609   }
610   {
611     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_MENU, EF_ALT_DOWN);
612     auto keyev = ui::BuildKeyEventFromXEvent(*event);
613     EXPECT_EQ(EF_ALT_DOWN, keyev->flags());
614   }
615   {
616     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
617     auto keyev = ui::BuildKeyEventFromXEvent(*event);
618     EXPECT_EQ(EF_NONE, keyev->flags());
619   }
620 }
621 
TEST_F(EventsXTest,KeyEventCode)622 TEST_F(EventsXTest, KeyEventCode) {
623   const DomCode kDomCodeForSpace = DomCode::SPACE;
624   const char kCodeForSpace[] = "Space";
625   ASSERT_EQ(kDomCodeForSpace,
626             ui::KeycodeConverter::CodeStringToDomCode(kCodeForSpace));
627   const uint16_t kNativeCodeSpace =
628       ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace);
629   ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace);
630   ASSERT_EQ(kNativeCodeSpace,
631             ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace));
632 
633   // KeyEvent converts from the native keycode (XKB) to the code.
634   ScopedXI2Event xevent;
635   xevent.InitKeyEvent(ET_KEY_PRESSED, VKEY_SPACE, kNativeCodeSpace);
636   auto keyev = ui::BuildKeyEventFromXEvent(*xevent);
637   EXPECT_EQ(kCodeForSpace, keyev->GetCodeString());
638 }
639 
640 namespace {
641 
SetKeyEventTimestamp(x11::Event * event,int64_t time64)642 void SetKeyEventTimestamp(x11::Event* event, int64_t time64) {
643   uint32_t time = time64 & UINT32_MAX;
644   event->As<x11::KeyEvent>()->time = static_cast<x11::Time>(time);
645 }
646 
AdvanceKeyEventTimestamp(x11::Event * event)647 void AdvanceKeyEventTimestamp(x11::Event* event) {
648   auto time = static_cast<uint32_t>(event->As<x11::KeyEvent>()->time) + 1;
649   event->As<x11::KeyEvent>()->time = static_cast<x11::Time>(time);
650 }
651 
652 }  // namespace
653 
TEST_F(EventsXTest,AutoRepeat)654 TEST_F(EventsXTest, AutoRepeat) {
655   const uint16_t kNativeCodeA =
656       ui::KeycodeConverter::DomCodeToNativeKeycode(DomCode::US_A);
657   const uint16_t kNativeCodeB =
658       ui::KeycodeConverter::DomCodeToNativeKeycode(DomCode::US_B);
659 
660   ScopedXI2Event native_event_a_pressed;
661   native_event_a_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
662   ScopedXI2Event native_event_a_pressed_1500;
663   native_event_a_pressed_1500.InitKeyEvent(ET_KEY_PRESSED, VKEY_A,
664                                            kNativeCodeA);
665   ScopedXI2Event native_event_a_pressed_3000;
666   native_event_a_pressed_3000.InitKeyEvent(ET_KEY_PRESSED, VKEY_A,
667                                            kNativeCodeA);
668 
669   ScopedXI2Event native_event_a_released;
670   native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA);
671   ScopedXI2Event native_event_b_pressed;
672   native_event_b_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_B, kNativeCodeB);
673   ScopedXI2Event native_event_a_pressed_nonstandard_state;
674   native_event_a_pressed_nonstandard_state.InitKeyEvent(ET_KEY_PRESSED, VKEY_A,
675                                                         kNativeCodeA);
676   // IBUS-GTK uses the mask (1 << 25) to detect reposted event.
677   {
678     x11::Event& event = *native_event_a_pressed_nonstandard_state;
679     int mask = static_cast<int>(event.As<x11::KeyEvent>()->state) | 1 << 25;
680     event.As<x11::KeyEvent>()->state = static_cast<x11::KeyButMask>(mask);
681   }
682 
683   int64_t ticks_base =
684       (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds() - 5000;
685   SetKeyEventTimestamp(native_event_a_pressed, ticks_base);
686   SetKeyEventTimestamp(native_event_a_pressed_1500, ticks_base + 1500);
687   SetKeyEventTimestamp(native_event_a_pressed_3000, ticks_base + 3000);
688 
689   {
690     auto key_a1 = BuildKeyEventFromXEvent(*native_event_a_pressed);
691     EXPECT_FALSE(key_a1->is_repeat());
692 
693     auto key_a1_released = BuildKeyEventFromXEvent(*native_event_a_released);
694     EXPECT_FALSE(key_a1_released->is_repeat());
695 
696     auto key_a2 = BuildKeyEventFromXEvent(*native_event_a_pressed);
697     EXPECT_FALSE(key_a2->is_repeat());
698 
699     AdvanceKeyEventTimestamp(native_event_a_pressed);
700     auto key_a2_repeated = BuildKeyEventFromXEvent(*native_event_a_pressed);
701     EXPECT_TRUE(key_a2_repeated->is_repeat());
702 
703     auto key_a2_released = BuildKeyEventFromXEvent(*native_event_a_released);
704     EXPECT_FALSE(key_a2_released->is_repeat());
705   }
706 
707   // Interleaved with different key press.
708   {
709     auto key_a3 = BuildKeyEventFromXEvent(*native_event_a_pressed);
710     EXPECT_FALSE(key_a3->is_repeat());
711 
712     auto key_b = BuildKeyEventFromXEvent(*native_event_b_pressed);
713     EXPECT_FALSE(key_b->is_repeat());
714 
715     AdvanceKeyEventTimestamp(native_event_a_pressed);
716     auto key_a3_again = BuildKeyEventFromXEvent(*native_event_a_pressed);
717     EXPECT_FALSE(key_a3_again->is_repeat());
718 
719     AdvanceKeyEventTimestamp(native_event_a_pressed);
720     auto key_a3_repeated = BuildKeyEventFromXEvent(*native_event_a_pressed);
721     EXPECT_TRUE(key_a3_repeated->is_repeat());
722 
723     AdvanceKeyEventTimestamp(native_event_a_pressed);
724     auto key_a3_repeated2 = BuildKeyEventFromXEvent(*native_event_a_pressed);
725     EXPECT_TRUE(key_a3_repeated2->is_repeat());
726 
727     auto key_a3_released = BuildKeyEventFromXEvent(*native_event_a_released);
728     EXPECT_FALSE(key_a3_released->is_repeat());
729   }
730 
731   // Hold the key longer than max auto repeat timeout.
732   {
733     auto key_a4_0 = BuildKeyEventFromXEvent(*native_event_a_pressed);
734     EXPECT_FALSE(key_a4_0->is_repeat());
735 
736     auto key_a4_1500 = BuildKeyEventFromXEvent(*native_event_a_pressed_1500);
737     EXPECT_TRUE(key_a4_1500->is_repeat());
738 
739     auto key_a4_3000 = BuildKeyEventFromXEvent(*native_event_a_pressed_3000);
740     EXPECT_TRUE(key_a4_3000->is_repeat());
741 
742     auto key_a4_released = BuildKeyEventFromXEvent(*native_event_a_released);
743     EXPECT_FALSE(key_a4_released->is_repeat());
744   }
745 
746   {
747     auto key_a4_pressed = BuildKeyEventFromXEvent(*native_event_a_pressed);
748     EXPECT_FALSE(key_a4_pressed->is_repeat());
749 
750     auto key_a4_pressed_nonstandard_state =
751         BuildKeyEventFromXEvent(*native_event_a_pressed_nonstandard_state);
752     EXPECT_FALSE(key_a4_pressed_nonstandard_state->is_repeat());
753   }
754 
755   {
756     auto key_a1 = BuildKeyEventFromXEvent(*native_event_a_pressed);
757     EXPECT_FALSE(key_a1->is_repeat());
758 
759     auto key_a1_with_same_event =
760         BuildKeyEventFromXEvent(*native_event_a_pressed);
761     EXPECT_FALSE(key_a1_with_same_event->is_repeat());
762   }
763 }
764 
765 // Checks that Event.Latency.OS.TOUCH_PRESSED, TOUCH_MOVED,
766 // and TOUCH_RELEASED histograms are computed properly.
TEST_F(EventsXTest,EventLatencyOSTouchHistograms)767 TEST_F(EventsXTest, EventLatencyOSTouchHistograms) {
768   base::HistogramTester histogram_tester;
769   ScopedXI2Event scoped_xevent;
770 
771   // SetUp for test
772   DeviceDataManagerX11::CreateInstance();
773   std::vector<int> devices;
774   devices.push_back(0);
775   ui::SetUpTouchDevicesForTest(devices);
776 
777   // Init touch begin, update, and end events with tracking id 5, touch id 0.
778   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchBegin, 5,
779                                gfx::Point(10, 10), {});
780   auto touch_begin = ui::BuildTouchEventFromXEvent(*scoped_xevent);
781   histogram_tester.ExpectTotalCount("Event.Latency.OS.TOUCH_PRESSED", 1);
782   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchUpdate, 5,
783                                gfx::Point(20, 20), {});
784   auto touch_update = ui::BuildTouchEventFromXEvent(*scoped_xevent);
785   histogram_tester.ExpectTotalCount("Event.Latency.OS.TOUCH_MOVED", 1);
786   scoped_xevent.InitTouchEvent(0, x11::Input::DeviceEvent::TouchEnd, 5,
787                                gfx::Point(30, 30), {});
788   auto touch_end = ui::BuildTouchEventFromXEvent(*scoped_xevent);
789   histogram_tester.ExpectTotalCount("Event.Latency.OS.TOUCH_RELEASED", 1);
790 }
791 
TEST_F(EventsXTest,EventLatencyOSMouseWheelHistogram)792 TEST_F(EventsXTest, EventLatencyOSMouseWheelHistogram) {
793   base::HistogramTester histogram_tester;
794   DeviceDataManagerX11::CreateInstance();
795 
796   // Initializes a native event and uses it to generate a MouseWheel event.
797   x11::Event native_event(x11::ButtonEvent{
798       .opcode = x11::ButtonEvent::Press,
799       // A valid wheel button number between min and max.
800       .detail = static_cast<x11::Button>(4),
801   });
802   auto mouse_ev = ui::BuildMouseWheelEventFromXEvent(native_event);
803   histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1);
804 }
805 
806 }  // namespace ui
807