| Index: ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
|
| diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
|
| index eaec9b1dd638ed7f60c83fc024559395bff1af39..da68c80e5693388eac1ab587a0f7766cf6d7d915 100644
|
| --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
|
| +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
|
| @@ -10,6 +10,7 @@
|
| #include <vector>
|
|
|
| #include "base/bind.h"
|
| +#include "base/command_line.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/memory/scoped_vector.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| @@ -17,11 +18,17 @@
|
| #include "base/time/time.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "ui/events/devices/device_data_manager.h"
|
| +#include "ui/events/event_switches.h"
|
| #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
|
| +#include "ui/events/ozone/evdev/touch_evdev_types.h"
|
| #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
|
| +#include "ui/events/ozone/evdev/touch_noise/touch_noise_filter.h"
|
| +#include "ui/events/ozone/evdev/touch_noise/touch_noise_finder.h"
|
| #include "ui/events/platform/platform_event_dispatcher.h"
|
| #include "ui/events/platform/platform_event_source.h"
|
|
|
| +namespace ui {
|
| +
|
| namespace {
|
|
|
| static int SetNonBlocking(int fd) {
|
| @@ -35,8 +42,6 @@ const char kTestDevicePath[] = "/dev/input/test-device";
|
|
|
| } // namespace
|
|
|
| -namespace ui {
|
| -
|
| class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
|
| public:
|
| MockTouchEventConverterEvdev(int fd,
|
| @@ -57,6 +62,8 @@ class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
|
| void Initialize(const EventDeviceInfo& device_info) override {}
|
| bool Reinitialize() override { return true; }
|
|
|
| + TouchNoiseFinder* touch_noise_finder() { return touch_noise_finder_.get(); }
|
| +
|
| private:
|
| int read_pipe_;
|
| int write_pipe_;
|
| @@ -120,7 +127,9 @@ MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
|
| read_pipe_ = fds[0];
|
| write_pipe_ = fds[1];
|
|
|
| - events_.resize(MAX_FINGERS);
|
| + events_.resize(ui::kNumTouchEvdevSlots);
|
| + for (size_t i = 0; i < events_.size(); ++i)
|
| + events_[i].slot = i;
|
| }
|
|
|
| void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
|
| @@ -134,8 +143,6 @@ void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
|
| << "write() failed, errno: " << errno;
|
| }
|
|
|
| -} // namespace ui
|
| -
|
| // Test fixture.
|
| class TouchEventConverterEvdevTest : public testing::Test {
|
| public:
|
| @@ -176,6 +183,10 @@ class TouchEventConverterEvdevTest : public testing::Test {
|
| return dispatched_events_[index];
|
| }
|
|
|
| + void ClearDispatchedEvents() {
|
| + dispatched_events_.clear();
|
| + }
|
| +
|
| private:
|
| base::MessageLoop* loop_;
|
| ui::MockTouchEventConverterEvdev* device_;
|
| @@ -448,28 +459,6 @@ TEST_F(TouchEventConverterEvdevTest, TwoFingerGesture) {
|
| EXPECT_FLOAT_EQ(.5f, ev1.pressure);
|
| }
|
|
|
| -TEST_F(TouchEventConverterEvdevTest, TypeA) {
|
| - ui::MockTouchEventConverterEvdev* dev = device();
|
| -
|
| - struct input_event mock_kernel_queue_press0[] = {
|
| - {{0, 0}, EV_ABS, ABS_MT_TOUCH_MAJOR, 3},
|
| - {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
|
| - {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
|
| - {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 51},
|
| - {{0, 0}, EV_SYN, SYN_MT_REPORT, 0},
|
| - {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 45},
|
| - {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 61},
|
| - {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 71},
|
| - {{0, 0}, EV_SYN, SYN_MT_REPORT, 0},
|
| - {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| - };
|
| -
|
| - // Check that two events are generated.
|
| - dev->ConfigureReadMock(mock_kernel_queue_press0, 10, 0);
|
| - dev->ReadNow();
|
| - EXPECT_EQ(2u, size());
|
| -}
|
| -
|
| TEST_F(TouchEventConverterEvdevTest, Unsync) {
|
| ui::MockTouchEventConverterEvdev* dev = device();
|
|
|
| @@ -560,7 +549,7 @@ TEST_F(TouchEventConverterEvdevTest, CheckSlotLimit) {
|
| {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 100},
|
| {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 999},
|
| {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 888},
|
| - {{0, 0}, EV_ABS, ABS_MT_SLOT, ui::TouchEventConverterEvdev::MAX_FINGERS},
|
| + {{0, 0}, EV_ABS, ABS_MT_SLOT, ui::kNumTouchEvdevSlots},
|
| {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 200},
|
| {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 777},
|
| {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 666},
|
| @@ -572,3 +561,170 @@ TEST_F(TouchEventConverterEvdevTest, CheckSlotLimit) {
|
| dev->ReadNow();
|
| EXPECT_EQ(1u, size());
|
| }
|
| +
|
| +namespace {
|
| +
|
| +// TouchNoiseFilter which:
|
| +// - Considers all events of type |noise_event_type| as noise.
|
| +// - Keeps track of the events that it receives.
|
| +class EventTypeTouchNoiseFilter : public TouchNoiseFilter {
|
| + public:
|
| + explicit EventTypeTouchNoiseFilter(EventType noise_event_type)
|
| + : noise_event_type_(noise_event_type) {}
|
| + ~EventTypeTouchNoiseFilter() override {}
|
| +
|
| + // TouchNoiseFilter:
|
| + void Filter(const std::vector<InProgressTouchEvdev>& touches,
|
| + base::TimeDelta time,
|
| + std::bitset<kNumTouchEvdevSlots>* slots_with_noise) override {
|
| + for (const InProgressTouchEvdev& touch : touches) {
|
| + EventType event_type = EventTypeFromTouch(touch);
|
| + ++counts_[event_type];
|
| + if (event_type == noise_event_type_)
|
| + slots_with_noise->set(touch.slot);
|
| + }
|
| + }
|
| +
|
| + // Returns the number of received events of |type|.
|
| + size_t num_events(EventType type) const {
|
| + std::map<EventType, size_t>::const_iterator it = counts_.find(type);
|
| + return it == counts_.end() ? 0u : it->second;
|
| + }
|
| +
|
| + private:
|
| + EventType EventTypeFromTouch(const InProgressTouchEvdev& touch) const {
|
| + if (touch.touching)
|
| + return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED;
|
| + return touch.was_touching ? ET_TOUCH_RELEASED : ET_UNKNOWN;
|
| + }
|
| +
|
| + EventType noise_event_type_;
|
| + std::map<EventType, size_t> counts_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(EventTypeTouchNoiseFilter);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class TouchEventConverterEvdevTouchNoiseTest
|
| + : public TouchEventConverterEvdevTest {
|
| + public:
|
| + TouchEventConverterEvdevTouchNoiseTest() {}
|
| + ~TouchEventConverterEvdevTouchNoiseTest() override {}
|
| +
|
| + // Makes the TouchNoiseFinder use |filter| and only |filter| to filter out
|
| + // touch noise.
|
| + void SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter> filter) {
|
| + TouchNoiseFinder* finder = device()->touch_noise_finder();
|
| + finder->filters_.clear();
|
| + finder->filters_.push_back(filter.release());
|
| + }
|
| +
|
| + // Returns the first of TouchNoiseFinder's filters.
|
| + ui::TouchNoiseFilter* first_filter() {
|
| + TouchNoiseFinder* finder = device()->touch_noise_finder();
|
| + return finder->filters_.empty() ? nullptr : *finder->filters_.begin();
|
| + }
|
| +
|
| + // TouchEventConverterEvdevTest:
|
| + void SetUp() override {
|
| + base::CommandLine::ForCurrentProcess()->AppendSwitch(
|
| + switches::kExtraTouchNoiseFiltering);
|
| + TouchEventConverterEvdevTest::SetUp();
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTouchNoiseTest);
|
| +};
|
| +
|
| +// Test that if TouchNoiseFinder identifies an event for an in-progress touch as
|
| +// noise, that the event is converted to ET_TOUCH_CANCELLED and that all
|
| +// subsequent events for the in-progress touch are cancelled.
|
| +TEST_F(TouchEventConverterEvdevTouchNoiseTest, TouchNoiseFiltering) {
|
| + struct input_event mock_kernel_queue[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 41},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| +
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 43},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| +
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| +
|
| + MockTouchEventConverterEvdev* dev = device();
|
| + SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
|
| + new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED)));
|
| + dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
|
| + dev->ReadNow();
|
| + ASSERT_EQ(0u, size());
|
| +
|
| + ClearDispatchedEvents();
|
| + SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
|
| + new EventTypeTouchNoiseFilter(ET_TOUCH_MOVED)));
|
| + dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
|
| + dev->ReadNow();
|
| + ASSERT_EQ(2u, size());
|
| + TouchEventParams event0 = dispatched_event(0);
|
| + EXPECT_EQ(ET_TOUCH_PRESSED, event0.type);
|
| + EXPECT_EQ(40, event0.location.x());
|
| + EXPECT_EQ(41, event0.location.y());
|
| + EXPECT_EQ(ET_TOUCH_CANCELLED, dispatched_event(1).type);
|
| +
|
| + ClearDispatchedEvents();
|
| + SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
|
| + new EventTypeTouchNoiseFilter(ET_TOUCH_RELEASED)));
|
| + dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
|
| + dev->ReadNow();
|
| + ASSERT_EQ(3u, size());
|
| + event0 = dispatched_event(0);
|
| + EXPECT_EQ(ET_TOUCH_PRESSED, event0.type);
|
| + EXPECT_EQ(40, event0.location.x());
|
| + EXPECT_EQ(41, event0.location.y());
|
| + TouchEventParams event1 = dispatched_event(1);
|
| + EXPECT_EQ(ET_TOUCH_MOVED, event1.type);
|
| + EXPECT_EQ(42, event1.location.x());
|
| + EXPECT_EQ(43, event1.location.y());
|
| + EXPECT_EQ(ET_TOUCH_CANCELLED, dispatched_event(2).type);
|
| +}
|
| +
|
| +// Test that TouchEventConverterEvdev keeps sending events to
|
| +// TouchNoiseFinder after the touch is canceled.
|
| +TEST_F(TouchEventConverterEvdevTouchNoiseTest,
|
| + DoNotSendTouchCancelsToTouchNoiseFinder) {
|
| + struct input_event mock_kernel_queue[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 41},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| +
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 42},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 43},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| +
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 43},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 44},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| +
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| +
|
| + MockTouchEventConverterEvdev* dev = device();
|
| + SetTouchNoiseFilter(scoped_ptr<TouchNoiseFilter>(
|
| + new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED)));
|
| + dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
|
| + dev->ReadNow();
|
| + ASSERT_EQ(0u, size());
|
| +
|
| + EventTypeTouchNoiseFilter* filter =
|
| + static_cast<EventTypeTouchNoiseFilter*>(first_filter());
|
| + EXPECT_EQ(1u, filter->num_events(ET_TOUCH_PRESSED));
|
| + EXPECT_EQ(2u, filter->num_events(ET_TOUCH_MOVED));
|
| + EXPECT_EQ(1u, filter->num_events(ET_TOUCH_RELEASED));
|
| +}
|
| +
|
| +} // namespace ui
|
|
|