Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: ui/events/ozone/evdev/tablet_event_converter_evdev_unittest.cc

Issue 721823002: ozone: Interpret absolute events for graphics tablets (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@o
Patch Set: Add missing initialisers for class members on TabletEventConverterEvdev Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/ozone/evdev/tablet_event_converter_evdev.cc ('k') | ui/events/ozone/events_ozone.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/bind.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.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/tablet_event_converter_evdev.h"
21 #include "ui/events/platform/platform_event_dispatcher.h"
22 #include "ui/events/platform/platform_event_source.h"
23
24 namespace {
25
26 static int SetNonBlocking(int fd) {
27 int flags = fcntl(fd, F_GETFL, 0);
28 if (flags == -1)
29 flags = 0;
30 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
31 }
32
33 const char kTestDevicePath[] = "/dev/input/test-device";
34
35 } // namespace
36
37 namespace ui {
38
39 class MockTabletEventConverterEvdev : public TabletEventConverterEvdev {
40 public:
41 MockTabletEventConverterEvdev(int fd,
42 base::FilePath path,
43 EventModifiersEvdev* modifiers,
44 CursorDelegateEvdev* cursor);
45 virtual ~MockTabletEventConverterEvdev(){};
46
47 void ConfigureReadMock(struct input_event* queue,
48 long read_this_many,
49 long queue_index);
50
51 unsigned size() { return dispatched_events_.size(); }
52 MouseEvent* event(unsigned index) {
53 DCHECK_GT(dispatched_events_.size(), index);
54 Event* ev = dispatched_events_[index];
55 DCHECK(ev->IsMouseEvent());
56 return static_cast<MouseEvent*>(ev);
57 }
58
59 // Actually dispatch the event reader code.
60 void ReadNow() {
61 OnFileCanReadWithoutBlocking(read_pipe_);
62 base::RunLoop().RunUntilIdle();
63 }
64
65 void DispatchCallback(scoped_ptr<Event> event) {
66 dispatched_events_.push_back(event.release());
67 }
68
69 private:
70 int read_pipe_;
71 int write_pipe_;
72
73 ScopedVector<Event> dispatched_events_;
74
75 DISALLOW_COPY_AND_ASSIGN(MockTabletEventConverterEvdev);
76 };
77
78 class MockTabletCursorEvdev : public CursorDelegateEvdev {
79 public:
80 MockTabletCursorEvdev() { cursor_display_bounds_ = gfx::Rect(1024, 768); }
81 virtual ~MockTabletCursorEvdev() {}
82
83 // CursorDelegateEvdev:
84 void MoveCursorTo(gfx::AcceleratedWidget widget,
85 const gfx::PointF& location) override {
86 NOTREACHED();
87 }
88 void MoveCursorTo(const gfx::PointF& location) override {
89 cursor_location_ = location;
90 }
91 void MoveCursor(const gfx::Vector2dF& delta) override { NOTREACHED(); }
92 bool IsCursorVisible() override { return 1; }
93 gfx::PointF location() override { return cursor_location_; }
94 gfx::Rect GetCursorDisplayBounds() override { return cursor_display_bounds_; }
95
96 private:
97 gfx::PointF cursor_location_;
98 gfx::Rect cursor_display_bounds_;
99 DISALLOW_COPY_AND_ASSIGN(MockTabletCursorEvdev);
100 };
101
102 MockTabletEventConverterEvdev::MockTabletEventConverterEvdev(
103 int fd,
104 base::FilePath path,
105 EventModifiersEvdev* modifiers,
106 CursorDelegateEvdev* cursor)
107 : TabletEventConverterEvdev(
108 fd,
109 path,
110 1,
111 modifiers,
112 cursor,
113 EventDeviceInfo(),
114 base::Bind(&MockTabletEventConverterEvdev::DispatchCallback,
115 base::Unretained(this))) {
116 // Real values taken from Wacom Intuos 4
117 x_abs_min_ = 0;
118 x_abs_range_ = 65024;
119 y_abs_min_ = 0;
120 y_abs_range_ = 40640;
121
122 int fds[2];
123
124 if (pipe(fds))
125 PLOG(FATAL) << "failed pipe";
126
127 DCHECK(SetNonBlocking(fds[0]) == 0)
128 << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
129 DCHECK(SetNonBlocking(fds[1]) == 0)
130 << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
131 read_pipe_ = fds[0];
132 write_pipe_ = fds[1];
133 }
134
135 void MockTabletEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
136 long read_this_many,
137 long queue_index) {
138 int nwrite = HANDLE_EINTR(write(write_pipe_, queue + queue_index,
139 sizeof(struct input_event) * read_this_many));
140 DCHECK(nwrite ==
141 static_cast<int>(sizeof(struct input_event) * read_this_many))
142 << "write() failed, errno: " << errno;
143 }
144
145 } // namespace ui
146
147 // Test fixture.
148 class TabletEventConverterEvdevTest : public testing::Test {
149 public:
150 TabletEventConverterEvdevTest() {}
151
152 // Overridden from testing::Test:
153 virtual void SetUp() override {
154 // Set up pipe to satisfy message pump (unused).
155 int evdev_io[2];
156 if (pipe(evdev_io))
157 PLOG(FATAL) << "failed pipe";
158 events_in_ = evdev_io[0];
159 events_out_ = evdev_io[1];
160
161 cursor_.reset(new ui::MockTabletCursorEvdev());
162 modifiers_.reset(new ui::EventModifiersEvdev());
163 device_.reset(new ui::MockTabletEventConverterEvdev(
164 events_in_, base::FilePath(kTestDevicePath), modifiers_.get(),
165 cursor_.get()));
166 }
167
168 virtual void TearDown() override {
169 modifiers_.reset();
170 cursor_.reset();
171 device_.reset();
172 }
173
174 ui::MockTabletEventConverterEvdev* device() { return device_.get(); }
175 ui::CursorDelegateEvdev* cursor() { return cursor_.get(); }
176 ui::EventModifiersEvdev* modifiers() { return modifiers_.get(); }
177
178 private:
179 scoped_ptr<ui::MockTabletEventConverterEvdev> device_;
180 scoped_ptr<ui::MockTabletCursorEvdev> cursor_;
181 scoped_ptr<ui::EventModifiersEvdev> modifiers_;
182
183 int events_out_;
184 int events_in_;
185
186 DISALLOW_COPY_AND_ASSIGN(TabletEventConverterEvdevTest);
187 };
188
189 #define EPSILON 20
190
191 // Uses real data captured from Wacom Intuos 4
192 TEST_F(TabletEventConverterEvdevTest, MoveTopLeft) {
193 ui::MockTabletEventConverterEvdev* dev = device();
194
195 struct input_event mock_kernel_queue[] = {
196 {{0, 0}, EV_ABS, ABS_Y, 616},
197 {{0, 0}, EV_ABS, ABS_DISTANCE, 62},
198 {{0, 0}, EV_ABS, ABS_TILT_X, 50},
199 {{0, 0}, EV_ABS, ABS_TILT_Y, 7},
200 {{0, 0}, EV_ABS, ABS_MISC, 1050626},
201 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
202 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
203 {{0, 0}, EV_SYN, SYN_REPORT, 0},
204 {{0, 0}, EV_ABS, ABS_Y, 0},
205 {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
206 {{0, 0}, EV_ABS, ABS_TILT_X, 0},
207 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
208 {{0, 0}, EV_ABS, ABS_MISC, 0},
209 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
210 {{0, 0}, EV_SYN, SYN_REPORT, 0},
211 };
212
213 dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
214 EXPECT_EQ(1u, dev->size());
215
216 ui::MouseEvent* event = dev->event(0);
217 EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
218
219 EXPECT_LT(cursor()->location().x(), EPSILON);
220 EXPECT_LT(cursor()->location().y(), EPSILON);
221 }
222
223 TEST_F(TabletEventConverterEvdevTest, MoveTopRight) {
224 ui::MockTabletEventConverterEvdev* dev = device();
225
226 struct input_event mock_kernel_queue[] = {
227 {{0, 0}, EV_ABS, ABS_X, 65024},
228 {{0, 0}, EV_ABS, ABS_Y, 33},
229 {{0, 0}, EV_ABS, ABS_DISTANCE, 62},
230 {{0, 0}, EV_ABS, ABS_TILT_X, 109},
231 {{0, 0}, EV_ABS, ABS_TILT_Y, 59},
232 {{0, 0}, EV_ABS, ABS_MISC, 1050626},
233 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
234 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
235 {{0, 0}, EV_SYN, SYN_REPORT, 0},
236 {{0, 0}, EV_ABS, ABS_X, 0},
237 {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
238 {{0, 0}, EV_ABS, ABS_TILT_X, 0},
239 {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
240 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
241 {{0, 0}, EV_ABS, ABS_MISC, 0},
242 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
243 {{0, 0}, EV_SYN, SYN_REPORT, 0},
244 };
245
246 dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
247 EXPECT_EQ(1u, dev->size());
248
249 ui::MouseEvent* event = dev->event(0);
250 EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
251
252 EXPECT_GT(cursor()->location().x(),
253 cursor()->GetCursorDisplayBounds().width() - EPSILON);
254 EXPECT_LT(cursor()->location().y(), EPSILON);
255 }
256
257 TEST_F(TabletEventConverterEvdevTest, MoveBottomLeft) {
258 ui::MockTabletEventConverterEvdev* dev = device();
259
260 struct input_event mock_kernel_queue[] = {
261 {{0, 0}, EV_ABS, ABS_Y, 40640},
262 {{0, 0}, EV_ABS, ABS_DISTANCE, 62},
263 {{0, 0}, EV_ABS, ABS_TILT_X, 95},
264 {{0, 0}, EV_ABS, ABS_TILT_Y, 44},
265 {{0, 0}, EV_ABS, ABS_MISC, 1050626},
266 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
267 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
268 {{0, 0}, EV_SYN, SYN_REPORT, 0},
269 {{0, 0}, EV_ABS, ABS_Y, 0},
270 {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
271 {{0, 0}, EV_ABS, ABS_TILT_X, 0},
272 {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
273 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
274 {{0, 0}, EV_ABS, ABS_MISC, 0},
275 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
276 {{0, 0}, EV_SYN, SYN_REPORT, 0},
277 };
278
279 dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
280 EXPECT_EQ(1u, dev->size());
281
282 ui::MouseEvent* event = dev->event(0);
283 EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
284
285 EXPECT_LT(cursor()->location().x(), EPSILON);
286 EXPECT_GT(cursor()->location().y(),
287 cursor()->GetCursorDisplayBounds().height() - EPSILON);
288 }
289
290 TEST_F(TabletEventConverterEvdevTest, MoveBottomRight) {
291 ui::MockTabletEventConverterEvdev* dev = device();
292
293 struct input_event mock_kernel_queue[] = {
294 {{0, 0}, EV_ABS, ABS_X, 65024},
295 {{0, 0}, EV_ABS, ABS_Y, 40640},
296 {{0, 0}, EV_ABS, ABS_DISTANCE, 62},
297 {{0, 0}, EV_ABS, ABS_TILT_X, 127},
298 {{0, 0}, EV_ABS, ABS_TILT_Y, 89},
299 {{0, 0}, EV_ABS, ABS_MISC, 1050626},
300 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
301 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
302 {{0, 0}, EV_SYN, SYN_REPORT, 0},
303 {{0, 0}, EV_ABS, ABS_X, 0},
304 {{0, 0}, EV_ABS, ABS_Y, 0},
305 {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
306 {{0, 0}, EV_ABS, ABS_TILT_X, 0},
307 {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
308 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
309 {{0, 0}, EV_ABS, ABS_MISC, 0},
310 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
311 {{0, 0}, EV_SYN, SYN_REPORT, 0},
312 };
313
314 dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
315 EXPECT_EQ(1u, dev->size());
316
317 ui::MouseEvent* event = dev->event(0);
318 EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
319
320 EXPECT_GT(cursor()->location().x(),
321 cursor()->GetCursorDisplayBounds().height() - EPSILON);
322 EXPECT_GT(cursor()->location().y(),
323 cursor()->GetCursorDisplayBounds().height() - EPSILON);
324 }
325
326 TEST_F(TabletEventConverterEvdevTest, Tap) {
327 ui::MockTabletEventConverterEvdev* dev = device();
328
329 struct input_event mock_kernel_queue[] = {
330 {{0, 0}, EV_ABS, ABS_X, 31628},
331 {{0, 0}, EV_ABS, ABS_Y, 21670},
332 {{0, 0}, EV_ABS, ABS_DISTANCE, 62},
333 {{0, 0}, EV_ABS, ABS_TILT_X, 114},
334 {{0, 0}, EV_ABS, ABS_TILT_Y, 85},
335 {{0, 0}, EV_ABS, ABS_MISC, 1050626},
336 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
337 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
338 {{0, 0}, EV_SYN, SYN_REPORT, 0},
339 {{0, 0}, EV_ABS, ABS_X, 32094},
340 {{0, 0}, EV_ABS, ABS_DISTANCE, 17},
341 {{0, 0}, EV_ABS, ABS_PRESSURE, 883},
342 {{0, 0}, EV_ABS, ABS_TILT_Y, 68},
343 {{0, 0}, EV_KEY, BTN_TOUCH, 1},
344 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
345 {{0, 0}, EV_SYN, SYN_REPORT, 0},
346 {{0, 0}, EV_ABS, ABS_X, 32036},
347 {{0, 0}, EV_ABS, ABS_Y, 21658},
348 {{0, 0}, EV_ABS, ABS_DISTANCE, 19},
349 {{0, 0}, EV_ABS, ABS_PRESSURE, 0},
350 {{0, 0}, EV_KEY, BTN_TOUCH, 0},
351 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
352 {{0, 0}, EV_SYN, SYN_REPORT, 0},
353 {{0, 0}, EV_ABS, ABS_X, 0},
354 {{0, 0}, EV_ABS, ABS_Y, 0},
355 {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
356 {{0, 0}, EV_ABS, ABS_TILT_X, 0},
357 {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
358 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
359 {{0, 0}, EV_ABS, ABS_MISC, 0},
360 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
361 {{0, 0}, EV_SYN, SYN_REPORT, 0},
362 };
363
364 dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
365 EXPECT_EQ(3u, dev->size());
366
367 ui::MouseEvent* event = dev->event(0);
368 EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
369 event = dev->event(1);
370 EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type());
371 EXPECT_EQ(true, event->IsLeftMouseButton());
372 event = dev->event(2);
373 EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type());
374 EXPECT_EQ(true, event->IsLeftMouseButton());
375 }
376
377 TEST_F(TabletEventConverterEvdevTest, StylusButtonPress) {
378 ui::MockTabletEventConverterEvdev* dev = device();
379
380 struct input_event mock_kernel_queue[] = {
381 {{0, 0}, EV_ABS, ABS_X, 30055},
382 {{0, 0}, EV_ABS, ABS_Y, 18094},
383 {{0, 0}, EV_ABS, ABS_DISTANCE, 62},
384 {{0, 0}, EV_ABS, ABS_TILT_X, 99},
385 {{0, 0}, EV_ABS, ABS_TILT_Y, 68},
386 {{0, 0}, EV_ABS, ABS_MISC, 1050626},
387 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
388 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
389 {{0, 0}, EV_SYN, SYN_REPORT, 0},
390 {{0, 0}, EV_ABS, ABS_X, 29380},
391 {{0, 0}, EV_KEY, BTN_STYLUS2, 1},
392 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
393 {{0, 0}, EV_SYN, SYN_REPORT, 0},
394 {{0, 0}, EV_ABS, ABS_X, 29355},
395 {{0, 0}, EV_ABS, ABS_Y, 20091},
396 {{0, 0}, EV_ABS, ABS_DISTANCE, 34},
397 {{0, 0}, EV_KEY, BTN_STYLUS2, 0},
398 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
399 {{0, 0}, EV_SYN, SYN_REPORT, 0},
400 {{0, 0}, EV_ABS, ABS_X, 0},
401 {{0, 0}, EV_ABS, ABS_Y, 0},
402 {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
403 {{0, 0}, EV_ABS, ABS_TILT_X, 0},
404 {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
405 {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
406 {{0, 0}, EV_ABS, ABS_MISC, 0},
407 {{0, 0}, EV_MSC, MSC_SERIAL, 159403517},
408 {{0, 0}, EV_SYN, SYN_REPORT, 0},
409 };
410
411 dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
412 EXPECT_EQ(3u, dev->size());
413
414 ui::MouseEvent* event = dev->event(0);
415 EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
416 event = dev->event(1);
417 EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type());
418 EXPECT_EQ(true, event->IsRightMouseButton());
419 event = dev->event(2);
420 EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type());
421 EXPECT_EQ(true, event->IsRightMouseButton());
422 }
423
424 // Should only get an event if BTN_TOOL received
425 TEST_F(TabletEventConverterEvdevTest, CheckStylusFiltering) {
426 ui::MockTabletEventConverterEvdev* dev = device();
427
428 struct input_event mock_kernel_queue[] = {
429 {{0, 0}, EV_ABS, ABS_X, 0},
430 {{0, 0}, EV_ABS, ABS_Y, 0},
431 {{0, 0}, EV_SYN, SYN_REPORT, 0},
432 };
433
434 dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
435 EXPECT_EQ(0u, dev->size());
436 }
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/tablet_event_converter_evdev.cc ('k') | ui/events/ozone/events_ozone.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698