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/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"
35 static int SetNonBlocking(int fd
) {
36 int flags
= fcntl(fd
, F_GETFL
, 0);
39 return fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
);
42 const char kTestDevicePath
[] = "/dev/input/test-device";
44 void InitPixelTouchscreen(TouchEventConverterEvdev
* device
) {
45 EventDeviceInfo devinfo
;
46 EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen
, &devinfo
));
47 device
->Initialize(devinfo
);
52 class MockTouchEventConverterEvdev
: public TouchEventConverterEvdev
{
54 MockTouchEventConverterEvdev(int fd
,
56 DeviceEventDispatcherEvdev
* dispatcher
);
57 ~MockTouchEventConverterEvdev() override
{}
59 void ConfigureReadMock(struct input_event
* queue
,
63 // Actually dispatch the event reader code.
65 OnFileCanReadWithoutBlocking(read_pipe_
);
66 base::RunLoop().RunUntilIdle();
69 bool Reinitialize() override
{ return true; }
71 TouchNoiseFinder
* touch_noise_finder() { return touch_noise_finder_
.get(); }
77 DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev
);
80 class MockDeviceEventDispatcherEvdev
: public DeviceEventDispatcherEvdev
{
82 MockDeviceEventDispatcherEvdev(
83 const base::Callback
<void(const TouchEventParams
& params
)>& callback
)
84 : callback_(callback
) {}
85 ~MockDeviceEventDispatcherEvdev() override
{}
87 // DeviceEventDispatcherEvdev:
88 void DispatchKeyEvent(const KeyEventParams
& params
) override
{}
89 void DispatchMouseMoveEvent(const MouseMoveEventParams
& params
) override
{}
90 void DispatchMouseButtonEvent(const MouseButtonEventParams
& params
) override
{
92 void DispatchMouseWheelEvent(const MouseWheelEventParams
& params
) override
{}
93 void DispatchScrollEvent(const ScrollEventParams
& params
) override
{}
94 void DispatchTouchEvent(const TouchEventParams
& params
) override
{
95 callback_
.Run(params
);
98 void DispatchKeyboardDevicesUpdated(
99 const std::vector
<KeyboardDevice
>& devices
) override
{}
100 void DispatchTouchscreenDevicesUpdated(
101 const std::vector
<TouchscreenDevice
>& devices
) override
{}
102 void DispatchMouseDevicesUpdated(
103 const std::vector
<InputDevice
>& devices
) override
{}
104 void DispatchTouchpadDevicesUpdated(
105 const std::vector
<InputDevice
>& devices
) override
{}
108 base::Callback
<void(const TouchEventParams
& params
)> callback_
;
111 MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
114 DeviceEventDispatcherEvdev
* dispatcher
)
115 : TouchEventConverterEvdev(fd
, path
, 1, INPUT_DEVICE_UNKNOWN
, dispatcher
) {
119 PLOG(FATAL
) << "failed pipe";
121 EXPECT_FALSE(SetNonBlocking(fds
[0]) || SetNonBlocking(fds
[1]))
122 << "failed to set non-blocking: " << strerror(errno
);
125 write_pipe_
= fds
[1];
127 events_
.resize(ui::kNumTouchEvdevSlots
);
128 for (size_t i
= 0; i
< events_
.size(); ++i
)
132 void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event
* queue
,
135 int nwrite
= HANDLE_EINTR(write(write_pipe_
,
137 sizeof(struct input_event
) * read_this_many
));
139 static_cast<int>(sizeof(struct input_event
) * read_this_many
))
140 << "write() failed, errno: " << errno
;
144 class TouchEventConverterEvdevTest
: public testing::Test
{
146 TouchEventConverterEvdevTest() {}
148 // Overridden from testing::Test:
149 void SetUp() override
{
150 // Set up pipe to satisfy message pump (unused).
153 PLOG(FATAL
) << "failed pipe";
154 events_in_
= evdev_io
[0];
155 events_out_
= evdev_io
[1];
157 // Device creation happens on a worker thread since it may involve blocking
158 // operations. Simulate that by creating it before creating a UI message
160 dispatcher_
.reset(new ui::MockDeviceEventDispatcherEvdev(
161 base::Bind(&TouchEventConverterEvdevTest::DispatchCallback
,
162 base::Unretained(this))));
163 device_
= new ui::MockTouchEventConverterEvdev(
164 events_in_
, base::FilePath(kTestDevicePath
), dispatcher_
.get());
165 loop_
= new base::MessageLoopForUI
;
167 ui::DeviceDataManager::CreateInstance();
170 void TearDown() override
{
175 ui::MockTouchEventConverterEvdev
* device() { return device_
; }
177 unsigned size() { return dispatched_events_
.size(); }
178 const ui::TouchEventParams
& dispatched_event(unsigned index
) {
179 DCHECK_GT(dispatched_events_
.size(), index
);
180 return dispatched_events_
[index
];
183 void ClearDispatchedEvents() {
184 dispatched_events_
.clear();
188 base::MessageLoop
* loop_
;
189 ui::MockTouchEventConverterEvdev
* device_
;
190 scoped_ptr
<ui::MockDeviceEventDispatcherEvdev
> dispatcher_
;
195 void DispatchCallback(const ui::TouchEventParams
& params
) {
196 dispatched_events_
.push_back(params
);
198 std::vector
<ui::TouchEventParams
> dispatched_events_
;
200 DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTest
);
203 TEST_F(TouchEventConverterEvdevTest
, NoEvents
) {
204 ui::MockTouchEventConverterEvdev
* dev
= device();
205 dev
->ConfigureReadMock(NULL
, 0, 0);
206 EXPECT_EQ(0u, size());
209 TEST_F(TouchEventConverterEvdevTest
, TouchMove
) {
210 ui::MockTouchEventConverterEvdev
* dev
= device();
212 InitPixelTouchscreen(dev
);
214 // Captured from Chromebook Pixel (Link).
216 time
= {1427323282, 19203};
217 struct input_event mock_kernel_queue_press
[] = {
218 {time
, EV_ABS
, ABS_MT_TRACKING_ID
, 3},
219 {time
, EV_ABS
, ABS_MT_POSITION_X
, 295},
220 {time
, EV_ABS
, ABS_MT_POSITION_Y
, 421},
221 {time
, EV_ABS
, ABS_MT_PRESSURE
, 34},
222 {time
, EV_ABS
, ABS_MT_TOUCH_MAJOR
, 116},
223 {time
, EV_KEY
, BTN_TOUCH
, 1},
224 {time
, EV_ABS
, ABS_X
, 295},
225 {time
, EV_ABS
, ABS_Y
, 421},
226 {time
, EV_ABS
, ABS_PRESSURE
, 34},
227 {time
, EV_SYN
, SYN_REPORT
, 0},
229 time
= {1427323282, 34693};
230 struct input_event mock_kernel_queue_move
[] = {
231 {time
, EV_ABS
, ABS_MT_POSITION_X
, 312},
232 {time
, EV_ABS
, ABS_MT_POSITION_Y
, 432},
233 {time
, EV_ABS
, ABS_MT_PRESSURE
, 43},
234 {time
, EV_ABS
, ABS_MT_TOUCH_MAJOR
, 100},
235 {time
, EV_ABS
, ABS_X
, 312},
236 {time
, EV_ABS
, ABS_Y
, 432},
237 {time
, EV_ABS
, ABS_PRESSURE
, 43},
238 {time
, EV_SYN
, SYN_REPORT
, 0},
240 time
= {1427323282, 144540};
241 struct input_event mock_kernel_queue_release
[] = {
242 {time
, EV_ABS
, ABS_MT_TRACKING_ID
, -1},
243 {time
, EV_KEY
, BTN_TOUCH
, 0},
244 {time
, EV_ABS
, ABS_PRESSURE
, 0},
245 {time
, EV_SYN
, SYN_REPORT
, 0},
249 dev
->ConfigureReadMock(mock_kernel_queue_press
,
250 arraysize(mock_kernel_queue_press
), 0);
252 EXPECT_EQ(1u, size());
253 ui::TouchEventParams event
= dispatched_event(0);
254 EXPECT_EQ(ui::ET_TOUCH_PRESSED
, event
.type
);
255 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282019203),
257 EXPECT_EQ(295, event
.location
.x());
258 EXPECT_EQ(421, event
.location
.y());
259 EXPECT_EQ(0, event
.touch_id
);
260 EXPECT_FLOAT_EQ(58.f
, event
.radii
.x());
261 EXPECT_FLOAT_EQ(0.13333334f
, event
.pressure
);
264 dev
->ConfigureReadMock(mock_kernel_queue_move
,
265 arraysize(mock_kernel_queue_move
), 0);
267 EXPECT_EQ(2u, size());
268 event
= dispatched_event(1);
269 EXPECT_EQ(ui::ET_TOUCH_MOVED
, event
.type
);
270 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282034693),
272 EXPECT_EQ(312, event
.location
.x());
273 EXPECT_EQ(432, event
.location
.y());
274 EXPECT_EQ(0, event
.touch_id
);
275 EXPECT_FLOAT_EQ(50.f
, event
.radii
.x());
276 EXPECT_FLOAT_EQ(0.16862745f
, event
.pressure
);
279 dev
->ConfigureReadMock(mock_kernel_queue_release
,
280 arraysize(mock_kernel_queue_release
), 0);
282 EXPECT_EQ(3u, size());
283 event
= dispatched_event(2);
284 EXPECT_EQ(ui::ET_TOUCH_RELEASED
, event
.type
);
285 EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282144540),
287 EXPECT_EQ(312, event
.location
.x());
288 EXPECT_EQ(432, event
.location
.y());
289 EXPECT_EQ(0, event
.touch_id
);
290 EXPECT_FLOAT_EQ(50.f
, event
.radii
.x());
291 EXPECT_FLOAT_EQ(0.16862745f
, event
.pressure
);
294 TEST_F(TouchEventConverterEvdevTest
, TwoFingerGesture
) {
295 ui::MockTouchEventConverterEvdev
* dev
= device();
297 InitPixelTouchscreen(dev
);
299 struct input_event mock_kernel_queue_press0
[] = {
300 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 684},
301 {{0, 0}, EV_ABS
, ABS_MT_TOUCH_MAJOR
, 3},
302 {{0, 0}, EV_ABS
, ABS_MT_PRESSURE
, 45},
303 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 42},
304 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 51}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
306 // Setup and discard a press.
307 dev
->ConfigureReadMock(mock_kernel_queue_press0
, 6, 0);
309 EXPECT_EQ(1u, size());
311 struct input_event mock_kernel_queue_move0
[] = {
312 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 40}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
314 // Setup and discard a move.
315 dev
->ConfigureReadMock(mock_kernel_queue_move0
, 2, 0);
317 EXPECT_EQ(2u, size());
319 struct input_event mock_kernel_queue_move0press1
[] = {
320 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 40}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
321 {{0, 0}, EV_ABS
, ABS_MT_SLOT
, 1}, {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 686},
322 {{0, 0}, EV_ABS
, ABS_MT_TOUCH_MAJOR
, 3},
323 {{0, 0}, EV_ABS
, ABS_MT_PRESSURE
, 45},
324 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 101},
325 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 102}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
327 // Move on 0, press on 1.
328 dev
->ConfigureReadMock(mock_kernel_queue_move0press1
, 9, 0);
330 EXPECT_EQ(4u, size());
331 ui::TouchEventParams ev0
= dispatched_event(2);
332 ui::TouchEventParams ev1
= dispatched_event(3);
335 EXPECT_EQ(ui::ET_TOUCH_MOVED
, ev0
.type
);
336 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0
.timestamp
);
337 EXPECT_EQ(40, ev0
.location
.x());
338 EXPECT_EQ(51, ev0
.location
.y());
339 EXPECT_EQ(0, ev0
.touch_id
);
340 EXPECT_FLOAT_EQ(0.17647059f
, ev0
.pressure
);
343 EXPECT_EQ(ui::ET_TOUCH_PRESSED
, ev1
.type
);
344 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1
.timestamp
);
345 EXPECT_EQ(101, ev1
.location
.x());
346 EXPECT_EQ(102, ev1
.location
.y());
347 EXPECT_EQ(1, ev1
.touch_id
);
348 EXPECT_FLOAT_EQ(0.17647059f
, ev1
.pressure
);
350 // Stationary 0, Moves 1.
351 struct input_event mock_kernel_queue_stationary0_move1
[] = {
352 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 40}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
354 dev
->ConfigureReadMock(mock_kernel_queue_stationary0_move1
, 2, 0);
356 EXPECT_EQ(5u, size());
357 ev1
= dispatched_event(4);
359 EXPECT_EQ(ui::ET_TOUCH_MOVED
, ev1
.type
);
360 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1
.timestamp
);
361 EXPECT_EQ(40, ev1
.location
.x());
362 EXPECT_EQ(102, ev1
.location
.y());
363 EXPECT_EQ(1, ev1
.touch_id
);
364 EXPECT_FLOAT_EQ(0.17647059f
, ev1
.pressure
);
366 // Move 0, stationary 1.
367 struct input_event mock_kernel_queue_move0_stationary1
[] = {
368 {{0, 0}, EV_ABS
, ABS_MT_SLOT
, 0}, {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 39},
369 {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
371 dev
->ConfigureReadMock(mock_kernel_queue_move0_stationary1
, 3, 0);
373 EXPECT_EQ(6u, size());
374 ev0
= dispatched_event(5);
376 EXPECT_EQ(ui::ET_TOUCH_MOVED
, ev0
.type
);
377 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0
.timestamp
);
378 EXPECT_EQ(39, ev0
.location
.x());
379 EXPECT_EQ(51, ev0
.location
.y());
380 EXPECT_EQ(0, ev0
.touch_id
);
381 EXPECT_FLOAT_EQ(0.17647059f
, ev0
.pressure
);
383 // Release 0, move 1.
384 struct input_event mock_kernel_queue_release0_move1
[] = {
385 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, -1}, {{0, 0}, EV_ABS
, ABS_MT_SLOT
, 1},
386 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 38}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
388 dev
->ConfigureReadMock(mock_kernel_queue_release0_move1
, 4, 0);
390 EXPECT_EQ(8u, size());
391 ev0
= dispatched_event(6);
392 ev1
= dispatched_event(7);
394 EXPECT_EQ(ui::ET_TOUCH_RELEASED
, ev0
.type
);
395 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0
.timestamp
);
396 EXPECT_EQ(39, ev0
.location
.x());
397 EXPECT_EQ(51, ev0
.location
.y());
398 EXPECT_EQ(0, ev0
.touch_id
);
399 EXPECT_FLOAT_EQ(0.17647059f
, ev0
.pressure
);
401 EXPECT_EQ(ui::ET_TOUCH_MOVED
, ev1
.type
);
402 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1
.timestamp
);
403 EXPECT_EQ(38, ev1
.location
.x());
404 EXPECT_EQ(102, ev1
.location
.y());
405 EXPECT_EQ(1, ev1
.touch_id
);
406 EXPECT_FLOAT_EQ(0.17647059f
, ev1
.pressure
);
409 struct input_event mock_kernel_queue_release1
[] = {
410 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, -1}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
412 dev
->ConfigureReadMock(mock_kernel_queue_release1
, 2, 0);
414 EXPECT_EQ(9u, size());
415 ev1
= dispatched_event(8);
417 EXPECT_EQ(ui::ET_TOUCH_RELEASED
, ev1
.type
);
418 EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1
.timestamp
);
419 EXPECT_EQ(38, ev1
.location
.x());
420 EXPECT_EQ(102, ev1
.location
.y());
421 EXPECT_EQ(1, ev1
.touch_id
);
422 EXPECT_FLOAT_EQ(0.17647059f
, ev1
.pressure
);
425 TEST_F(TouchEventConverterEvdevTest
, Unsync
) {
426 ui::MockTouchEventConverterEvdev
* dev
= device();
428 InitPixelTouchscreen(dev
);
430 struct input_event mock_kernel_queue_press0
[] = {
431 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 684},
432 {{0, 0}, EV_ABS
, ABS_MT_TOUCH_MAJOR
, 3},
433 {{0, 0}, EV_ABS
, ABS_MT_PRESSURE
, 45},
434 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 42},
435 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 51}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
438 dev
->ConfigureReadMock(mock_kernel_queue_press0
, 6, 0);
440 EXPECT_EQ(1u, size());
442 // Prepare a move with a drop.
443 struct input_event mock_kernel_queue_move0
[] = {
444 {{0, 0}, EV_SYN
, SYN_DROPPED
, 0},
445 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 40}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
448 // Verify that we didn't receive it/
449 dev
->ConfigureReadMock(mock_kernel_queue_move0
, 3, 0);
451 EXPECT_EQ(1u, size());
453 struct input_event mock_kernel_queue_move1
[] = {
454 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 40}, {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
457 // Verify that it re-syncs after a SYN_REPORT.
458 dev
->ConfigureReadMock(mock_kernel_queue_move1
, 2, 0);
460 EXPECT_EQ(2u, size());
463 TEST_F(TouchEventConverterEvdevTest
, ShouldResumeExistingContactsOnStart
) {
464 ui::MockTouchEventConverterEvdev
* dev
= device();
466 EventDeviceInfo devinfo
;
467 EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen
, &devinfo
));
469 // Set up an existing contact in slot 0.
470 devinfo
.SetAbsMtSlot(ABS_MT_TRACKING_ID
, 0, 1);
471 devinfo
.SetAbsMtSlot(ABS_MT_TOUCH_MAJOR
, 0, 100);
472 devinfo
.SetAbsMtSlot(ABS_MT_POSITION_X
, 0, 100);
473 devinfo
.SetAbsMtSlot(ABS_MT_POSITION_Y
, 0, 100);
474 devinfo
.SetAbsMtSlot(ABS_MT_PRESSURE
, 0, 128);
476 // Initialize the device.
477 dev
->Initialize(devinfo
);
479 // Any report should suffice to dispatch the update.. do an empty one.
480 struct input_event mock_kernel_queue_empty_report
[] = {
481 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
484 dev
->ConfigureReadMock(mock_kernel_queue_empty_report
,
485 arraysize(mock_kernel_queue_empty_report
), 0);
487 EXPECT_EQ(1u, size());
489 ui::TouchEventParams ev
= dispatched_event(0);
490 EXPECT_EQ(ET_TOUCH_PRESSED
, ev
.type
);
491 EXPECT_EQ(0, ev
.touch_id
);
492 EXPECT_FLOAT_EQ(50.f
, ev
.radii
.x());
493 EXPECT_FLOAT_EQ(0.f
, ev
.radii
.y());
494 EXPECT_FLOAT_EQ(0.50196081f
, ev
.pressure
);
498 TEST_F(TouchEventConverterEvdevTest
,
499 DontChangeMultitouchPositionFromLegacyAxes
) {
500 ui::MockTouchEventConverterEvdev
* dev
= device();
502 InitPixelTouchscreen(dev
);
504 struct input_event mock_kernel_queue
[] = {
505 {{0, 0}, EV_ABS
, ABS_MT_SLOT
, 0},
506 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 100},
507 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 999},
508 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 888},
509 {{0, 0}, EV_ABS
, ABS_MT_PRESSURE
, 55},
510 {{0, 0}, EV_ABS
, ABS_MT_SLOT
, 1},
511 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 200},
512 {{0, 0}, EV_ABS
, ABS_MT_PRESSURE
, 44},
513 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 777},
514 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 666},
515 {{0, 0}, EV_ABS
, ABS_X
, 999},
516 {{0, 0}, EV_ABS
, ABS_Y
, 888},
517 {{0, 0}, EV_ABS
, ABS_PRESSURE
, 55},
518 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
521 // Check that two events are generated.
522 dev
->ConfigureReadMock(mock_kernel_queue
, arraysize(mock_kernel_queue
), 0);
525 const unsigned int kExpectedEventCount
= 2;
526 EXPECT_EQ(kExpectedEventCount
, size());
527 if (kExpectedEventCount
!= size())
530 ui::TouchEventParams ev0
= dispatched_event(0);
531 ui::TouchEventParams ev1
= dispatched_event(1);
533 EXPECT_EQ(0, ev0
.touch_id
);
534 EXPECT_EQ(999, ev0
.location
.x());
535 EXPECT_EQ(888, ev0
.location
.y());
536 EXPECT_FLOAT_EQ(0.21568628f
, ev0
.pressure
);
538 EXPECT_EQ(1, ev1
.touch_id
);
539 EXPECT_EQ(777, ev1
.location
.x());
540 EXPECT_EQ(666, ev1
.location
.y());
541 EXPECT_FLOAT_EQ(0.17254902f
, ev1
.pressure
);
545 TEST_F(TouchEventConverterEvdevTest
, CheckSlotLimit
) {
546 ui::MockTouchEventConverterEvdev
* dev
= device();
548 struct input_event mock_kernel_queue
[] = {
549 {{0, 0}, EV_ABS
, ABS_MT_SLOT
, 0},
550 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 100},
551 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 999},
552 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 888},
553 {{0, 0}, EV_ABS
, ABS_MT_SLOT
, ui::kNumTouchEvdevSlots
},
554 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 200},
555 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 777},
556 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 666},
557 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
560 // Check that one 1 event is generated
561 dev
->ConfigureReadMock(mock_kernel_queue
, arraysize(mock_kernel_queue
), 0);
563 EXPECT_EQ(1u, size());
568 // TouchNoiseFilter which:
569 // - Considers all events of type |noise_event_type| as noise.
570 // - Keeps track of the events that it receives.
571 class EventTypeTouchNoiseFilter
: public TouchNoiseFilter
{
573 explicit EventTypeTouchNoiseFilter(EventType noise_event_type
)
574 : noise_event_type_(noise_event_type
) {}
575 ~EventTypeTouchNoiseFilter() override
{}
578 void Filter(const std::vector
<InProgressTouchEvdev
>& touches
,
579 base::TimeDelta time
,
580 std::bitset
<kNumTouchEvdevSlots
>* slots_with_noise
) override
{
581 for (const InProgressTouchEvdev
& touch
: touches
) {
582 EventType event_type
= EventTypeFromTouch(touch
);
583 ++counts_
[event_type
];
584 if (event_type
== noise_event_type_
)
585 slots_with_noise
->set(touch
.slot
);
589 // Returns the number of received events of |type|.
590 size_t num_events(EventType type
) const {
591 std::map
<EventType
, size_t>::const_iterator it
= counts_
.find(type
);
592 return it
== counts_
.end() ? 0u : it
->second
;
596 EventType
EventTypeFromTouch(const InProgressTouchEvdev
& touch
) const {
598 return touch
.was_touching
? ET_TOUCH_MOVED
: ET_TOUCH_PRESSED
;
599 return touch
.was_touching
? ET_TOUCH_RELEASED
: ET_UNKNOWN
;
602 EventType noise_event_type_
;
603 std::map
<EventType
, size_t> counts_
;
605 DISALLOW_COPY_AND_ASSIGN(EventTypeTouchNoiseFilter
);
610 class TouchEventConverterEvdevTouchNoiseTest
611 : public TouchEventConverterEvdevTest
{
613 TouchEventConverterEvdevTouchNoiseTest() {}
614 ~TouchEventConverterEvdevTouchNoiseTest() override
{}
616 // Makes the TouchNoiseFinder use |filter| and only |filter| to filter out
618 void SetTouchNoiseFilter(scoped_ptr
<TouchNoiseFilter
> filter
) {
619 TouchNoiseFinder
* finder
= device()->touch_noise_finder();
620 finder
->filters_
.clear();
621 finder
->filters_
.push_back(filter
.release());
624 // Returns the first of TouchNoiseFinder's filters.
625 ui::TouchNoiseFilter
* first_filter() {
626 TouchNoiseFinder
* finder
= device()->touch_noise_finder();
627 return finder
->filters_
.empty() ? nullptr : *finder
->filters_
.begin();
630 // TouchEventConverterEvdevTest:
631 void SetUp() override
{
632 base::CommandLine::ForCurrentProcess()->AppendSwitch(
633 switches::kExtraTouchNoiseFiltering
);
634 TouchEventConverterEvdevTest::SetUp();
638 DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTouchNoiseTest
);
641 // Test that if TouchNoiseFinder identifies an event for an in-progress touch as
642 // noise, that the event is converted to ET_TOUCH_CANCELLED and that all
643 // subsequent events for the in-progress touch are cancelled.
644 TEST_F(TouchEventConverterEvdevTouchNoiseTest
, TouchNoiseFiltering
) {
645 struct input_event mock_kernel_queue
[] = {
646 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 684},
647 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 40},
648 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 41},
649 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
651 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 42},
652 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 43},
653 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
655 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, -1},
656 {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
659 MockTouchEventConverterEvdev
* dev
= device();
660 SetTouchNoiseFilter(scoped_ptr
<TouchNoiseFilter
>(
661 new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED
)));
662 dev
->ConfigureReadMock(mock_kernel_queue
, arraysize(mock_kernel_queue
), 0);
664 ASSERT_EQ(0u, size());
666 ClearDispatchedEvents();
667 SetTouchNoiseFilter(scoped_ptr
<TouchNoiseFilter
>(
668 new EventTypeTouchNoiseFilter(ET_TOUCH_MOVED
)));
669 dev
->ConfigureReadMock(mock_kernel_queue
, arraysize(mock_kernel_queue
), 0);
671 ASSERT_EQ(2u, size());
672 TouchEventParams event0
= dispatched_event(0);
673 EXPECT_EQ(ET_TOUCH_PRESSED
, event0
.type
);
674 EXPECT_EQ(40, event0
.location
.x());
675 EXPECT_EQ(41, event0
.location
.y());
676 EXPECT_EQ(ET_TOUCH_CANCELLED
, dispatched_event(1).type
);
678 ClearDispatchedEvents();
679 SetTouchNoiseFilter(scoped_ptr
<TouchNoiseFilter
>(
680 new EventTypeTouchNoiseFilter(ET_TOUCH_RELEASED
)));
681 dev
->ConfigureReadMock(mock_kernel_queue
, arraysize(mock_kernel_queue
), 0);
683 ASSERT_EQ(3u, size());
684 event0
= dispatched_event(0);
685 EXPECT_EQ(ET_TOUCH_PRESSED
, event0
.type
);
686 EXPECT_EQ(40, event0
.location
.x());
687 EXPECT_EQ(41, event0
.location
.y());
688 TouchEventParams event1
= dispatched_event(1);
689 EXPECT_EQ(ET_TOUCH_MOVED
, event1
.type
);
690 EXPECT_EQ(42, event1
.location
.x());
691 EXPECT_EQ(43, event1
.location
.y());
692 EXPECT_EQ(ET_TOUCH_CANCELLED
, dispatched_event(2).type
);
695 // Test that TouchEventConverterEvdev keeps sending events to
696 // TouchNoiseFinder after the touch is canceled.
697 TEST_F(TouchEventConverterEvdevTouchNoiseTest
,
698 DoNotSendTouchCancelsToTouchNoiseFinder
) {
699 struct input_event mock_kernel_queue
[] = {
700 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, 684},
701 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 40},
702 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 41},
703 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
705 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 42},
706 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 43},
707 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
709 {{0, 0}, EV_ABS
, ABS_MT_POSITION_X
, 43},
710 {{0, 0}, EV_ABS
, ABS_MT_POSITION_Y
, 44},
711 {{0, 0}, EV_SYN
, SYN_REPORT
, 0},
713 {{0, 0}, EV_ABS
, ABS_MT_TRACKING_ID
, -1},
714 {{0, 0}, EV_SYN
, SYN_REPORT
, 0}
717 MockTouchEventConverterEvdev
* dev
= device();
718 SetTouchNoiseFilter(scoped_ptr
<TouchNoiseFilter
>(
719 new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED
)));
720 dev
->ConfigureReadMock(mock_kernel_queue
, arraysize(mock_kernel_queue
), 0);
722 ASSERT_EQ(0u, size());
724 EventTypeTouchNoiseFilter
* filter
=
725 static_cast<EventTypeTouchNoiseFilter
*>(first_filter());
726 EXPECT_EQ(1u, filter
->num_events(ET_TOUCH_PRESSED
));
727 EXPECT_EQ(2u, filter
->num_events(ET_TOUCH_MOVED
));
728 EXPECT_EQ(1u, filter
->num_events(ET_TOUCH_RELEASED
));