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

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

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 months 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
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/command_line.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/posix/eintr_wrapper.h"
17 #include "base/run_loop.h"
18 #include "base/time/time.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/events/devices/device_data_manager.h"
21 #include "ui/events/event_switches.h"
22 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
23 #include "ui/events/ozone/evdev/event_device_test_util.h"
24 #include "ui/events/ozone/evdev/touch_evdev_types.h"
25 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
26 #include "ui/events/ozone/evdev/touch_noise/touch_noise_filter.h"
27 #include "ui/events/ozone/evdev/touch_noise/touch_noise_finder.h"
28 #include "ui/events/platform/platform_event_dispatcher.h"
29 #include "ui/events/platform/platform_event_source.h"
30
31 namespace ui {
32
33 namespace {
34
35 static int SetNonBlocking(int fd) {
36 int flags = fcntl(fd, F_GETFL, 0);
37 if (flags == -1)
38 flags = 0;
39 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
40 }
41
42 const char kTestDevicePath[] = "/dev/input/test-device";
43
44 void InitPixelTouchscreen(TouchEventConverterEvdev* device) {
45 EventDeviceInfo devinfo;
46 EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &devinfo));
47 device->Initialize(devinfo);
48 }
49
50 void InitEloTouchscreen(TouchEventConverterEvdev* device) {
51 EventDeviceInfo devinfo;
52 EXPECT_TRUE(CapabilitiesToDeviceInfo(kElo_TouchSystems_2700, &devinfo));
53 device->Initialize(devinfo);
54 }
55
56 } // namespace
57
58 class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
59 public:
60 MockTouchEventConverterEvdev(int fd,
61 base::FilePath path,
62 const EventDeviceInfo& devinfo,
63 DeviceEventDispatcherEvdev* dispatcher);
64 ~MockTouchEventConverterEvdev() override;
65
66 void ConfigureReadMock(struct input_event* queue,
67 long read_this_many,
68 long queue_index);
69
70 // Actually dispatch the event reader code.
71 void ReadNow() {
72 OnFileCanReadWithoutBlocking(read_pipe_);
73 base::RunLoop().RunUntilIdle();
74 }
75
76 void SimulateReinitialize(const EventDeviceInfo& devinfo) {
77 Initialize(devinfo);
78 }
79
80 void Reinitialize() override {}
81
82 TouchNoiseFinder* touch_noise_finder() { return touch_noise_finder_.get(); }
83
84 private:
85 int read_pipe_;
86 int write_pipe_;
87
88 DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev);
89 };
90
91 class MockDeviceEventDispatcherEvdev : public DeviceEventDispatcherEvdev {
92 public:
93 MockDeviceEventDispatcherEvdev(
94 const base::Callback<void(const TouchEventParams& params)>& callback)
95 : callback_(callback) {}
96 ~MockDeviceEventDispatcherEvdev() override {}
97
98 // DeviceEventDispatcherEvdev:
99 void DispatchKeyEvent(const KeyEventParams& params) override {}
100 void DispatchMouseMoveEvent(const MouseMoveEventParams& params) override {}
101 void DispatchMouseButtonEvent(const MouseButtonEventParams& params) override {
102 }
103 void DispatchMouseWheelEvent(const MouseWheelEventParams& params) override {}
104 void DispatchScrollEvent(const ScrollEventParams& params) override {}
105 void DispatchTouchEvent(const TouchEventParams& params) override {
106 callback_.Run(params);
107 }
108
109 void DispatchKeyboardDevicesUpdated(
110 const std::vector<KeyboardDevice>& devices) override {}
111 void DispatchTouchscreenDevicesUpdated(
112 const std::vector<TouchscreenDevice>& devices) override {}
113 void DispatchMouseDevicesUpdated(
114 const std::vector<InputDevice>& devices) override {}
115 void DispatchTouchpadDevicesUpdated(
116 const std::vector<InputDevice>& devices) override {}
117 void DispatchDeviceListsComplete() override {}
118
119 private:
120 base::Callback<void(const TouchEventParams& params)> callback_;
121 };
122
123 MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
124 int fd,
125 base::FilePath path,
126 const EventDeviceInfo& devinfo,
127 DeviceEventDispatcherEvdev* dispatcher)
128 : TouchEventConverterEvdev(fd,
129 path,
130 1,
131 INPUT_DEVICE_UNKNOWN,
132 devinfo,
133 dispatcher) {
134 int fds[2];
135
136 if (pipe(fds))
137 PLOG(FATAL) << "failed pipe";
138
139 EXPECT_FALSE(SetNonBlocking(fds[0]) || SetNonBlocking(fds[1]))
140 << "failed to set non-blocking: " << strerror(errno);
141
142 read_pipe_ = fds[0];
143 write_pipe_ = fds[1];
144
145 events_.resize(ui::kNumTouchEvdevSlots);
146 for (size_t i = 0; i < events_.size(); ++i)
147 events_[i].slot = i;
148
149 SetEnabled(true);
150 }
151
152 MockTouchEventConverterEvdev::~MockTouchEventConverterEvdev() {
153 SetEnabled(false);
154 }
155
156 void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
157 long read_this_many,
158 long queue_index) {
159 int nwrite = HANDLE_EINTR(write(write_pipe_,
160 queue + queue_index,
161 sizeof(struct input_event) * read_this_many));
162 DCHECK(nwrite ==
163 static_cast<int>(sizeof(struct input_event) * read_this_many))
164 << "write() failed, errno: " << errno;
165 }
166
167 // Test fixture.
168 class TouchEventConverterEvdevTest : public testing::Test {
169 public:
170 TouchEventConverterEvdevTest() {}
171
172 // Overridden from testing::Test:
173 void SetUp() override {
174 // Set up pipe to satisfy message pump (unused).
175 int evdev_io[2];
176 if (pipe(evdev_io))
177 PLOG(FATAL) << "failed pipe";
178 events_in_ = evdev_io[0];
179 events_out_ = evdev_io[1];
180
181 // Device creation happens on a worker thread since it may involve blocking
182 // operations. Simulate that by creating it before creating a UI message
183 // loop.
184 EventDeviceInfo devinfo;
185 dispatcher_.reset(new ui::MockDeviceEventDispatcherEvdev(
186 base::Bind(&TouchEventConverterEvdevTest::DispatchCallback,
187 base::Unretained(this))));
188 device_.reset(new ui::MockTouchEventConverterEvdev(
189 events_in_, base::FilePath(kTestDevicePath), devinfo,
190 dispatcher_.get()));
191 loop_ = new base::MessageLoopForUI;
192
193 ui::DeviceDataManager::CreateInstance();
194 }
195
196 void TearDown() override {
197 device_.reset();
198 delete loop_;
199 }
200
201 ui::MockTouchEventConverterEvdev* device() { return device_.get(); }
202
203 unsigned size() { return dispatched_events_.size(); }
204 const ui::TouchEventParams& dispatched_event(unsigned index) {
205 DCHECK_GT(dispatched_events_.size(), index);
206 return dispatched_events_[index];
207 }
208
209 void ClearDispatchedEvents() { dispatched_events_.clear(); }
210
211 void DestroyDevice() { device_.reset(); }
212
213 private:
214 base::MessageLoop* loop_;
215 scoped_ptr<ui::MockTouchEventConverterEvdev> device_;
216 scoped_ptr<ui::MockDeviceEventDispatcherEvdev> dispatcher_;
217
218 int events_out_;
219 int events_in_;
220
221 void DispatchCallback(const ui::TouchEventParams& params) {
222 dispatched_events_.push_back(params);
223 }
224 std::vector<ui::TouchEventParams> dispatched_events_;
225
226 DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTest);
227 };
228
229 TEST_F(TouchEventConverterEvdevTest, NoEvents) {
230 ui::MockTouchEventConverterEvdev* dev = device();
231 dev->ConfigureReadMock(NULL, 0, 0);
232 EXPECT_EQ(0u, size());
233 }
234
235 TEST_F(TouchEventConverterEvdevTest, TouchMove) {
236 ui::MockTouchEventConverterEvdev* dev = device();
237
238 InitPixelTouchscreen(dev);
239
240 // Captured from Chromebook Pixel (Link).
241 timeval time;
242 time = {1427323282, 19203};
243 struct input_event mock_kernel_queue_press[] = {
244 {time, EV_ABS, ABS_MT_TRACKING_ID, 3},
245 {time, EV_ABS, ABS_MT_POSITION_X, 295},
246 {time, EV_ABS, ABS_MT_POSITION_Y, 421},
247 {time, EV_ABS, ABS_MT_PRESSURE, 34},
248 {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116},
249 {time, EV_KEY, BTN_TOUCH, 1},
250 {time, EV_ABS, ABS_X, 295},
251 {time, EV_ABS, ABS_Y, 421},
252 {time, EV_ABS, ABS_PRESSURE, 34},
253 {time, EV_SYN, SYN_REPORT, 0},
254 };
255 time = {1427323282, 34693};
256 struct input_event mock_kernel_queue_move[] = {
257 {time, EV_ABS, ABS_MT_POSITION_X, 312},
258 {time, EV_ABS, ABS_MT_POSITION_Y, 432},
259 {time, EV_ABS, ABS_MT_PRESSURE, 43},
260 {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 100},
261 {time, EV_ABS, ABS_X, 312},
262 {time, EV_ABS, ABS_Y, 432},
263 {time, EV_ABS, ABS_PRESSURE, 43},
264 {time, EV_SYN, SYN_REPORT, 0},
265 };
266 time = {1427323282, 144540};
267 struct input_event mock_kernel_queue_release[] = {
268 {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
269 {time, EV_KEY, BTN_TOUCH, 0},
270 {time, EV_ABS, ABS_PRESSURE, 0},
271 {time, EV_SYN, SYN_REPORT, 0},
272 };
273
274 // Press.
275 dev->ConfigureReadMock(mock_kernel_queue_press,
276 arraysize(mock_kernel_queue_press), 0);
277 dev->ReadNow();
278 EXPECT_EQ(1u, size());
279 ui::TouchEventParams event = dispatched_event(0);
280 EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type);
281 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282019203),
282 event.timestamp);
283 EXPECT_EQ(295, event.location.x());
284 EXPECT_EQ(421, event.location.y());
285 EXPECT_EQ(0, event.slot);
286 EXPECT_FLOAT_EQ(58.f, event.radii.x());
287 EXPECT_FLOAT_EQ(0.13333334f, event.pressure);
288
289 // Move.
290 dev->ConfigureReadMock(mock_kernel_queue_move,
291 arraysize(mock_kernel_queue_move), 0);
292 dev->ReadNow();
293 EXPECT_EQ(2u, size());
294 event = dispatched_event(1);
295 EXPECT_EQ(ui::ET_TOUCH_MOVED, event.type);
296 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282034693),
297 event.timestamp);
298 EXPECT_EQ(312, event.location.x());
299 EXPECT_EQ(432, event.location.y());
300 EXPECT_EQ(0, event.slot);
301 EXPECT_FLOAT_EQ(50.f, event.radii.x());
302 EXPECT_FLOAT_EQ(0.16862745f, event.pressure);
303
304 // Release.
305 dev->ConfigureReadMock(mock_kernel_queue_release,
306 arraysize(mock_kernel_queue_release), 0);
307 dev->ReadNow();
308 EXPECT_EQ(3u, size());
309 event = dispatched_event(2);
310 EXPECT_EQ(ui::ET_TOUCH_RELEASED, event.type);
311 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282144540),
312 event.timestamp);
313 EXPECT_EQ(312, event.location.x());
314 EXPECT_EQ(432, event.location.y());
315 EXPECT_EQ(0, event.slot);
316 EXPECT_FLOAT_EQ(50.f, event.radii.x());
317 EXPECT_FLOAT_EQ(0.16862745f, event.pressure);
318 }
319
320 TEST_F(TouchEventConverterEvdevTest, TwoFingerGesture) {
321 ui::MockTouchEventConverterEvdev* dev = device();
322
323 InitPixelTouchscreen(dev);
324
325 struct input_event mock_kernel_queue_press0[] = {
326 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
327 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
328 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
329 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
330 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
331 };
332 // Setup and discard a press.
333 dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
334 dev->ReadNow();
335 EXPECT_EQ(1u, size());
336
337 struct input_event mock_kernel_queue_move0[] = {
338 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
339 };
340 // Setup and discard a move.
341 dev->ConfigureReadMock(mock_kernel_queue_move0, 2, 0);
342 dev->ReadNow();
343 EXPECT_EQ(2u, size());
344
345 struct input_event mock_kernel_queue_move0press1[] = {
346 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
347 {{0, 0}, EV_ABS, ABS_MT_SLOT, 1}, {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 686},
348 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
349 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
350 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 101},
351 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 102}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
352 };
353 // Move on 0, press on 1.
354 dev->ConfigureReadMock(mock_kernel_queue_move0press1, 9, 0);
355 dev->ReadNow();
356 EXPECT_EQ(4u, size());
357 ui::TouchEventParams ev0 = dispatched_event(2);
358 ui::TouchEventParams ev1 = dispatched_event(3);
359
360 // Move
361 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0.type);
362 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0.timestamp);
363 EXPECT_EQ(40, ev0.location.x());
364 EXPECT_EQ(51, ev0.location.y());
365 EXPECT_EQ(0, ev0.slot);
366 EXPECT_FLOAT_EQ(0.17647059f, ev0.pressure);
367
368 // Press
369 EXPECT_EQ(ui::ET_TOUCH_PRESSED, ev1.type);
370 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
371 EXPECT_EQ(101, ev1.location.x());
372 EXPECT_EQ(102, ev1.location.y());
373 EXPECT_EQ(1, ev1.slot);
374 EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
375
376 // Stationary 0, Moves 1.
377 struct input_event mock_kernel_queue_stationary0_move1[] = {
378 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
379 };
380 dev->ConfigureReadMock(mock_kernel_queue_stationary0_move1, 2, 0);
381 dev->ReadNow();
382 EXPECT_EQ(5u, size());
383 ev1 = dispatched_event(4);
384
385 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1.type);
386 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
387 EXPECT_EQ(40, ev1.location.x());
388 EXPECT_EQ(102, ev1.location.y());
389 EXPECT_EQ(1, ev1.slot);
390 EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
391
392 // Move 0, stationary 1.
393 struct input_event mock_kernel_queue_move0_stationary1[] = {
394 {{0, 0}, EV_ABS, ABS_MT_SLOT, 0}, {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 39},
395 {{0, 0}, EV_SYN, SYN_REPORT, 0}
396 };
397 dev->ConfigureReadMock(mock_kernel_queue_move0_stationary1, 3, 0);
398 dev->ReadNow();
399 EXPECT_EQ(6u, size());
400 ev0 = dispatched_event(5);
401
402 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0.type);
403 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0.timestamp);
404 EXPECT_EQ(39, ev0.location.x());
405 EXPECT_EQ(51, ev0.location.y());
406 EXPECT_EQ(0, ev0.slot);
407 EXPECT_FLOAT_EQ(0.17647059f, ev0.pressure);
408
409 // Release 0, move 1.
410 struct input_event mock_kernel_queue_release0_move1[] = {
411 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_ABS, ABS_MT_SLOT, 1},
412 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 38}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
413 };
414 dev->ConfigureReadMock(mock_kernel_queue_release0_move1, 4, 0);
415 dev->ReadNow();
416 EXPECT_EQ(8u, size());
417 ev0 = dispatched_event(6);
418 ev1 = dispatched_event(7);
419
420 EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev0.type);
421 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0.timestamp);
422 EXPECT_EQ(39, ev0.location.x());
423 EXPECT_EQ(51, ev0.location.y());
424 EXPECT_EQ(0, ev0.slot);
425 EXPECT_FLOAT_EQ(0.17647059f, ev0.pressure);
426
427 EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1.type);
428 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
429 EXPECT_EQ(38, ev1.location.x());
430 EXPECT_EQ(102, ev1.location.y());
431 EXPECT_EQ(1, ev1.slot);
432 EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
433
434 // Release 1.
435 struct input_event mock_kernel_queue_release1[] = {
436 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
437 };
438 dev->ConfigureReadMock(mock_kernel_queue_release1, 2, 0);
439 dev->ReadNow();
440 EXPECT_EQ(9u, size());
441 ev1 = dispatched_event(8);
442
443 EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev1.type);
444 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
445 EXPECT_EQ(38, ev1.location.x());
446 EXPECT_EQ(102, ev1.location.y());
447 EXPECT_EQ(1, ev1.slot);
448 EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
449 }
450
451 TEST_F(TouchEventConverterEvdevTest, Unsync) {
452 ui::MockTouchEventConverterEvdev* dev = device();
453
454 InitPixelTouchscreen(dev);
455
456 struct input_event mock_kernel_queue_press0[] = {
457 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
458 {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
459 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
460 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
461 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
462 };
463
464 dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
465 dev->ReadNow();
466 EXPECT_EQ(1u, size());
467
468 // Prepare a move with a drop.
469 struct input_event mock_kernel_queue_move0[] = {
470 {{0, 0}, EV_SYN, SYN_DROPPED, 0},
471 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
472 };
473
474 // Verify that we didn't receive it/
475 dev->ConfigureReadMock(mock_kernel_queue_move0, 3, 0);
476 dev->ReadNow();
477 EXPECT_EQ(1u, size());
478
479 struct input_event mock_kernel_queue_move1[] = {
480 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
481 };
482
483 // Verify that it re-syncs after a SYN_REPORT.
484 dev->ConfigureReadMock(mock_kernel_queue_move1, 2, 0);
485 dev->ReadNow();
486 EXPECT_EQ(2u, size());
487 }
488
489 TEST_F(TouchEventConverterEvdevTest, ShouldResumeExistingContactsOnStart) {
490 ui::MockTouchEventConverterEvdev* dev = device();
491
492 EventDeviceInfo devinfo;
493 EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &devinfo));
494
495 // Set up an existing contact in slot 0.
496 devinfo.SetAbsMtSlot(ABS_MT_TRACKING_ID, 0, 1);
497 devinfo.SetAbsMtSlot(ABS_MT_TOUCH_MAJOR, 0, 100);
498 devinfo.SetAbsMtSlot(ABS_MT_POSITION_X, 0, 100);
499 devinfo.SetAbsMtSlot(ABS_MT_POSITION_Y, 0, 100);
500 devinfo.SetAbsMtSlot(ABS_MT_PRESSURE, 0, 128);
501
502 // Initialize the device.
503 dev->Initialize(devinfo);
504
505 // Any report should suffice to dispatch the update.. do an empty one.
506 struct input_event mock_kernel_queue_empty_report[] = {
507 {{0, 0}, EV_SYN, SYN_REPORT, 0},
508 };
509
510 dev->ConfigureReadMock(mock_kernel_queue_empty_report,
511 arraysize(mock_kernel_queue_empty_report), 0);
512 dev->ReadNow();
513 EXPECT_EQ(1u, size());
514
515 ui::TouchEventParams ev = dispatched_event(0);
516 EXPECT_EQ(ET_TOUCH_PRESSED, ev.type);
517 EXPECT_EQ(0, ev.slot);
518 EXPECT_FLOAT_EQ(50.f, ev.radii.x());
519 EXPECT_FLOAT_EQ(0.f, ev.radii.y());
520 EXPECT_FLOAT_EQ(0.50196081f, ev.pressure);
521 }
522
523 TEST_F(TouchEventConverterEvdevTest, ShouldReleaseContactsOnStop) {
524 ui::MockTouchEventConverterEvdev* dev = device();
525
526 InitPixelTouchscreen(dev);
527
528 // Captured from Chromebook Pixel (Link).
529 timeval time;
530 time = {1429651083, 686882};
531 struct input_event mock_kernel_queue_press[] = {
532 {time, EV_ABS, ABS_MT_TRACKING_ID, 0},
533 {time, EV_ABS, ABS_MT_POSITION_X, 1003},
534 {time, EV_ABS, ABS_MT_POSITION_Y, 749},
535 {time, EV_ABS, ABS_MT_PRESSURE, 50},
536 {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116},
537 {time, EV_KEY, BTN_TOUCH, 1},
538 {time, EV_ABS, ABS_X, 1003},
539 {time, EV_ABS, ABS_Y, 749},
540 {time, EV_ABS, ABS_PRESSURE, 50},
541 {time, EV_SYN, SYN_REPORT, 0},
542 };
543
544 dev->ConfigureReadMock(mock_kernel_queue_press,
545 arraysize(mock_kernel_queue_press), 0);
546 dev->ReadNow();
547 EXPECT_EQ(1u, size());
548
549 ui::TouchEventParams ev1 = dispatched_event(0);
550 EXPECT_EQ(ET_TOUCH_PRESSED, ev1.type);
551 EXPECT_EQ(0, ev1.slot);
552
553 DestroyDevice();
554 EXPECT_EQ(2u, size());
555
556 ui::TouchEventParams ev2 = dispatched_event(1);
557 EXPECT_EQ(ET_TOUCH_RELEASED, ev2.type);
558 EXPECT_EQ(0, ev2.slot);
559 }
560
561 TEST_F(TouchEventConverterEvdevTest, ShouldRemoveContactsWhenDisabled) {
562 ui::MockTouchEventConverterEvdev* dev = device();
563
564 EventDeviceInfo devinfo;
565 EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &devinfo));
566
567 // Captured from Chromebook Pixel (Link).
568 timeval time;
569 time = {1429651083, 686882};
570 struct input_event mock_kernel_queue_press[] = {
571 {time, EV_ABS, ABS_MT_TRACKING_ID, 0},
572 {time, EV_ABS, ABS_MT_POSITION_X, 1003},
573 {time, EV_ABS, ABS_MT_POSITION_Y, 749},
574 {time, EV_ABS, ABS_MT_PRESSURE, 50},
575 {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116},
576 {time, EV_KEY, BTN_TOUCH, 1},
577 {time, EV_ABS, ABS_X, 1003},
578 {time, EV_ABS, ABS_Y, 749},
579 {time, EV_ABS, ABS_PRESSURE, 50},
580 {time, EV_SYN, SYN_REPORT, 0},
581 };
582
583 // Initialize the device.
584 dev->Initialize(devinfo);
585
586 dev->ConfigureReadMock(mock_kernel_queue_press,
587 arraysize(mock_kernel_queue_press), 0);
588 dev->ReadNow();
589 EXPECT_EQ(1u, size());
590
591 ui::TouchEventParams ev1 = dispatched_event(0);
592 EXPECT_EQ(ET_TOUCH_PRESSED, ev1.type);
593 EXPECT_EQ(0, ev1.slot);
594 EXPECT_EQ(1003, ev1.location.x());
595 EXPECT_EQ(749, ev1.location.y());
596
597 // Disable the device (should release the contact).
598 dev->SetEnabled(false);
599 EXPECT_EQ(2u, size());
600
601 ui::TouchEventParams ev2 = dispatched_event(1);
602 EXPECT_EQ(ET_TOUCH_RELEASED, ev2.type);
603 EXPECT_EQ(0, ev2.slot);
604
605 // Set up the previous contact in slot 0.
606 devinfo.SetAbsMtSlot(ABS_MT_TRACKING_ID, 0, 0);
607 devinfo.SetAbsMtSlot(ABS_MT_TOUCH_MAJOR, 0, 116);
608 devinfo.SetAbsMtSlot(ABS_MT_POSITION_X, 0, 1003);
609 devinfo.SetAbsMtSlot(ABS_MT_POSITION_Y, 0, 749);
610 devinfo.SetAbsMtSlot(ABS_MT_PRESSURE, 0, 50);
611
612 // Re-enable the device (should re-apply the contact).
613 dev->SimulateReinitialize(devinfo);
614 dev->SetEnabled(true);
615 EXPECT_EQ(3u, size());
616
617 ui::TouchEventParams ev3 = dispatched_event(2);
618 EXPECT_EQ(ET_TOUCH_PRESSED, ev3.type);
619 EXPECT_EQ(0, ev3.slot);
620 EXPECT_EQ(1003, ev3.location.x());
621 EXPECT_EQ(749, ev3.location.y());
622 }
623
624 // crbug.com/477695
625 TEST_F(TouchEventConverterEvdevTest, ShouldUseLeftButtonIfNoTouchButton) {
626 ui::MockTouchEventConverterEvdev* dev = device();
627
628 InitEloTouchscreen(dev);
629
630 // Captured from Elo TouchSystems 2700.
631 timeval time;
632 time = {1433965490, 837958};
633 struct input_event mock_kernel_queue_press[] = {
634 {time, EV_ABS, ABS_X, 3654},
635 {time, EV_ABS, ABS_Y, 1054},
636 {time, EV_ABS, ABS_MISC, 18},
637 {time, EV_SYN, SYN_REPORT, 0},
638
639 {time, EV_MSC, MSC_SCAN, 90001},
640 {time, EV_KEY, BTN_LEFT, 1},
641 {time, EV_ABS, ABS_Y, 1055},
642 {time, EV_ABS, ABS_MISC, 25},
643 {time, EV_SYN, SYN_REPORT, 0},
644 };
645 time = {1433965491, 1953};
646 struct input_event mock_kernel_queue_move[] = {
647 {time, EV_ABS, ABS_X, 3644},
648 {time, EV_ABS, ABS_Y, 1059},
649 {time, EV_ABS, ABS_MISC, 36},
650 {time, EV_SYN, SYN_REPORT, 0},
651 };
652 time = {1433965491, 225959};
653 struct input_event mock_kernel_queue_release[] = {
654 {time, EV_MSC, MSC_SCAN, 90001},
655 {time, EV_KEY, BTN_LEFT, 0},
656 {time, EV_ABS, ABS_MISC, 0},
657 {time, EV_SYN, SYN_REPORT, 0},
658 };
659
660 // Press.
661 dev->ConfigureReadMock(mock_kernel_queue_press,
662 arraysize(mock_kernel_queue_press), 0);
663 dev->ReadNow();
664 EXPECT_EQ(1u, size());
665 ui::TouchEventParams event = dispatched_event(0);
666 EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type);
667 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965490837958),
668 event.timestamp);
669 EXPECT_EQ(3654, event.location.x());
670 EXPECT_EQ(1055, event.location.y());
671 EXPECT_EQ(0, event.slot);
672 EXPECT_FLOAT_EQ(0.f, event.radii.x());
673 EXPECT_FLOAT_EQ(0.f, event.pressure);
674
675 // Move.
676 dev->ConfigureReadMock(mock_kernel_queue_move,
677 arraysize(mock_kernel_queue_move), 0);
678 dev->ReadNow();
679 EXPECT_EQ(2u, size());
680 event = dispatched_event(1);
681 EXPECT_EQ(ui::ET_TOUCH_MOVED, event.type);
682 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965491001953),
683 event.timestamp);
684 EXPECT_EQ(3644, event.location.x());
685 EXPECT_EQ(1059, event.location.y());
686 EXPECT_EQ(0, event.slot);
687 EXPECT_FLOAT_EQ(0.f, event.radii.x());
688 EXPECT_FLOAT_EQ(0.f, event.pressure);
689
690 // Release.
691 dev->ConfigureReadMock(mock_kernel_queue_release,
692 arraysize(mock_kernel_queue_release), 0);
693 dev->ReadNow();
694 EXPECT_EQ(3u, size());
695 event = dispatched_event(2);
696 EXPECT_EQ(ui::ET_TOUCH_RELEASED, event.type);
697 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965491225959),
698 event.timestamp);
699 EXPECT_EQ(3644, event.location.x());
700 EXPECT_EQ(1059, event.location.y());
701 EXPECT_EQ(0, event.slot);
702 EXPECT_FLOAT_EQ(0.f, event.radii.x());
703 EXPECT_FLOAT_EQ(0.f, event.pressure);
704
705 // No dispatch on destruction.
706 DestroyDevice();
707 EXPECT_EQ(3u, size());
708 }
709
710 // crbug.com/407386
711 TEST_F(TouchEventConverterEvdevTest,
712 DontChangeMultitouchPositionFromLegacyAxes) {
713 ui::MockTouchEventConverterEvdev* dev = device();
714
715 InitPixelTouchscreen(dev);
716
717 struct input_event mock_kernel_queue[] = {
718 {{0, 0}, EV_ABS, ABS_MT_SLOT, 0},
719 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 100},
720 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 999},
721 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 888},
722 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 55},
723 {{0, 0}, EV_ABS, ABS_MT_SLOT, 1},
724 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 200},
725 {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 44},
726 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 777},
727 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 666},
728 {{0, 0}, EV_ABS, ABS_X, 999},
729 {{0, 0}, EV_ABS, ABS_Y, 888},
730 {{0, 0}, EV_ABS, ABS_PRESSURE, 55},
731 {{0, 0}, EV_SYN, SYN_REPORT, 0},
732 };
733
734 // Check that two events are generated.
735 dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
736 dev->ReadNow();
737
738 const unsigned int kExpectedEventCount = 2;
739 EXPECT_EQ(kExpectedEventCount, size());
740 if (kExpectedEventCount != size())
741 return;
742
743 ui::TouchEventParams ev0 = dispatched_event(0);
744 ui::TouchEventParams ev1 = dispatched_event(1);
745
746 EXPECT_EQ(0, ev0.slot);
747 EXPECT_EQ(999, ev0.location.x());
748 EXPECT_EQ(888, ev0.location.y());
749 EXPECT_FLOAT_EQ(0.21568628f, ev0.pressure);
750
751 EXPECT_EQ(1, ev1.slot);
752 EXPECT_EQ(777, ev1.location.x());
753 EXPECT_EQ(666, ev1.location.y());
754 EXPECT_FLOAT_EQ(0.17254902f, ev1.pressure);
755 }
756
757 // crbug.com/446939
758 TEST_F(TouchEventConverterEvdevTest, CheckSlotLimit) {
759 ui::MockTouchEventConverterEvdev* dev = device();
760
761 struct input_event mock_kernel_queue[] = {
762 {{0, 0}, EV_ABS, ABS_MT_SLOT, 0},
763 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 100},
764 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 999},
765 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 888},
766 {{0, 0}, EV_ABS, ABS_MT_SLOT, ui::kNumTouchEvdevSlots},
767 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 200},
768 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 777},
769 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 666},
770 {{0, 0}, EV_SYN, SYN_REPORT, 0},
771 };
772
773 // Check that one 1 event is generated
774 dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
775 dev->ReadNow();
776 EXPECT_EQ(1u, size());
777 }
778
779 namespace {
780
781 // TouchNoiseFilter which:
782 // - Considers all events of type |noise_event_type| as noise.
783 // - Keeps track of the events that it receives.
784 class EventTypeTouchNoiseFilter : public TouchNoiseFilter {
785 public:
786 explicit EventTypeTouchNoiseFilter(EventType noise_event_type)
787 : noise_event_type_(noise_event_type) {}
788 ~EventTypeTouchNoiseFilter() override {}
789
790 // TouchNoiseFilter:
791 void Filter(const std::vector<InProgressTouchEvdev>& touches,
792 base::TimeDelta time,
793 std::bitset<kNumTouchEvdevSlots>* slots_with_noise) override {
794 for (const InProgressTouchEvdev& touch : touches) {
795 EventType event_type = EventTypeFromTouch(touch);
796 ++counts_[event_type];
797 if (event_type == noise_event_type_)
798 slots_with_noise->set(touch.slot);
799 }
800 }
801
802 // Returns the number of received events of |type|.
803 size_t num_events(EventType type) const {
804 std::map<EventType, size_t>::const_iterator it = counts_.find(type);
805 return it == counts_.end() ? 0u : it->second;
806 }
807
808 private:
809 EventType EventTypeFromTouch(const InProgressTouchEvdev& touch) const {
810 if (touch.touching)
811 return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED;
812 return touch.was_touching ? ET_TOUCH_RELEASED : ET_UNKNOWN;
813 }
814
815 EventType noise_event_type_;
816 std::map<EventType, size_t> counts_;
817
818 DISALLOW_COPY_AND_ASSIGN(EventTypeTouchNoiseFilter);
819 };
820
821 } // namespace
822
823 class TouchEventConverterEvdevTouchNoiseTest
824 : public TouchEventConverterEvdevTest {
825 public:
826 TouchEventConverterEvdevTouchNoiseTest() {}
827 ~TouchEventConverterEvdevTouchNoiseTest() override {}
828
829 // Makes the TouchNoiseFinder use |filter| and only |filter| to filter out
830 // touch noise.
831 void SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter> filter) {
832 TouchNoiseFinder* finder = device()->touch_noise_finder();
833 finder->filters_.clear();
834 finder->filters_.push_back(filter.release());
835 }
836
837 // Returns the first of TouchNoiseFinder's filters.
838 ui::TouchNoiseFilter* first_filter() {
839 TouchNoiseFinder* finder = device()->touch_noise_finder();
840 return finder->filters_.empty() ? nullptr : *finder->filters_.begin();
841 }
842
843 // TouchEventConverterEvdevTest:
844 void SetUp() override {
845 base::CommandLine::ForCurrentProcess()->AppendSwitch(
846 switches::kExtraTouchNoiseFiltering);
847 TouchEventConverterEvdevTest::SetUp();
848 }
849
850 private:
851 DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTouchNoiseTest);
852 };
853
854 // Test that if TouchNoiseFinder identifies an event for an in-progress touch as
855 // noise, that the event is converted to ET_TOUCH_CANCELLED and that all
856 // subsequent events for the in-progress touch are cancelled.
857 TEST_F(TouchEventConverterEvdevTouchNoiseTest, TouchNoiseFiltering) {
858 struct input_event mock_kernel_queue[] = {
859 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
860 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40},
861 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 41},
862 {{0, 0}, EV_SYN, SYN_REPORT, 0},
863
864 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
865 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 43},
866 {{0, 0}, EV_SYN, SYN_REPORT, 0},
867
868 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1},
869 {{0, 0}, EV_SYN, SYN_REPORT, 0}
870 };
871
872 MockTouchEventConverterEvdev* dev = device();
873 SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
874 new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED)));
875 dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
876 dev->ReadNow();
877 ASSERT_EQ(0u, size());
878
879 ClearDispatchedEvents();
880 SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
881 new EventTypeTouchNoiseFilter(ET_TOUCH_MOVED)));
882 dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
883 dev->ReadNow();
884 ASSERT_EQ(2u, size());
885 TouchEventParams event0 = dispatched_event(0);
886 EXPECT_EQ(ET_TOUCH_PRESSED, event0.type);
887 EXPECT_EQ(40, event0.location.x());
888 EXPECT_EQ(41, event0.location.y());
889 EXPECT_EQ(ET_TOUCH_CANCELLED, dispatched_event(1).type);
890
891 ClearDispatchedEvents();
892 SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
893 new EventTypeTouchNoiseFilter(ET_TOUCH_RELEASED)));
894 dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
895 dev->ReadNow();
896 ASSERT_EQ(3u, size());
897 event0 = dispatched_event(0);
898 EXPECT_EQ(ET_TOUCH_PRESSED, event0.type);
899 EXPECT_EQ(40, event0.location.x());
900 EXPECT_EQ(41, event0.location.y());
901 TouchEventParams event1 = dispatched_event(1);
902 EXPECT_EQ(ET_TOUCH_MOVED, event1.type);
903 EXPECT_EQ(42, event1.location.x());
904 EXPECT_EQ(43, event1.location.y());
905 EXPECT_EQ(ET_TOUCH_CANCELLED, dispatched_event(2).type);
906 }
907
908 // Test that TouchEventConverterEvdev keeps sending events to
909 // TouchNoiseFinder after the touch is canceled.
910 TEST_F(TouchEventConverterEvdevTouchNoiseTest,
911 DoNotSendTouchCancelsToTouchNoiseFinder) {
912 struct input_event mock_kernel_queue[] = {
913 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
914 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40},
915 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 41},
916 {{0, 0}, EV_SYN, SYN_REPORT, 0},
917
918 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
919 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 43},
920 {{0, 0}, EV_SYN, SYN_REPORT, 0},
921
922 {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 43},
923 {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 44},
924 {{0, 0}, EV_SYN, SYN_REPORT, 0},
925
926 {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1},
927 {{0, 0}, EV_SYN, SYN_REPORT, 0}
928 };
929
930 MockTouchEventConverterEvdev* dev = device();
931 SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
932 new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED)));
933 dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
934 dev->ReadNow();
935 ASSERT_EQ(0u, size());
936
937 EventTypeTouchNoiseFilter* filter =
938 static_cast<EventTypeTouchNoiseFilter*>(first_filter());
939 EXPECT_EQ(1u, filter->num_events(ET_TOUCH_PRESSED));
940 EXPECT_EQ(2u, filter->num_events(ET_TOUCH_MOVED));
941 EXPECT_EQ(1u, filter->num_events(ET_TOUCH_RELEASED));
942 }
943
944 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698