Upstream version 5.34.104.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/message_loop/message_pump_dispatcher.h"
15 #include "base/posix/eintr_wrapper.h"
16 #include "base/run_loop.h"
17 #include "base/time/time.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/events/event.h"
20 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
21
22 namespace {
23
24 static int SetNonBlocking(int fd) {
25   int flags = fcntl(fd, F_GETFL, 0);
26   if (flags == -1)
27     flags = 0;
28   return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
29 }
30
31 const char kTestDevicePath[] = "/dev/input/test-device";
32
33 }  // namespace
34
35 namespace ui {
36
37 class MockTouchEventConverterEvdev : public TouchEventConverterEvdev,
38                                      public base::MessagePumpDispatcher {
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   virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE;
57
58  private:
59   int read_pipe_;
60   int write_pipe_;
61
62   ScopedVector<TouchEvent> dispatched_events_;
63
64   DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev);
65 };
66
67 MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(int fd,
68                                                            base::FilePath path)
69     : TouchEventConverterEvdev(fd, path, EventDeviceInfo()) {
70   pressure_min_ = 30;
71   pressure_max_ = 60;
72
73   // TODO(rjkroege): Check test axes.
74   x_min_ = 0;
75   x_max_ = std::numeric_limits<int>::max();
76   y_min_ = 0;
77   y_max_ = std::numeric_limits<int>::max();
78
79   int fds[2];
80
81   if (pipe(fds))
82     NOTREACHED() << "failed pipe(): " << strerror(errno);
83
84   DCHECK(SetNonBlocking(fds[0]) == 0)
85       << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
86   DCHECK(SetNonBlocking(fds[1]) == 0)
87       << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
88   read_pipe_ = fds[0];
89   write_pipe_ = fds[1];
90 }
91
92 uint32_t MockTouchEventConverterEvdev::Dispatch(
93     const base::NativeEvent& event) {
94   ui::TouchEvent* ev = new ui::TouchEvent(event);
95   dispatched_events_.push_back(ev);
96   return POST_DISPATCH_NONE;
97 }
98
99 void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
100                                                      long read_this_many,
101                                                      long queue_index) {
102   int nwrite = HANDLE_EINTR(write(write_pipe_,
103                                   queue + queue_index,
104                                   sizeof(struct input_event) * read_this_many));
105   DCHECK(nwrite ==
106          static_cast<int>(sizeof(struct input_event) * read_this_many))
107       << "write() failed, errno: " << errno;
108 }
109
110 }  // namespace ui
111
112 // Test fixture.
113 class TouchEventConverterEvdevTest : public testing::Test {
114  public:
115   TouchEventConverterEvdevTest() {}
116
117   // Overridden from testing::Test:
118   virtual void SetUp() OVERRIDE {
119     // Set up pipe to satisfy message pump (unused).
120     int evdev_io[2];
121     if (pipe(evdev_io))
122       PLOG(FATAL) << "failed pipe";
123     events_in_ = evdev_io[0];
124     events_out_ = evdev_io[1];
125
126     loop_ = new base::MessageLoopForUI;
127     device_ = new ui::MockTouchEventConverterEvdev(
128         events_in_, base::FilePath(kTestDevicePath));
129     base::MessagePumpOzone::Current()->AddDispatcherForRootWindow(device_);
130   }
131   virtual void TearDown() OVERRIDE {
132     delete device_;
133     delete loop_;
134   }
135
136   ui::MockTouchEventConverterEvdev* device() { return device_; }
137
138  private:
139   base::MessageLoop* loop_;
140   ui::MockTouchEventConverterEvdev* device_;
141
142   int events_out_;
143   int events_in_;
144
145   DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTest);
146 };
147
148 // TODO(rjkroege): Test for valid handling of time stamps.
149 TEST_F(TouchEventConverterEvdevTest, TouchDown) {
150   ui::MockTouchEventConverterEvdev* dev = device();
151
152   struct input_event mock_kernel_queue[] = {
153     {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
154     {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
155     {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
156     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
157     {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
158   };
159
160   dev->ConfigureReadMock(mock_kernel_queue, 1, 0);
161   dev->ReadNow();
162   EXPECT_EQ(0u, dev->size());
163
164   dev->ConfigureReadMock(mock_kernel_queue, 2, 1);
165   dev->ReadNow();
166   EXPECT_EQ(0u, dev->size());
167
168   dev->ConfigureReadMock(mock_kernel_queue, 3, 3);
169   dev->ReadNow();
170   EXPECT_EQ(1u, dev->size());
171
172   ui::TouchEvent* event = dev->event(0);
173   EXPECT_FALSE(event == NULL);
174
175   EXPECT_EQ(ui::ET_TOUCH_PRESSED, event->type());
176   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
177   EXPECT_EQ(42, event->x());
178   EXPECT_EQ(51, event->y());
179   EXPECT_EQ(0, event->touch_id());
180   EXPECT_FLOAT_EQ(.5f, event->force());
181   EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
182 }
183
184 TEST_F(TouchEventConverterEvdevTest, NoEvents) {
185   ui::MockTouchEventConverterEvdev* dev = device();
186   dev->ConfigureReadMock(NULL, 0, 0);
187   EXPECT_EQ(0u, dev->size());
188 }
189
190 TEST_F(TouchEventConverterEvdevTest, TouchMove) {
191   ui::MockTouchEventConverterEvdev* dev = device();
192
193   struct input_event mock_kernel_queue_press[] = {
194     {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
195     {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
196     {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
197     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
198     {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
199   };
200
201   struct input_event mock_kernel_queue_move1[] = {
202     {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 50},
203     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
204     {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 43}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
205   };
206
207   struct input_event mock_kernel_queue_move2[] = {
208     {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 42}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
209   };
210
211   // Setup and discard a press.
212   dev->ConfigureReadMock(mock_kernel_queue_press, 6, 0);
213   dev->ReadNow();
214   EXPECT_EQ(1u, dev->size());
215
216   dev->ConfigureReadMock(mock_kernel_queue_move1, 4, 0);
217   dev->ReadNow();
218   EXPECT_EQ(2u, dev->size());
219   ui::TouchEvent* event = dev->event(1);
220   EXPECT_FALSE(event == NULL);
221
222   EXPECT_EQ(ui::ET_TOUCH_MOVED, event->type());
223   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
224   EXPECT_EQ(42, event->x());
225   EXPECT_EQ(43, event->y());
226   EXPECT_EQ(0, event->touch_id());
227   EXPECT_FLOAT_EQ(2.f / 3.f, event->force());
228   EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
229
230   dev->ConfigureReadMock(mock_kernel_queue_move2, 2, 0);
231   dev->ReadNow();
232   EXPECT_EQ(3u, dev->size());
233   event = dev->event(2);
234   EXPECT_FALSE(event == NULL);
235
236   EXPECT_EQ(ui::ET_TOUCH_MOVED, event->type());
237   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
238   EXPECT_EQ(42, event->x());
239   EXPECT_EQ(42, event->y());
240   EXPECT_EQ(0, event->touch_id());
241   EXPECT_FLOAT_EQ(2.f / 3.f, event->force());
242   EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
243 }
244
245 TEST_F(TouchEventConverterEvdevTest, TouchRelease) {
246   ui::MockTouchEventConverterEvdev* dev = device();
247
248   struct input_event mock_kernel_queue_press[] = {
249     {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
250     {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
251     {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
252     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
253     {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
254   };
255
256   struct input_event mock_kernel_queue_release[] = {
257     {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
258   };
259
260   // Setup and discard a press.
261   dev->ConfigureReadMock(mock_kernel_queue_press, 6, 0);
262   dev->ReadNow();
263   EXPECT_EQ(1u, dev->size());
264   ui::TouchEvent* event = dev->event(0);
265   EXPECT_FALSE(event == NULL);
266
267   dev->ConfigureReadMock(mock_kernel_queue_release, 2, 0);
268   dev->ReadNow();
269   EXPECT_EQ(2u, dev->size());
270   event = dev->event(1);
271   EXPECT_FALSE(event == NULL);
272
273   EXPECT_EQ(ui::ET_TOUCH_RELEASED, event->type());
274   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), event->time_stamp());
275   EXPECT_EQ(42, event->x());
276   EXPECT_EQ(51, event->y());
277   EXPECT_EQ(0, event->touch_id());
278   EXPECT_FLOAT_EQ(.5f, event->force());
279   EXPECT_FLOAT_EQ(0.f, event->rotation_angle());
280 }
281
282 TEST_F(TouchEventConverterEvdevTest, TwoFingerGesture) {
283   ui::MockTouchEventConverterEvdev* dev = device();
284
285   ui::TouchEvent* ev0;
286   ui::TouchEvent* ev1;
287
288   struct input_event mock_kernel_queue_press0[] = {
289     {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
290     {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
291     {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
292     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
293     {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
294   };
295   // Setup and discard a press.
296   dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
297   dev->ReadNow();
298   EXPECT_EQ(1u, dev->size());
299
300   struct input_event mock_kernel_queue_move0[] = {
301     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
302   };
303   // Setup and discard a move.
304   dev->ConfigureReadMock(mock_kernel_queue_move0, 2, 0);
305   dev->ReadNow();
306   EXPECT_EQ(2u, dev->size());
307
308   struct input_event mock_kernel_queue_move0press1[] = {
309     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
310     {{0, 0}, EV_ABS, ABS_MT_SLOT, 1}, {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 686},
311     {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
312     {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
313     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 101},
314     {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 102}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
315   };
316   // Move on 0, press on 1.
317   dev->ConfigureReadMock(mock_kernel_queue_move0press1, 9, 0);
318   dev->ReadNow();
319   EXPECT_EQ(4u, dev->size());
320   ev0 = dev->event(2);
321   ev1 = dev->event(3);
322
323   // Move
324   EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0->type());
325   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0->time_stamp());
326   EXPECT_EQ(40, ev0->x());
327   EXPECT_EQ(51, ev0->y());
328   EXPECT_EQ(0, ev0->touch_id());
329   EXPECT_FLOAT_EQ(.5f, ev0->force());
330   EXPECT_FLOAT_EQ(0.f, ev0->rotation_angle());
331
332   // Press
333   EXPECT_EQ(ui::ET_TOUCH_PRESSED, ev1->type());
334   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
335   EXPECT_EQ(101, ev1->x());
336   EXPECT_EQ(102, ev1->y());
337   EXPECT_EQ(1, ev1->touch_id());
338   EXPECT_FLOAT_EQ(.5f, ev1->force());
339   EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
340
341   // Stationary 0, Moves 1.
342   struct input_event mock_kernel_queue_stationary0_move1[] = {
343     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
344   };
345   dev->ConfigureReadMock(mock_kernel_queue_stationary0_move1, 2, 0);
346   dev->ReadNow();
347   EXPECT_EQ(5u, dev->size());
348   ev1 = dev->event(4);
349
350   EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1->type());
351   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
352   EXPECT_EQ(40, ev1->x());
353   EXPECT_EQ(102, ev1->y());
354   EXPECT_EQ(1, ev1->touch_id());
355
356   EXPECT_FLOAT_EQ(.5f, ev1->force());
357   EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
358
359   // Move 0, stationary 1.
360   struct input_event mock_kernel_queue_move0_stationary1[] = {
361     {{0, 0}, EV_ABS, ABS_MT_SLOT, 0}, {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 39},
362     {{0, 0}, EV_SYN, SYN_REPORT, 0}
363   };
364   dev->ConfigureReadMock(mock_kernel_queue_move0_stationary1, 3, 0);
365   dev->ReadNow();
366   EXPECT_EQ(6u, dev->size());
367   ev0 = dev->event(5);
368
369   EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0->type());
370   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0->time_stamp());
371   EXPECT_EQ(39, ev0->x());
372   EXPECT_EQ(51, ev0->y());
373   EXPECT_EQ(0, ev0->touch_id());
374   EXPECT_FLOAT_EQ(.5f, ev0->force());
375   EXPECT_FLOAT_EQ(0.f, ev0->rotation_angle());
376
377   // Release 0, move 1.
378   struct input_event mock_kernel_queue_release0_move1[] = {
379     {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_ABS, ABS_MT_SLOT, 1},
380     {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 38}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
381   };
382   dev->ConfigureReadMock(mock_kernel_queue_release0_move1, 4, 0);
383   dev->ReadNow();
384   EXPECT_EQ(8u, dev->size());
385   ev0 = dev->event(6);
386   ev1 = dev->event(7);
387
388   EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev0->type());
389   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0->time_stamp());
390   EXPECT_EQ(39, ev0->x());
391   EXPECT_EQ(51, ev0->y());
392   EXPECT_EQ(0, ev0->touch_id());
393   EXPECT_FLOAT_EQ(.5f, ev0->force());
394   EXPECT_FLOAT_EQ(0.f, ev0->rotation_angle());
395
396   EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1->type());
397   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
398   EXPECT_EQ(38, ev1->x());
399   EXPECT_EQ(102, ev1->y());
400   EXPECT_EQ(1, ev1->touch_id());
401   EXPECT_FLOAT_EQ(.5f, ev1->force());
402   EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
403
404   // Release 1.
405   struct input_event mock_kernel_queue_release1[] = {
406     {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
407   };
408   dev->ConfigureReadMock(mock_kernel_queue_release1, 2, 0);
409   dev->ReadNow();
410   EXPECT_EQ(9u, dev->size());
411   ev1 = dev->event(8);
412
413   EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev1->type());
414   EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1->time_stamp());
415   EXPECT_EQ(38, ev1->x());
416   EXPECT_EQ(102, ev1->y());
417   EXPECT_EQ(1, ev1->touch_id());
418   EXPECT_FLOAT_EQ(.5f, ev1->force());
419   EXPECT_FLOAT_EQ(0.f, ev1->rotation_angle());
420 }