Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / events / ozone / evdev / touch_event_converter_evdev_unittest.cc
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.
4
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <linux/input.h>
8 #include <unistd.h>
9
10 #include <vector>
11
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"
22
23 namespace {
24
25 static int SetNonBlocking(int fd) {
26   int flags = fcntl(fd, F_GETFL, 0);
27   if (flags == -1)
28     flags = 0;
29   return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
30 }
31
32 const char kTestDevicePath[] = "/dev/input/test-device";
33
34 }  // namespace
35
36 namespace ui {
37
38 class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
39  public:
40   MockTouchEventConverterEvdev(int fd, base::FilePath path);
41   virtual ~MockTouchEventConverterEvdev() {};
42
43   void ConfigureReadMock(struct input_event* queue,
44                          long read_this_many,
45                          long queue_index);
46
47   unsigned size() { return dispatched_events_.size(); }
48   TouchEvent* event(unsigned index) { return dispatched_events_[index]; }
49
50   // Actually dispatch the event reader code.
51   void ReadNow() {
52     OnFileCanReadWithoutBlocking(read_pipe_);
53     base::RunLoop().RunUntilIdle();
54   }
55
56   void DispatchCallback(Event* event) {
57     dispatched_events_.push_back(
58         new TouchEvent(*static_cast<TouchEvent*>(event)));
59   }
60
61   bool Reinitialize() OVERRIDE { return true; }
62
63  private:
64   int read_pipe_;
65   int write_pipe_;
66
67   ScopedVector<TouchEvent> dispatched_events_;
68
69   DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev);
70 };
71
72 MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(int fd,
73                                                            base::FilePath path)
74     : TouchEventConverterEvdev(
75           fd,
76           path,
77           EventDeviceInfo(),
78           base::Bind(&MockTouchEventConverterEvdev::DispatchCallback,
79                      base::Unretained(this))) {
80   pressure_min_ = 30;
81   pressure_max_ = 60;
82
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();
88
89   int fds[2];
90
91   if (pipe(fds))
92     PLOG(FATAL) << "failed pipe";
93
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;
98   read_pipe_ = fds[0];
99   write_pipe_ = fds[1];
100 }
101
102 void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
103                                                      long read_this_many,
104                                                      long queue_index) {
105   int nwrite = HANDLE_EINTR(write(write_pipe_,
106                                   queue + queue_index,
107                                   sizeof(struct input_event) * read_this_many));
108   DCHECK(nwrite ==
109          static_cast<int>(sizeof(struct input_event) * read_this_many))
110       << "write() failed, errno: " << errno;
111 }
112
113 }  // namespace ui
114
115 // Test fixture.
116 class TouchEventConverterEvdevTest : public testing::Test {
117  public:
118   TouchEventConverterEvdevTest() {}
119
120   // Overridden from testing::Test:
121   virtual void SetUp() OVERRIDE {
122     // Set up pipe to satisfy message pump (unused).
123     int evdev_io[2];
124     if (pipe(evdev_io))
125       PLOG(FATAL) << "failed pipe";
126     events_in_ = evdev_io[0];
127     events_out_ = evdev_io[1];
128
129     loop_ = new base::MessageLoopForUI;
130     device_ = new ui::MockTouchEventConverterEvdev(
131         events_in_, base::FilePath(kTestDevicePath));
132   }
133
134   virtual void TearDown() OVERRIDE {
135     delete device_;
136     delete loop_;
137   }
138
139   ui::MockTouchEventConverterEvdev* device() { return device_; }
140
141  private:
142   base::MessageLoop* loop_;
143   ui::MockTouchEventConverterEvdev* device_;
144
145   int events_out_;
146   int events_in_;
147
148   DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTest);
149 };
150
151 // TODO(rjkroege): Test for valid handling of time stamps.
152 TEST_F(TouchEventConverterEvdevTest, TouchDown) {
153   ui::MockTouchEventConverterEvdev* dev = device();
154
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}
161   };
162
163   dev->ConfigureReadMock(mock_kernel_queue, 1, 0);
164   dev->ReadNow();
165   EXPECT_EQ(0u, dev->size());
166
167   dev->ConfigureReadMock(mock_kernel_queue, 2, 1);
168   dev->ReadNow();
169   EXPECT_EQ(0u, dev->size());
170
171   dev->ConfigureReadMock(mock_kernel_queue, 3, 3);
172   dev->ReadNow();
173   EXPECT_EQ(1u, dev->size());
174
175   ui::TouchEvent* event = dev->event(0);
176   EXPECT_FALSE(event == NULL);
177
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());
185 }
186
187 TEST_F(TouchEventConverterEvdevTest, NoEvents) {
188   ui::MockTouchEventConverterEvdev* dev = device();
189   dev->ConfigureReadMock(NULL, 0, 0);
190   EXPECT_EQ(0u, dev->size());
191 }
192
193 TEST_F(TouchEventConverterEvdevTest, TouchMove) {
194   ui::MockTouchEventConverterEvdev* dev = device();
195
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}
202   };
203
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}
208   };
209
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}
212   };
213
214   // Setup and discard a press.
215   dev->ConfigureReadMock(mock_kernel_queue_press, 6, 0);
216   dev->ReadNow();
217   EXPECT_EQ(1u, dev->size());
218
219   dev->ConfigureReadMock(mock_kernel_queue_move1, 4, 0);
220   dev->ReadNow();
221   EXPECT_EQ(2u, dev->size());
222   ui::TouchEvent* event = dev->event(1);
223   EXPECT_FALSE(event == NULL);
224
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());
232
233   dev->ConfigureReadMock(mock_kernel_queue_move2, 2, 0);
234   dev->ReadNow();
235   EXPECT_EQ(3u, dev->size());
236   event = dev->event(2);
237   EXPECT_FALSE(event == NULL);
238
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());
246 }
247
248 TEST_F(TouchEventConverterEvdevTest, TouchRelease) {
249   ui::MockTouchEventConverterEvdev* dev = device();
250
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}
257   };
258
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}
261   };
262
263   // Setup and discard a press.
264   dev->ConfigureReadMock(mock_kernel_queue_press, 6, 0);
265   dev->ReadNow();
266   EXPECT_EQ(1u, dev->size());
267   ui::TouchEvent* event = dev->event(0);
268   EXPECT_FALSE(event == NULL);
269
270   dev->ConfigureReadMock(mock_kernel_queue_release, 2, 0);
271   dev->ReadNow();
272   EXPECT_EQ(2u, dev->size());
273   event = dev->event(1);
274   EXPECT_FALSE(event == NULL);
275
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());
283 }
284
285 TEST_F(TouchEventConverterEvdevTest, TwoFingerGesture) {
286   ui::MockTouchEventConverterEvdev* dev = device();
287
288   ui::TouchEvent* ev0;
289   ui::TouchEvent* ev1;
290
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}
297   };
298   // Setup and discard a press.
299   dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
300   dev->ReadNow();
301   EXPECT_EQ(1u, dev->size());
302
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}
305   };
306   // Setup and discard a move.
307   dev->ConfigureReadMock(mock_kernel_queue_move0, 2, 0);
308   dev->ReadNow();
309   EXPECT_EQ(2u, dev->size());
310
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}
318   };
319   // Move on 0, press on 1.
320   dev->ConfigureReadMock(mock_kernel_queue_move0press1, 9, 0);
321   dev->ReadNow();
322   EXPECT_EQ(4u, dev->size());
323   ev0 = dev->event(2);
324   ev1 = dev->event(3);
325
326   // Move
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());
334
335   // Press
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());
343
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}
347   };
348   dev->ConfigureReadMock(mock_kernel_queue_stationary0_move1, 2, 0);
349   dev->ReadNow();
350   EXPECT_EQ(5u, dev->size());
351   ev1 = dev->event(4);
352
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());
358
359   EXPECT_FLOAT_EQ(.5f, ev1->force());
360   EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
361
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}
366   };
367   dev->ConfigureReadMock(mock_kernel_queue_move0_stationary1, 3, 0);
368   dev->ReadNow();
369   EXPECT_EQ(6u, dev->size());
370   ev0 = dev->event(5);
371
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());
379
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}
384   };
385   dev->ConfigureReadMock(mock_kernel_queue_release0_move1, 4, 0);
386   dev->ReadNow();
387   EXPECT_EQ(8u, dev->size());
388   ev0 = dev->event(6);
389   ev1 = dev->event(7);
390
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());
398
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());
406
407   // Release 1.
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},
410   };
411   dev->ConfigureReadMock(mock_kernel_queue_release1, 2, 0);
412   dev->ReadNow();
413   EXPECT_EQ(9u, dev->size());
414   ev1 = dev->event(8);
415
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());
423 }
424
425 TEST_F(TouchEventConverterEvdevTest, TypeA) {
426   ui::MockTouchEventConverterEvdev* dev = device();
427
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}
439   };
440
441   // Check that two events are generated.
442   dev->ConfigureReadMock(mock_kernel_queue_press0, 10, 0);
443   dev->ReadNow();
444   EXPECT_EQ(2u, dev->size());
445 }
446
447 TEST_F(TouchEventConverterEvdevTest, Unsync) {
448   ui::MockTouchEventConverterEvdev* dev = device();
449
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}
456   };
457
458   dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
459   dev->ReadNow();
460   EXPECT_EQ(1u, dev->size());
461
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}
466   };
467
468   // Verify that we didn't receive it/
469   dev->ConfigureReadMock(mock_kernel_queue_move0, 3, 0);
470   dev->ReadNow();
471   EXPECT_EQ(1u, dev->size());
472
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}
475   };
476
477   // Verify that it re-syncs after a SYN_REPORT.
478   dev->ConfigureReadMock(mock_kernel_queue_move1, 2, 0);
479   dev->ReadNow();
480   EXPECT_EQ(2u, dev->size());
481 }