1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/events/ozone/evdev/event_device_test_util.h"
7 #include "base/format_macros.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "ui/events/ozone/evdev/event_device_info.h"
13 #include "ui/events/ozone/evdev/event_device_util.h"
19 // This test requres 64 bit groups in bitmask inputs (merge them if 32-bit).
20 const int kTestDataWordSize
= 64;
22 #define EVDEV_BITS_TO_GROUPS(x) \
23 (((x) + kTestDataWordSize - 1) / kTestDataWordSize)
25 std::string
SerializeBitfield(unsigned long* bitmap
, int max
) {
28 for (int i
= EVDEV_BITS_TO_GROUPS(max
) - 1; i
>= 0; i
--) {
29 if (bitmap
[i
] || ret
.size()) {
30 base::StringAppendF(&ret
, "%lx", bitmap
[i
]);
37 if (ret
.length() == 0)
43 bool ParseBitfield(const std::string
& bitfield
,
45 std::vector
<unsigned long>* out
) {
46 std::vector
<std::string
> groups
;
47 base::SplitString(bitfield
, ' ', &groups
);
49 out
->resize(EVDEV_BITS_TO_LONGS(max_bits
));
51 // Convert big endian 64-bit groups to little endian EVDEV_LONG_BIT groups.
52 for (unsigned int i
= 0; i
< groups
.size(); ++i
) {
53 int off
= groups
.size() - 1 - i
;
56 if (!base::HexStringToUInt64(groups
[off
], &val
))
59 for (int j
= 0; j
< kTestDataWordSize
; ++j
) {
60 unsigned int code
= i
* kTestDataWordSize
+ j
;
66 EvdevSetBit(&(*out
)[0], code
);
70 // Require canonically formatted input.
71 if (bitfield
!= SerializeBitfield(out
->data(), max_bits
))
79 // Captured from Chromebook Pixel.
80 const DeviceCapabilities kLinkKeyboard
= {
81 /* path */ "/sys/devices/platform/i8042/serio0/input/input6/event6",
82 /* name */ "AT Translated Set 2 keyboard",
83 /* phys */ "isa0060/serio0/input0",
91 /* key */ "400402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe",
100 // Captured from Chromebook Pixel.
101 const DeviceAbsoluteAxis kLinkTouchscreenAbsAxes
[] = {
102 {ABS_X
, {0, 0, 2559, 0, 0, 20}},
103 {ABS_Y
, {0, 0, 1699, 0, 0, 20}},
104 {ABS_PRESSURE
, {0, 0, 255, 0, 0, 0}},
105 {ABS_MT_SLOT
, {0, 0, 15, 0, 0, 0}},
106 {ABS_MT_TOUCH_MAJOR
, {0, 0, 938, 0, 0, 0}},
107 {ABS_MT_ORIENTATION
, {0, -3, 4, 0, 0, 0}},
108 {ABS_MT_POSITION_X
, {0, 0, 2559, 0, 0, 20}},
109 {ABS_MT_POSITION_Y
, {0, 0, 1699, 0, 0, 20}},
110 {ABS_MT_TRACKING_ID
, {0, 0, 65535, 0, 0, 0}},
111 {ABS_MT_PRESSURE
, {0, 0, 255, 0, 0, 0}},
113 const DeviceCapabilities kLinkTouchscreen
= {
114 /* path */ "/sys/devices/pci0000:00/0000:00:02.0/i2c-2/2-004a/"
115 "input/input7/event7",
116 /* name */ "Atmel maXTouch Touchscreen",
117 /* phys */ "i2c-2-004a/input0",
119 /* bustype */ "0018",
121 /* product */ "0000",
122 /* version */ "0000",
125 /* key */ "400 0 0 0 0 0",
127 /* abs */ "671800001000003",
132 kLinkTouchscreenAbsAxes
,
133 arraysize(kLinkTouchscreenAbsAxes
),
136 // Captured from Chromebook Pixel.
137 const DeviceAbsoluteAxis kLinkTouchpadAbsAxes
[] = {
138 {ABS_X
, {0, 0, 2040, 0, 0, 20}},
139 {ABS_Y
, {0, 0, 1360, 0, 0, 20}},
140 {ABS_PRESSURE
, {0, 0, 255, 0, 0, 0}},
141 {ABS_MT_SLOT
, {0, 0, 9, 0, 0, 0}},
142 {ABS_MT_TOUCH_MAJOR
, {0, 0, 1878, 0, 0, 0}},
143 {ABS_MT_ORIENTATION
, {0, -3, 4, 0, 0, 0}},
144 {ABS_MT_POSITION_X
, {0, 0, 2040, 0, 0, 20}},
145 {ABS_MT_POSITION_Y
, {0, 0, 1360, 0, 0, 20}},
146 {ABS_MT_TRACKING_ID
, {0, 0, 65535, 0, 0, 0}},
147 {ABS_MT_PRESSURE
, {0, 0, 255, 0, 0, 0}},
149 const DeviceCapabilities kLinkTouchpad
= {
150 /* path */ "/sys/devices/pci0000:00/0000:00:02.0/i2c-1/1-004b/"
151 "input/input8/event8",
152 /* name */ "Atmel maXTouch Touchpad",
153 /* phys */ "i2c-1-004b/input0",
155 /* bustype */ "0018",
157 /* product */ "0000",
158 /* version */ "0000",
161 /* key */ "e520 10000 0 0 0 0",
163 /* abs */ "671800001000003",
168 kLinkTouchpadAbsAxes
,
169 arraysize(kLinkTouchpadAbsAxes
),
172 // Captured from generic HP KU-1156 USB keyboard.
173 const DeviceCapabilities kHpUsbKeyboard
= {
174 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/"
175 "input/input17/event10",
176 /* name */ "Chicony HP Elite USB Keyboard",
177 /* phys */ "usb-0000:00:1d.0-1.3/input0",
179 /* bustype */ "0003",
181 /* product */ "034a",
182 /* version */ "0110",
185 /* key */ "1000000000007 ff9f207ac14057ff febeffdfffefffff "
195 // Captured from generic HP KU-1156 USB keyboard (2nd device with media keys).
196 const DeviceAbsoluteAxis kHpUsbKeyboard_ExtraAbsAxes
[] = {
197 {ABS_VOLUME
, {0, 0, 767, 0, 0, 0}},
199 const DeviceCapabilities kHpUsbKeyboard_Extra
= {
200 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/"
201 "input/input18/event16",
202 /* name */ "Chicony HP Elite USB Keyboard",
203 /* phys */ "usb-0000:00:1d.0-1.3/input1",
205 /* bustype */ "0003",
207 /* product */ "034a",
208 /* version */ "0110",
211 /* key */ "3007f 0 0 483ffff17aff32d bf54444600000000 1 120f938b17c000 "
212 "677bfad941dfed 9ed68000004400 10000002",
214 /* abs */ "100000000",
219 kHpUsbKeyboard_ExtraAbsAxes
,
220 arraysize(kHpUsbKeyboard_ExtraAbsAxes
),
223 // Captured from Dell MS111-L 3-Button Optical USB Mouse.
224 const DeviceCapabilities kLogitechUsbMouse
= {
225 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.4/"
226 "2-1.2.4:1.0/input/input16/event9",
227 /* name */ "Logitech USB Optical Mouse",
228 /* phys */ "usb-0000:00:1d.0-1.2.4/input0",
230 /* bustype */ "0003",
232 /* product */ "c05a",
233 /* version */ "0111",
236 /* key */ "ff0000 0 0 0 0",
245 // Captured from "Mimo Touch 2" Universal DisplayLink monitor.
246 const DeviceAbsoluteAxis kMimoTouch2TouchscreenAbsAxes
[] = {
247 {ABS_X
, {0, 0, 2047, 0, 0, 0}},
248 {ABS_Y
, {0, 0, 2047, 0, 0, 0}},
250 const DeviceCapabilities kMimoTouch2Touchscreen
= {
251 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3.2/"
252 "2-1.3.2:1.0/input/input15/event14",
253 /* name */ "eGalax Inc. USB TouchController",
254 /* phys */ "usb-0000:00:1d.0-1.3.2/input0",
256 /* bustype */ "0003",
258 /* product */ "0001",
259 /* version */ "0100",
262 /* key */ "400 0 0 0 0 0",
269 kMimoTouch2TouchscreenAbsAxes
,
270 arraysize(kMimoTouch2TouchscreenAbsAxes
),
273 // Captured from Wacom Intuos Pen and Touch Small Tablet.
274 const DeviceAbsoluteAxis kWacomIntuosPtS_PenAbsAxes
[] = {
275 {ABS_X
, {0, 0, 15200, 4, 0, 100}},
276 {ABS_Y
, {0, 0, 9500, 4, 0, 100}},
277 {ABS_PRESSURE
, {0, 0, 1023, 0, 0, 0}},
278 {ABS_DISTANCE
, {0, 0, 31, 0, 0, 0}},
280 const DeviceCapabilities kWacomIntuosPtS_Pen
= {
281 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/"
282 "2-1.2.3:1.0/input/input9/event9",
283 /* name */ "Wacom Intuos PT S Pen",
286 /* bustype */ "0003",
288 /* product */ "0302",
289 /* version */ "0100",
292 /* key */ "1c03 0 0 0 0 0",
299 kWacomIntuosPtS_PenAbsAxes
,
300 arraysize(kWacomIntuosPtS_PenAbsAxes
),
303 // Captured from Wacom Intuos Pen and Touch Small Tablet.
304 const DeviceAbsoluteAxis kWacomIntuosPtS_FingerAbsAxes
[] = {
305 {ABS_X
, {0, 0, 4096, 4, 0, 26}},
306 {ABS_Y
, {0, 0, 4096, 4, 0, 43}},
307 {ABS_MT_SLOT
, {0, 0, 15, 0, 0, 0}},
308 {ABS_MT_TOUCH_MAJOR
, {0, 0, 4096, 0, 0, 0}},
309 {ABS_MT_TOUCH_MINOR
, {0, 0, 4096, 0, 0, 0}},
310 {ABS_MT_POSITION_X
, {0, 0, 4096, 4, 0, 26}},
311 {ABS_MT_POSITION_Y
, {0, 0, 4096, 4, 0, 43}},
312 {ABS_MT_TRACKING_ID
, {0, 0, 65535, 0, 0, 0}},
314 const DeviceCapabilities kWacomIntuosPtS_Finger
= {
315 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/"
316 "2-1.2.3:1.1/input/input10/event10",
317 /* name */ "Wacom Intuos PT S Finger",
320 /* bustype */ "0003",
322 /* product */ "0302",
323 /* version */ "0100",
326 /* key */ "e520 630000 0 0 0 0",
328 /* abs */ "263800000000003",
333 kWacomIntuosPtS_FingerAbsAxes
,
334 arraysize(kWacomIntuosPtS_FingerAbsAxes
),
337 // Captured from Logitech Wireless Touch Keyboard K400.
338 const DeviceAbsoluteAxis kLogitechTouchKeyboardK400AbsAxes
[] = {
339 {ABS_VOLUME
, {0, 1, 652, 0, 0, 0}},
341 const DeviceCapabilities kLogitechTouchKeyboardK400
= {
342 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/"
343 "2-1.2.3:1.2/0003:046D:C52B.0006/input/input19/event17",
344 /* name */ "Logitech Unifying Device. Wireless PID:4024",
345 /* phys */ "usb-0000:00:1d.0-1.2.3:1",
347 /* bustype */ "001d",
349 /* product */ "4024",
350 /* version */ "0111",
353 /* key */ "3007f 0 0 483ffff17aff32d bf54444600000000 ffff0001 "
354 "130f938b17c007 ffff7bfad9415fff febeffdfffefffff "
357 /* abs */ "100000000",
362 kLogitechTouchKeyboardK400AbsAxes
,
363 arraysize(kLogitechTouchKeyboardK400AbsAxes
),
366 // Captured from Elo TouchSystems 2700 touchscreen.
367 const DeviceAbsoluteAxis kElo_TouchSystems_2700AbsAxes
[] = {
368 {ABS_X
, {0, 0, 4095, 0, 0, 0}},
369 {ABS_Y
, {0, 0, 4095, 0, 0, 0}},
370 {ABS_MISC
, {0, 0, 256, 0, 0, 0}},
372 const DeviceCapabilities kElo_TouchSystems_2700
= {
373 /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/"
374 "input/input9/event9",
375 /* name */ "Elo TouchSystems, Inc. Elo TouchSystems 2700 IntelliTouch(r) "
376 "USB Touchmonitor Interface",
377 /* phys */ "usb-0000:00:1d.0-1.3/input0",
378 /* uniq */ "20A01347",
379 /* bustype */ "0003",
381 /* product */ "0020",
382 /* version */ "0100",
385 /* key */ "10000 0 0 0 0",
387 /* abs */ "10000000003",
392 kElo_TouchSystems_2700AbsAxes
,
393 arraysize(kElo_TouchSystems_2700AbsAxes
),
396 // Captured from Intel reference design: "Wilson Beach".
397 const DeviceAbsoluteAxis kWilsonBeachActiveStylusAbsAxes
[] = {
398 {ABS_X
, {0, 0, 9600, 0, 0, 33}},
399 {ABS_Y
, {0, 0, 7200, 0, 0, 44}},
400 {ABS_PRESSURE
, {0, 0, 1024, 0, 0, 0}},
402 const DeviceCapabilities kWilsonBeachActiveStylus
= {
403 /* path */ "/sys/devices/pci0000:00/INT3433:00/i2c-1/"
404 "i2c-NTRG0001:00/0018:1B96:0D03.0004/input/"
406 /* name */ "NTRG0001:00 1B96:0D03 Pen",
409 /* bustype */ "0018",
411 /* product */ "0d03",
412 /* version */ "0100",
415 /* key */ "c03 1 0 0 0 0",
422 kWilsonBeachActiveStylusAbsAxes
,
423 arraysize(kWilsonBeachActiveStylusAbsAxes
),
426 ui::InputDeviceType
InputDeviceTypeFromBusType(int bustype
) {
430 return ui::InputDeviceType::INPUT_DEVICE_INTERNAL
;
432 case 0x1D: // Used in kLogitechTouchKeyboardK400 but not listed in input.h.
433 return ui::InputDeviceType::INPUT_DEVICE_EXTERNAL
;
435 NOTREACHED() << "Unexpected bus type";
436 return ui::InputDeviceType::INPUT_DEVICE_UNKNOWN
;
440 bool CapabilitiesToDeviceInfo(const DeviceCapabilities
& capabilities
,
441 EventDeviceInfo
* devinfo
) {
442 std::vector
<unsigned long> ev_bits
;
443 if (!ParseBitfield(capabilities
.ev
, EV_CNT
, &ev_bits
))
445 devinfo
->SetEventTypes(&ev_bits
[0], ev_bits
.size());
447 std::vector
<unsigned long> key_bits
;
448 if (!ParseBitfield(capabilities
.key
, KEY_CNT
, &key_bits
))
450 devinfo
->SetKeyEvents(&key_bits
[0], key_bits
.size());
452 std::vector
<unsigned long> rel_bits
;
453 if (!ParseBitfield(capabilities
.rel
, REL_CNT
, &rel_bits
))
455 devinfo
->SetRelEvents(&rel_bits
[0], rel_bits
.size());
457 std::vector
<unsigned long> abs_bits
;
458 if (!ParseBitfield(capabilities
.abs
, ABS_CNT
, &abs_bits
))
460 devinfo
->SetAbsEvents(&abs_bits
[0], abs_bits
.size());
462 std::vector
<unsigned long> msc_bits
;
463 if (!ParseBitfield(capabilities
.msc
, MSC_CNT
, &msc_bits
))
465 devinfo
->SetMscEvents(&msc_bits
[0], msc_bits
.size());
467 std::vector
<unsigned long> led_bits
;
468 if (!ParseBitfield(capabilities
.led
, LED_CNT
, &led_bits
))
470 devinfo
->SetLedEvents(&led_bits
[0], led_bits
.size());
472 std::vector
<unsigned long> prop_bits
;
473 if (!ParseBitfield(capabilities
.prop
, INPUT_PROP_CNT
, &prop_bits
))
475 devinfo
->SetProps(&prop_bits
[0], prop_bits
.size());
477 for (size_t i
= 0; i
< capabilities
.abs_axis_count
; ++i
) {
478 const DeviceAbsoluteAxis
& axis
= capabilities
.abs_axis
[i
];
479 devinfo
->SetAbsInfo(axis
.code
, axis
.absinfo
);
482 size_t slots
= devinfo
->GetAbsMtSlotCount();
483 std::vector
<int32_t> zero_slots(slots
, 0);
484 std::vector
<int32_t> minus_one_slots(slots
, -1);
485 for (int code
= EVDEV_ABS_MT_FIRST
; code
<= EVDEV_ABS_MT_LAST
; ++code
) {
486 if (!devinfo
->HasAbsEvent(code
))
488 if (code
== ABS_MT_TRACKING_ID
)
489 devinfo
->SetAbsMtSlots(code
, minus_one_slots
);
491 devinfo
->SetAbsMtSlots(code
, zero_slots
);
495 sscanf(capabilities
.bustype
, "%x", &bustype
);
496 devinfo
->SetDeviceType(InputDeviceTypeFromBusType(bustype
));