1 // Copyright 2014 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 <linux/input.h>
7 #include "base/memory/scoped_ptr.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/message_loop/message_loop.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/events/event.h"
12 #include "ui/events/keycodes/keyboard_codes.h"
13 #include "ui/events/ozone/evdev/key_event_converter_evdev.h"
17 const char kTestDevicePath
[] = "/dev/input/test-device";
19 class MockKeyEventConverterEvdev
: public KeyEventConverterEvdev
{
21 MockKeyEventConverterEvdev(int fd
, EventModifiersEvdev
* modifiers
)
22 : KeyEventConverterEvdev(fd
,
23 base::FilePath(kTestDevicePath
),
25 EventDispatchCallback()) {
28 virtual ~MockKeyEventConverterEvdev() {};
30 unsigned size() { return dispatched_events_
.size(); }
31 KeyEvent
* event(unsigned index
) {
32 CHECK_GT(dispatched_events_
.size(), index
);
33 return dispatched_events_
[index
];
36 virtual void DispatchEventToCallback(Event
* event
) OVERRIDE
;
39 ScopedVector
<KeyEvent
> dispatched_events_
;
41 DISALLOW_COPY_AND_ASSIGN(MockKeyEventConverterEvdev
);
44 void MockKeyEventConverterEvdev::DispatchEventToCallback(Event
* event
) {
45 dispatched_events_
.push_back(new KeyEvent(*static_cast<KeyEvent
*>(event
)));
51 class KeyEventConverterEvdevTest
: public testing::Test
{
53 KeyEventConverterEvdevTest() {}
55 // Overridden from testing::Test:
56 virtual void SetUp() OVERRIDE
{
58 // Set up pipe to satisfy message pump (unused).
61 PLOG(FATAL
) << "failed pipe";
62 events_in_
= evdev_io
[0];
63 events_out_
= evdev_io
[1];
65 modifiers_
= new ui::EventModifiersEvdev();
66 device_
= new ui::MockKeyEventConverterEvdev(events_in_
, modifiers_
);
68 virtual void TearDown() OVERRIDE
{
75 ui::MockKeyEventConverterEvdev
* device() { return device_
; }
76 ui::EventModifiersEvdev
* modifiers() { return modifiers_
; }
79 base::MessageLoopForUI ui_loop_
;
81 ui::EventModifiersEvdev
* modifiers_
;
82 ui::MockKeyEventConverterEvdev
* device_
;
87 DISALLOW_COPY_AND_ASSIGN(KeyEventConverterEvdevTest
);
90 TEST_F(KeyEventConverterEvdevTest
, KeyPress
) {
91 ui::MockKeyEventConverterEvdev
* dev
= device();
93 struct input_event mock_kernel_queue
[] = {
94 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7002a},
95 {{0, 0}, EV_KEY
, KEY_BACKSPACE
, 1},
96 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
98 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7002a},
99 {{0, 0}, EV_KEY
, KEY_BACKSPACE
, 0},
100 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
103 dev
->ProcessEvents(mock_kernel_queue
, arraysize(mock_kernel_queue
));
104 EXPECT_EQ(2u, dev
->size());
108 event
= dev
->event(0);
109 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
110 EXPECT_EQ(ui::VKEY_BACK
, event
->key_code());
111 EXPECT_EQ(0, event
->flags());
113 event
= dev
->event(1);
114 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
115 EXPECT_EQ(ui::VKEY_BACK
, event
->key_code());
116 EXPECT_EQ(0, event
->flags());
119 TEST_F(KeyEventConverterEvdevTest
, KeyRepeat
) {
120 ui::MockKeyEventConverterEvdev
* dev
= device();
122 struct input_event mock_kernel_queue
[] = {
123 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7002a},
124 {{0, 0}, EV_KEY
, KEY_BACKSPACE
, 1},
125 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
127 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7002a},
128 {{0, 0}, EV_KEY
, KEY_BACKSPACE
, 2},
129 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
131 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7002a},
132 {{0, 0}, EV_KEY
, KEY_BACKSPACE
, 2},
133 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
135 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7002a},
136 {{0, 0}, EV_KEY
, KEY_BACKSPACE
, 0},
137 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
140 dev
->ProcessEvents(mock_kernel_queue
, arraysize(mock_kernel_queue
));
141 EXPECT_EQ(4u, dev
->size());
145 event
= dev
->event(0);
146 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
147 EXPECT_EQ(ui::VKEY_BACK
, event
->key_code());
148 EXPECT_EQ(0, event
->flags());
150 event
= dev
->event(1);
151 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
152 EXPECT_EQ(ui::VKEY_BACK
, event
->key_code());
153 EXPECT_EQ(0, event
->flags());
155 event
= dev
->event(2);
156 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
157 EXPECT_EQ(ui::VKEY_BACK
, event
->key_code());
158 EXPECT_EQ(0, event
->flags());
160 event
= dev
->event(3);
161 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
162 EXPECT_EQ(ui::VKEY_BACK
, event
->key_code());
163 EXPECT_EQ(0, event
->flags());
166 TEST_F(KeyEventConverterEvdevTest
, NoEvents
) {
167 ui::MockKeyEventConverterEvdev
* dev
= device();
168 dev
->ProcessEvents(NULL
, 0);
169 EXPECT_EQ(0u, dev
->size());
172 TEST_F(KeyEventConverterEvdevTest
, KeyWithModifier
) {
173 ui::MockKeyEventConverterEvdev
* dev
= device();
175 struct input_event mock_kernel_queue
[] = {
176 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x700e1},
177 {{0, 0}, EV_KEY
, KEY_LEFTSHIFT
, 1},
178 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
180 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70004},
181 {{0, 0}, EV_KEY
, KEY_A
, 1},
182 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
184 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70004},
185 {{0, 0}, EV_KEY
, KEY_A
, 0},
186 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
188 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x700e1},
189 {{0, 0}, EV_KEY
, KEY_LEFTSHIFT
, 0},
190 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
193 dev
->ProcessEvents(mock_kernel_queue
, arraysize(mock_kernel_queue
));
194 EXPECT_EQ(4u, dev
->size());
198 event
= dev
->event(0);
199 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
200 EXPECT_EQ(ui::VKEY_SHIFT
, event
->key_code());
201 EXPECT_EQ(ui::EF_SHIFT_DOWN
, event
->flags());
203 event
= dev
->event(1);
204 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
205 EXPECT_EQ(ui::VKEY_A
, event
->key_code());
206 EXPECT_EQ(ui::EF_SHIFT_DOWN
, event
->flags());
208 event
= dev
->event(2);
209 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
210 EXPECT_EQ(ui::VKEY_A
, event
->key_code());
211 EXPECT_EQ(ui::EF_SHIFT_DOWN
, event
->flags());
213 event
= dev
->event(3);
214 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
215 EXPECT_EQ(ui::VKEY_SHIFT
, event
->key_code());
216 EXPECT_EQ(0, event
->flags());
219 TEST_F(KeyEventConverterEvdevTest
, KeyWithDuplicateModifier
) {
220 ui::MockKeyEventConverterEvdev
* dev
= device();
222 struct input_event mock_kernel_queue
[] = {
223 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x700e1},
224 {{0, 0}, EV_KEY
, KEY_LEFTCTRL
, 1},
225 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
227 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x700e5},
228 {{0, 0}, EV_KEY
, KEY_RIGHTCTRL
, 1},
229 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
231 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7001d},
232 {{0, 0}, EV_KEY
, KEY_Z
, 1},
233 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
235 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x7001d},
236 {{0, 0}, EV_KEY
, KEY_Z
, 0},
237 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
239 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x700e1},
240 {{0, 0}, EV_KEY
, KEY_LEFTCTRL
, 0},
241 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
243 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x700e5},
244 {{0, 0}, EV_KEY
, KEY_RIGHTCTRL
, 0},
245 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
248 dev
->ProcessEvents(mock_kernel_queue
, arraysize(mock_kernel_queue
));
249 EXPECT_EQ(6u, dev
->size());
253 event
= dev
->event(0);
254 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
255 EXPECT_EQ(ui::VKEY_CONTROL
, event
->key_code());
256 EXPECT_EQ(ui::EF_CONTROL_DOWN
, event
->flags());
258 event
= dev
->event(1);
259 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
260 EXPECT_EQ(ui::VKEY_CONTROL
, event
->key_code());
261 EXPECT_EQ(ui::EF_CONTROL_DOWN
, event
->flags());
263 event
= dev
->event(2);
264 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
265 EXPECT_EQ(ui::VKEY_Z
, event
->key_code());
266 EXPECT_EQ(ui::EF_CONTROL_DOWN
, event
->flags());
268 event
= dev
->event(3);
269 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
270 EXPECT_EQ(ui::VKEY_Z
, event
->key_code());
271 EXPECT_EQ(ui::EF_CONTROL_DOWN
, event
->flags());
273 event
= dev
->event(4);
274 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
275 EXPECT_EQ(ui::VKEY_CONTROL
, event
->key_code());
276 EXPECT_EQ(ui::EF_CONTROL_DOWN
, event
->flags());
278 event
= dev
->event(5);
279 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
280 EXPECT_EQ(ui::VKEY_CONTROL
, event
->key_code());
281 EXPECT_EQ(0, event
->flags());
284 TEST_F(KeyEventConverterEvdevTest
, KeyWithLock
) {
285 ui::MockKeyEventConverterEvdev
* dev
= device();
287 struct input_event mock_kernel_queue
[] = {
288 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70039},
289 {{0, 0}, EV_KEY
, KEY_CAPSLOCK
, 1},
290 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
292 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70039},
293 {{0, 0}, EV_KEY
, KEY_CAPSLOCK
, 0},
294 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
296 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70014},
297 {{0, 0}, EV_KEY
, KEY_Q
, 1},
298 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
300 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70014},
301 {{0, 0}, EV_KEY
, KEY_Q
, 0},
302 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
304 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70039},
305 {{0, 0}, EV_KEY
, KEY_CAPSLOCK
, 1},
306 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
308 {{0, 0}, EV_MSC
, MSC_SCAN
, 0x70039},
309 {{0, 0}, EV_KEY
, KEY_CAPSLOCK
, 0},
310 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
313 dev
->ProcessEvents(mock_kernel_queue
, arraysize(mock_kernel_queue
));
314 EXPECT_EQ(6u, dev
->size());
318 event
= dev
->event(0);
319 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
320 EXPECT_EQ(ui::VKEY_CAPITAL
, event
->key_code());
321 EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN
, event
->flags());
323 event
= dev
->event(1);
324 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
325 EXPECT_EQ(ui::VKEY_CAPITAL
, event
->key_code());
326 EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN
, event
->flags());
328 event
= dev
->event(2);
329 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
330 EXPECT_EQ(ui::VKEY_Q
, event
->key_code());
331 EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN
, event
->flags());
333 event
= dev
->event(3);
334 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
335 EXPECT_EQ(ui::VKEY_Q
, event
->key_code());
336 EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN
, event
->flags());
338 event
= dev
->event(4);
339 EXPECT_EQ(ui::ET_KEY_PRESSED
, event
->type());
340 EXPECT_EQ(ui::VKEY_CAPITAL
, event
->key_code());
341 EXPECT_EQ(0, event
->flags());
343 event
= dev
->event(5);
344 EXPECT_EQ(ui::ET_KEY_RELEASED
, event
->type());
345 EXPECT_EQ(ui::VKEY_CAPITAL
, event
->key_code());
346 EXPECT_EQ(0, event
->flags());