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.
7 #include <linux/input.h>
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/posix/eintr_wrapper.h"
15 #include "base/run_loop.h"
16 #include "base/time/time.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/events/event.h"
19 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
20 #include "ui/events/platform/platform_event_dispatcher.h"
21 #include "ui/events/platform/platform_event_source.h"
25 static int SetNonBlocking(int fd) {
26 int flags = fcntl(fd, F_GETFL, 0);
29 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
32 const char kTestDevicePath[] = "/dev/input/test-device";
38 class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
40 MockTouchEventConverterEvdev(int fd, base::FilePath path);
41 virtual ~MockTouchEventConverterEvdev() {};
43 void ConfigureReadMock(struct input_event* queue,
47 unsigned size() { return dispatched_events_.size(); }
48 TouchEvent* event(unsigned index) { return dispatched_events_[index]; }
50 // Actually dispatch the event reader code.
52 OnFileCanReadWithoutBlocking(read_pipe_);
53 base::RunLoop().RunUntilIdle();
56 void DispatchCallback(Event* event) {
57 dispatched_events_.push_back(
58 new TouchEvent(*static_cast<TouchEvent*>(event)));
61 bool Reinitialize() OVERRIDE { return true; }
67 ScopedVector<TouchEvent> dispatched_events_;
69 DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev);
72 MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(int fd,
74 : TouchEventConverterEvdev(
78 base::Bind(&MockTouchEventConverterEvdev::DispatchCallback,
79 base::Unretained(this))) {
83 // TODO(rjkroege): Check test axes.
84 x_min_pixels_ = x_min_tuxels_ = 0;
85 x_num_pixels_ = x_num_tuxels_ = std::numeric_limits<int>::max();
86 y_min_pixels_ = y_min_tuxels_ = 0;
87 y_num_pixels_ = y_num_tuxels_ = std::numeric_limits<int>::max();
92 PLOG(FATAL) << "failed pipe";
94 DCHECK(SetNonBlocking(fds[0]) == 0)
95 << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
96 DCHECK(SetNonBlocking(fds[1]) == 0)
97 << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
102 void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
105 int nwrite = HANDLE_EINTR(write(write_pipe_,
107 sizeof(struct input_event) * read_this_many));
109 static_cast<int>(sizeof(struct input_event) * read_this_many))
110 << "write() failed, errno: " << errno;
116 class TouchEventConverterEvdevTest : public testing::Test {
118 TouchEventConverterEvdevTest() {}
120 // Overridden from testing::Test:
121 virtual void SetUp() OVERRIDE {
122 // Set up pipe to satisfy message pump (unused).
125 PLOG(FATAL) << "failed pipe";
126 events_in_ = evdev_io[0];
127 events_out_ = evdev_io[1];
129 loop_ = new base::MessageLoopForUI;
130 device_ = new ui::MockTouchEventConverterEvdev(
131 events_in_, base::FilePath(kTestDevicePath));
134 virtual void TearDown() OVERRIDE {
139 ui::MockTouchEventConverterEvdev* device() { return device_; }
142 base::MessageLoop* loop_;
143 ui::MockTouchEventConverterEvdev* device_;
148 DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTest);
151 // TODO(rjkroege): Test for valid handling of time stamps.
152 TEST_F(TouchEventConverterEvdevTest, TouchDown) {
153 ui::MockTouchEventConverterEvdev* dev = device();
155 struct input_event mock_kernel_queue[] = {
156 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
157 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
158 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
159 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
160 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
163 dev->ConfigureReadMock(mock_kernel_queue, 1, 0);
165 EXPECT_EQ(0u, dev->size());
167 dev->ConfigureReadMock(mock_kernel_queue, 2, 1);
169 EXPECT_EQ(0u, dev->size());
171 dev->ConfigureReadMock(mock_kernel_queue, 3, 3);
173 EXPECT_EQ(1u, dev->size());
175 ui::TouchEvent* event = dev->event(0);
176 EXPECT_FALSE(event == NULL);
178 EXPECT_EQ(ui::ET_TOUCH_PRESSED, event->type());
179 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
180 EXPECT_EQ(42, event->x());
181 EXPECT_EQ(51, event->y());
182 EXPECT_EQ(0, event->touch_id());
183 EXPECT_FLOAT_EQ(.5f, event->force());
184 EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
187 TEST_F(TouchEventConverterEvdevTest, NoEvents) {
188 ui::MockTouchEventConverterEvdev* dev = device();
189 dev->ConfigureReadMock(NULL, 0, 0);
190 EXPECT_EQ(0u, dev->size());
193 TEST_F(TouchEventConverterEvdevTest, TouchMove) {
194 ui::MockTouchEventConverterEvdev* dev = device();
196 struct input_event mock_kernel_queue_press[] = {
197 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
198 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
199 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
200 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
201 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
204 struct input_event mock_kernel_queue_move1[] = {
205 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 50},
206 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
207 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 43}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
210 struct input_event mock_kernel_queue_move2[] = {
211 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 42}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
214 // Setup and discard a press.
215 dev->ConfigureReadMock(mock_kernel_queue_press, 6, 0);
217 EXPECT_EQ(1u, dev->size());
219 dev->ConfigureReadMock(mock_kernel_queue_move1, 4, 0);
221 EXPECT_EQ(2u, dev->size());
222 ui::TouchEvent* event = dev->event(1);
223 EXPECT_FALSE(event == NULL);
225 EXPECT_EQ(ui::ET_TOUCH_MOVED, event->type());
226 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
227 EXPECT_EQ(42, event->x());
228 EXPECT_EQ(43, event->y());
229 EXPECT_EQ(0, event->touch_id());
230 EXPECT_FLOAT_EQ(2.f / 3.f, event->force());
231 EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
233 dev->ConfigureReadMock(mock_kernel_queue_move2, 2, 0);
235 EXPECT_EQ(3u, dev->size());
236 event = dev->event(2);
237 EXPECT_FALSE(event == NULL);
239 EXPECT_EQ(ui::ET_TOUCH_MOVED, event->type());
240 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
241 EXPECT_EQ(42, event->x());
242 EXPECT_EQ(42, event->y());
243 EXPECT_EQ(0, event->touch_id());
244 EXPECT_FLOAT_EQ(2.f / 3.f, event->force());
245 EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
248 TEST_F(TouchEventConverterEvdevTest, TouchRelease) {
249 ui::MockTouchEventConverterEvdev* dev = device();
251 struct input_event mock_kernel_queue_press[] = {
252 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
253 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
254 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
255 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
256 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
259 struct input_event mock_kernel_queue_release[] = {
260 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
263 // Setup and discard a press.
264 dev->ConfigureReadMock(mock_kernel_queue_press, 6, 0);
266 EXPECT_EQ(1u, dev->size());
267 ui::TouchEvent* event = dev->event(0);
268 EXPECT_FALSE(event == NULL);
270 dev->ConfigureReadMock(mock_kernel_queue_release, 2, 0);
272 EXPECT_EQ(2u, dev->size());
273 event = dev->event(1);
274 EXPECT_FALSE(event == NULL);
276 EXPECT_EQ(ui::ET_TOUCH_RELEASED, event->type());
277 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
278 EXPECT_EQ(42, event->x());
279 EXPECT_EQ(51, event->y());
280 EXPECT_EQ(0, event->touch_id());
281 EXPECT_FLOAT_EQ(.5f, event->force());
282 EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
285 TEST_F(TouchEventConverterEvdevTest, TwoFingerGesture) {
286 ui::MockTouchEventConverterEvdev* dev = device();
291 struct input_event mock_kernel_queue_press0[] = {
292 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
293 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
294 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
295 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
296 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
298 // Setup and discard a press.
299 dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
301 EXPECT_EQ(1u, dev->size());
303 struct input_event mock_kernel_queue_move0[] = {
304 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
306 // Setup and discard a move.
307 dev->ConfigureReadMock(mock_kernel_queue_move0, 2, 0);
309 EXPECT_EQ(2u, dev->size());
311 struct input_event mock_kernel_queue_move0press1[] = {
312 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
313 {{0, 0}, EV_ABS, ABS_MT_SLOT, 1}, {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 686},
314 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
315 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
316 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 101},
317 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 102}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
319 // Move on 0, press on 1.
320 dev->ConfigureReadMock(mock_kernel_queue_move0press1, 9, 0);
322 EXPECT_EQ(4u, dev->size());
327 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0->type());
328 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0->time_stamp());
329 EXPECT_EQ(40, ev0->x());
330 EXPECT_EQ(51, ev0->y());
331 EXPECT_EQ(0, ev0->touch_id());
332 EXPECT_FLOAT_EQ(.5f, ev0->force());
333 EXPECT_FLOAT_EQ(0.f, ev0->rotation_angle());
336 EXPECT_EQ(ui::ET_TOUCH_PRESSED, ev1->type());
337 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
338 EXPECT_EQ(101, ev1->x());
339 EXPECT_EQ(102, ev1->y());
340 EXPECT_EQ(1, ev1->touch_id());
341 EXPECT_FLOAT_EQ(.5f, ev1->force());
342 EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
344 // Stationary 0, Moves 1.
345 struct input_event mock_kernel_queue_stationary0_move1[] = {
346 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
348 dev->ConfigureReadMock(mock_kernel_queue_stationary0_move1, 2, 0);
350 EXPECT_EQ(5u, dev->size());
353 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1->type());
354 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
355 EXPECT_EQ(40, ev1->x());
356 EXPECT_EQ(102, ev1->y());
357 EXPECT_EQ(1, ev1->touch_id());
359 EXPECT_FLOAT_EQ(.5f, ev1->force());
360 EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
362 // Move 0, stationary 1.
363 struct input_event mock_kernel_queue_move0_stationary1[] = {
364 {{0, 0}, EV_ABS, ABS_MT_SLOT, 0}, {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 39},
365 {{0, 0}, EV_SYN, SYN_REPORT, 0}
367 dev->ConfigureReadMock(mock_kernel_queue_move0_stationary1, 3, 0);
369 EXPECT_EQ(6u, dev->size());
372 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0->type());
373 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0->time_stamp());
374 EXPECT_EQ(39, ev0->x());
375 EXPECT_EQ(51, ev0->y());
376 EXPECT_EQ(0, ev0->touch_id());
377 EXPECT_FLOAT_EQ(.5f, ev0->force());
378 EXPECT_FLOAT_EQ(0.f, ev0->rotation_angle());
380 // Release 0, move 1.
381 struct input_event mock_kernel_queue_release0_move1[] = {
382 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_ABS, ABS_MT_SLOT, 1},
383 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 38}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
385 dev->ConfigureReadMock(mock_kernel_queue_release0_move1, 4, 0);
387 EXPECT_EQ(8u, dev->size());
391 EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev0->type());
392 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0->time_stamp());
393 EXPECT_EQ(39, ev0->x());
394 EXPECT_EQ(51, ev0->y());
395 EXPECT_EQ(0, ev0->touch_id());
396 EXPECT_FLOAT_EQ(.5f, ev0->force());
397 EXPECT_FLOAT_EQ(0.f, ev0->rotation_angle());
399 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1->type());
400 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
401 EXPECT_EQ(38, ev1->x());
402 EXPECT_EQ(102, ev1->y());
403 EXPECT_EQ(1, ev1->touch_id());
404 EXPECT_FLOAT_EQ(.5f, ev1->force());
405 EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
408 struct input_event mock_kernel_queue_release1[] = {
409 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
411 dev->ConfigureReadMock(mock_kernel_queue_release1, 2, 0);
413 EXPECT_EQ(9u, dev->size());
416 EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev1->type());
417 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
418 EXPECT_EQ(38, ev1->x());
419 EXPECT_EQ(102, ev1->y());
420 EXPECT_EQ(1, ev1->touch_id());
421 EXPECT_FLOAT_EQ(.5f, ev1->force());
422 EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
425 TEST_F(TouchEventConverterEvdevTest, TypeA) {
426 ui::MockTouchEventConverterEvdev* dev = device();
428 struct input_event mock_kernel_queue_press0[] = {
429 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
430 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
431 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
432 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51},
433 {{0, 0}, EV_SYN, SYN_MT_REPORT, 0},
434 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
435 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 61},
436 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 71},
437 {{0, 0}, EV_SYN, SYN_MT_REPORT, 0},
438 {{0, 0}, EV_SYN, SYN_REPORT, 0}
441 // Check that two events are generated.
442 dev->ConfigureReadMock(mock_kernel_queue_press0, 10, 0);
444 EXPECT_EQ(2u, dev->size());
447 TEST_F(TouchEventConverterEvdevTest, Unsync) {
448 ui::MockTouchEventConverterEvdev* dev = device();
450 struct input_event mock_kernel_queue_press0[] = {
451 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
452 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
453 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
454 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
455 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
458 dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
460 EXPECT_EQ(1u, dev->size());
462 // Prepare a move with a drop.
463 struct input_event mock_kernel_queue_move0[] = {
464 {{0, 0}, EV_SYN, SYN_DROPPED, 0},
465 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
468 // Verify that we didn't receive it/
469 dev->ConfigureReadMock(mock_kernel_queue_move0, 3, 0);
471 EXPECT_EQ(1u, dev->size());
473 struct input_event mock_kernel_queue_move1[] = {
474 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
477 // Verify that it re-syncs after a SYN_REPORT.
478 dev->ConfigureReadMock(mock_kernel_queue_move1, 2, 0);
480 EXPECT_EQ(2u, dev->size());