| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..da6958f0beabe37a13d1f0cfeeb9659b1d70859f
|
| --- /dev/null
|
| +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
|
| @@ -0,0 +1,944 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <errno.h>
|
| +#include <fcntl.h>
|
| +#include <linux/input.h>
|
| +#include <unistd.h>
|
| +
|
| +#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"
|
| +#include "base/run_loop.h"
|
| +#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/event_device_test_util.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) {
|
| + int flags = fcntl(fd, F_GETFL, 0);
|
| + if (flags == -1)
|
| + flags = 0;
|
| + return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
| +}
|
| +
|
| +const char kTestDevicePath[] = "/dev/input/test-device";
|
| +
|
| +void InitPixelTouchscreen(TouchEventConverterEvdev* device) {
|
| + EventDeviceInfo devinfo;
|
| + EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &devinfo));
|
| + device->Initialize(devinfo);
|
| +}
|
| +
|
| +void InitEloTouchscreen(TouchEventConverterEvdev* device) {
|
| + EventDeviceInfo devinfo;
|
| + EXPECT_TRUE(CapabilitiesToDeviceInfo(kElo_TouchSystems_2700, &devinfo));
|
| + device->Initialize(devinfo);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
|
| + public:
|
| + MockTouchEventConverterEvdev(int fd,
|
| + base::FilePath path,
|
| + const EventDeviceInfo& devinfo,
|
| + DeviceEventDispatcherEvdev* dispatcher);
|
| + ~MockTouchEventConverterEvdev() override;
|
| +
|
| + void ConfigureReadMock(struct input_event* queue,
|
| + long read_this_many,
|
| + long queue_index);
|
| +
|
| + // Actually dispatch the event reader code.
|
| + void ReadNow() {
|
| + OnFileCanReadWithoutBlocking(read_pipe_);
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| +
|
| + void SimulateReinitialize(const EventDeviceInfo& devinfo) {
|
| + Initialize(devinfo);
|
| + }
|
| +
|
| + void Reinitialize() override {}
|
| +
|
| + TouchNoiseFinder* touch_noise_finder() { return touch_noise_finder_.get(); }
|
| +
|
| + private:
|
| + int read_pipe_;
|
| + int write_pipe_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev);
|
| +};
|
| +
|
| +class MockDeviceEventDispatcherEvdev : public DeviceEventDispatcherEvdev {
|
| + public:
|
| + MockDeviceEventDispatcherEvdev(
|
| + const base::Callback<void(const TouchEventParams& params)>& callback)
|
| + : callback_(callback) {}
|
| + ~MockDeviceEventDispatcherEvdev() override {}
|
| +
|
| + // DeviceEventDispatcherEvdev:
|
| + void DispatchKeyEvent(const KeyEventParams& params) override {}
|
| + void DispatchMouseMoveEvent(const MouseMoveEventParams& params) override {}
|
| + void DispatchMouseButtonEvent(const MouseButtonEventParams& params) override {
|
| + }
|
| + void DispatchMouseWheelEvent(const MouseWheelEventParams& params) override {}
|
| + void DispatchScrollEvent(const ScrollEventParams& params) override {}
|
| + void DispatchTouchEvent(const TouchEventParams& params) override {
|
| + callback_.Run(params);
|
| + }
|
| +
|
| + void DispatchKeyboardDevicesUpdated(
|
| + const std::vector<KeyboardDevice>& devices) override {}
|
| + void DispatchTouchscreenDevicesUpdated(
|
| + const std::vector<TouchscreenDevice>& devices) override {}
|
| + void DispatchMouseDevicesUpdated(
|
| + const std::vector<InputDevice>& devices) override {}
|
| + void DispatchTouchpadDevicesUpdated(
|
| + const std::vector<InputDevice>& devices) override {}
|
| + void DispatchDeviceListsComplete() override {}
|
| +
|
| + private:
|
| + base::Callback<void(const TouchEventParams& params)> callback_;
|
| +};
|
| +
|
| +MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
|
| + int fd,
|
| + base::FilePath path,
|
| + const EventDeviceInfo& devinfo,
|
| + DeviceEventDispatcherEvdev* dispatcher)
|
| + : TouchEventConverterEvdev(fd,
|
| + path,
|
| + 1,
|
| + INPUT_DEVICE_UNKNOWN,
|
| + devinfo,
|
| + dispatcher) {
|
| + int fds[2];
|
| +
|
| + if (pipe(fds))
|
| + PLOG(FATAL) << "failed pipe";
|
| +
|
| + EXPECT_FALSE(SetNonBlocking(fds[0]) || SetNonBlocking(fds[1]))
|
| + << "failed to set non-blocking: " << strerror(errno);
|
| +
|
| + read_pipe_ = fds[0];
|
| + write_pipe_ = fds[1];
|
| +
|
| + events_.resize(ui::kNumTouchEvdevSlots);
|
| + for (size_t i = 0; i < events_.size(); ++i)
|
| + events_[i].slot = i;
|
| +
|
| + SetEnabled(true);
|
| +}
|
| +
|
| +MockTouchEventConverterEvdev::~MockTouchEventConverterEvdev() {
|
| + SetEnabled(false);
|
| +}
|
| +
|
| +void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue,
|
| + long read_this_many,
|
| + long queue_index) {
|
| + int nwrite = HANDLE_EINTR(write(write_pipe_,
|
| + queue + queue_index,
|
| + sizeof(struct input_event) * read_this_many));
|
| + DCHECK(nwrite ==
|
| + static_cast<int>(sizeof(struct input_event) * read_this_many))
|
| + << "write() failed, errno: " << errno;
|
| +}
|
| +
|
| +// Test fixture.
|
| +class TouchEventConverterEvdevTest : public testing::Test {
|
| + public:
|
| + TouchEventConverterEvdevTest() {}
|
| +
|
| + // Overridden from testing::Test:
|
| + void SetUp() override {
|
| + // Set up pipe to satisfy message pump (unused).
|
| + int evdev_io[2];
|
| + if (pipe(evdev_io))
|
| + PLOG(FATAL) << "failed pipe";
|
| + events_in_ = evdev_io[0];
|
| + events_out_ = evdev_io[1];
|
| +
|
| + // Device creation happens on a worker thread since it may involve blocking
|
| + // operations. Simulate that by creating it before creating a UI message
|
| + // loop.
|
| + EventDeviceInfo devinfo;
|
| + dispatcher_.reset(new ui::MockDeviceEventDispatcherEvdev(
|
| + base::Bind(&TouchEventConverterEvdevTest::DispatchCallback,
|
| + base::Unretained(this))));
|
| + device_.reset(new ui::MockTouchEventConverterEvdev(
|
| + events_in_, base::FilePath(kTestDevicePath), devinfo,
|
| + dispatcher_.get()));
|
| + loop_ = new base::MessageLoopForUI;
|
| +
|
| + ui::DeviceDataManager::CreateInstance();
|
| + }
|
| +
|
| + void TearDown() override {
|
| + device_.reset();
|
| + delete loop_;
|
| + }
|
| +
|
| + ui::MockTouchEventConverterEvdev* device() { return device_.get(); }
|
| +
|
| + unsigned size() { return dispatched_events_.size(); }
|
| + const ui::TouchEventParams& dispatched_event(unsigned index) {
|
| + DCHECK_GT(dispatched_events_.size(), index);
|
| + return dispatched_events_[index];
|
| + }
|
| +
|
| + void ClearDispatchedEvents() { dispatched_events_.clear(); }
|
| +
|
| + void DestroyDevice() { device_.reset(); }
|
| +
|
| + private:
|
| + base::MessageLoop* loop_;
|
| + scoped_ptr<ui::MockTouchEventConverterEvdev> device_;
|
| + scoped_ptr<ui::MockDeviceEventDispatcherEvdev> dispatcher_;
|
| +
|
| + int events_out_;
|
| + int events_in_;
|
| +
|
| + void DispatchCallback(const ui::TouchEventParams& params) {
|
| + dispatched_events_.push_back(params);
|
| + }
|
| + std::vector<ui::TouchEventParams> dispatched_events_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTest);
|
| +};
|
| +
|
| +TEST_F(TouchEventConverterEvdevTest, NoEvents) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| + dev->ConfigureReadMock(NULL, 0, 0);
|
| + EXPECT_EQ(0u, size());
|
| +}
|
| +
|
| +TEST_F(TouchEventConverterEvdevTest, TouchMove) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + InitPixelTouchscreen(dev);
|
| +
|
| + // Captured from Chromebook Pixel (Link).
|
| + timeval time;
|
| + time = {1427323282, 19203};
|
| + struct input_event mock_kernel_queue_press[] = {
|
| + {time, EV_ABS, ABS_MT_TRACKING_ID, 3},
|
| + {time, EV_ABS, ABS_MT_POSITION_X, 295},
|
| + {time, EV_ABS, ABS_MT_POSITION_Y, 421},
|
| + {time, EV_ABS, ABS_MT_PRESSURE, 34},
|
| + {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116},
|
| + {time, EV_KEY, BTN_TOUCH, 1},
|
| + {time, EV_ABS, ABS_X, 295},
|
| + {time, EV_ABS, ABS_Y, 421},
|
| + {time, EV_ABS, ABS_PRESSURE, 34},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| + time = {1427323282, 34693};
|
| + struct input_event mock_kernel_queue_move[] = {
|
| + {time, EV_ABS, ABS_MT_POSITION_X, 312},
|
| + {time, EV_ABS, ABS_MT_POSITION_Y, 432},
|
| + {time, EV_ABS, ABS_MT_PRESSURE, 43},
|
| + {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 100},
|
| + {time, EV_ABS, ABS_X, 312},
|
| + {time, EV_ABS, ABS_Y, 432},
|
| + {time, EV_ABS, ABS_PRESSURE, 43},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| + time = {1427323282, 144540};
|
| + struct input_event mock_kernel_queue_release[] = {
|
| + {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
|
| + {time, EV_KEY, BTN_TOUCH, 0},
|
| + {time, EV_ABS, ABS_PRESSURE, 0},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| +
|
| + // Press.
|
| + dev->ConfigureReadMock(mock_kernel_queue_press,
|
| + arraysize(mock_kernel_queue_press), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| + ui::TouchEventParams event = dispatched_event(0);
|
| + EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282019203),
|
| + event.timestamp);
|
| + EXPECT_EQ(295, event.location.x());
|
| + EXPECT_EQ(421, event.location.y());
|
| + EXPECT_EQ(0, event.slot);
|
| + EXPECT_FLOAT_EQ(58.f, event.radii.x());
|
| + EXPECT_FLOAT_EQ(0.13333334f, event.pressure);
|
| +
|
| + // Move.
|
| + dev->ConfigureReadMock(mock_kernel_queue_move,
|
| + arraysize(mock_kernel_queue_move), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(2u, size());
|
| + event = dispatched_event(1);
|
| + EXPECT_EQ(ui::ET_TOUCH_MOVED, event.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282034693),
|
| + event.timestamp);
|
| + EXPECT_EQ(312, event.location.x());
|
| + EXPECT_EQ(432, event.location.y());
|
| + EXPECT_EQ(0, event.slot);
|
| + EXPECT_FLOAT_EQ(50.f, event.radii.x());
|
| + EXPECT_FLOAT_EQ(0.16862745f, event.pressure);
|
| +
|
| + // Release.
|
| + dev->ConfigureReadMock(mock_kernel_queue_release,
|
| + arraysize(mock_kernel_queue_release), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(3u, size());
|
| + event = dispatched_event(2);
|
| + EXPECT_EQ(ui::ET_TOUCH_RELEASED, event.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1427323282144540),
|
| + event.timestamp);
|
| + EXPECT_EQ(312, event.location.x());
|
| + EXPECT_EQ(432, event.location.y());
|
| + EXPECT_EQ(0, event.slot);
|
| + EXPECT_FLOAT_EQ(50.f, event.radii.x());
|
| + EXPECT_FLOAT_EQ(0.16862745f, event.pressure);
|
| +}
|
| +
|
| +TEST_F(TouchEventConverterEvdevTest, TwoFingerGesture) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + InitPixelTouchscreen(dev);
|
| +
|
| + struct input_event mock_kernel_queue_press0[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
|
| + {{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_REPORT, 0}
|
| + };
|
| + // Setup and discard a press.
|
| + dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| +
|
| + struct input_event mock_kernel_queue_move0[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| + // Setup and discard a move.
|
| + dev->ConfigureReadMock(mock_kernel_queue_move0, 2, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(2u, size());
|
| +
|
| + struct input_event mock_kernel_queue_move0press1[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| + {{0, 0}, EV_ABS, ABS_MT_SLOT, 1}, {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 686},
|
| + {{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, 101},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 102}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| + // Move on 0, press on 1.
|
| + dev->ConfigureReadMock(mock_kernel_queue_move0press1, 9, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(4u, size());
|
| + ui::TouchEventParams ev0 = dispatched_event(2);
|
| + ui::TouchEventParams ev1 = dispatched_event(3);
|
| +
|
| + // Move
|
| + EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0.timestamp);
|
| + EXPECT_EQ(40, ev0.location.x());
|
| + EXPECT_EQ(51, ev0.location.y());
|
| + EXPECT_EQ(0, ev0.slot);
|
| + EXPECT_FLOAT_EQ(0.17647059f, ev0.pressure);
|
| +
|
| + // Press
|
| + EXPECT_EQ(ui::ET_TOUCH_PRESSED, ev1.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
|
| + EXPECT_EQ(101, ev1.location.x());
|
| + EXPECT_EQ(102, ev1.location.y());
|
| + EXPECT_EQ(1, ev1.slot);
|
| + EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
|
| +
|
| + // Stationary 0, Moves 1.
|
| + struct input_event mock_kernel_queue_stationary0_move1[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| + dev->ConfigureReadMock(mock_kernel_queue_stationary0_move1, 2, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(5u, size());
|
| + ev1 = dispatched_event(4);
|
| +
|
| + EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
|
| + EXPECT_EQ(40, ev1.location.x());
|
| + EXPECT_EQ(102, ev1.location.y());
|
| + EXPECT_EQ(1, ev1.slot);
|
| + EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
|
| +
|
| + // Move 0, stationary 1.
|
| + struct input_event mock_kernel_queue_move0_stationary1[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_SLOT, 0}, {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 39},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| + dev->ConfigureReadMock(mock_kernel_queue_move0_stationary1, 3, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(6u, size());
|
| + ev0 = dispatched_event(5);
|
| +
|
| + EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0.timestamp);
|
| + EXPECT_EQ(39, ev0.location.x());
|
| + EXPECT_EQ(51, ev0.location.y());
|
| + EXPECT_EQ(0, ev0.slot);
|
| + EXPECT_FLOAT_EQ(0.17647059f, ev0.pressure);
|
| +
|
| + // Release 0, move 1.
|
| + struct input_event mock_kernel_queue_release0_move1[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_ABS, ABS_MT_SLOT, 1},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 38}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| + dev->ConfigureReadMock(mock_kernel_queue_release0_move1, 4, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(8u, size());
|
| + ev0 = dispatched_event(6);
|
| + ev1 = dispatched_event(7);
|
| +
|
| + EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev0.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev0.timestamp);
|
| + EXPECT_EQ(39, ev0.location.x());
|
| + EXPECT_EQ(51, ev0.location.y());
|
| + EXPECT_EQ(0, ev0.slot);
|
| + EXPECT_FLOAT_EQ(0.17647059f, ev0.pressure);
|
| +
|
| + EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
|
| + EXPECT_EQ(38, ev1.location.x());
|
| + EXPECT_EQ(102, ev1.location.y());
|
| + EXPECT_EQ(1, ev1.slot);
|
| + EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
|
| +
|
| + // Release 1.
|
| + struct input_event mock_kernel_queue_release1[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, -1}, {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| + dev->ConfigureReadMock(mock_kernel_queue_release1, 2, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(9u, size());
|
| + ev1 = dispatched_event(8);
|
| +
|
| + EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev1.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(0), ev1.timestamp);
|
| + EXPECT_EQ(38, ev1.location.x());
|
| + EXPECT_EQ(102, ev1.location.y());
|
| + EXPECT_EQ(1, ev1.slot);
|
| + EXPECT_FLOAT_EQ(0.17647059f, ev1.pressure);
|
| +}
|
| +
|
| +TEST_F(TouchEventConverterEvdevTest, Unsync) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + InitPixelTouchscreen(dev);
|
| +
|
| + struct input_event mock_kernel_queue_press0[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 684},
|
| + {{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_REPORT, 0}
|
| + };
|
| +
|
| + dev->ConfigureReadMock(mock_kernel_queue_press0, 6, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| +
|
| + // Prepare a move with a drop.
|
| + struct input_event mock_kernel_queue_move0[] = {
|
| + {{0, 0}, EV_SYN, SYN_DROPPED, 0},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| +
|
| + // Verify that we didn't receive it/
|
| + dev->ConfigureReadMock(mock_kernel_queue_move0, 3, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| +
|
| + struct input_event mock_kernel_queue_move1[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 40}, {{0, 0}, EV_SYN, SYN_REPORT, 0}
|
| + };
|
| +
|
| + // Verify that it re-syncs after a SYN_REPORT.
|
| + dev->ConfigureReadMock(mock_kernel_queue_move1, 2, 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(2u, size());
|
| +}
|
| +
|
| +TEST_F(TouchEventConverterEvdevTest, ShouldResumeExistingContactsOnStart) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + EventDeviceInfo devinfo;
|
| + EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &devinfo));
|
| +
|
| + // Set up an existing contact in slot 0.
|
| + devinfo.SetAbsMtSlot(ABS_MT_TRACKING_ID, 0, 1);
|
| + devinfo.SetAbsMtSlot(ABS_MT_TOUCH_MAJOR, 0, 100);
|
| + devinfo.SetAbsMtSlot(ABS_MT_POSITION_X, 0, 100);
|
| + devinfo.SetAbsMtSlot(ABS_MT_POSITION_Y, 0, 100);
|
| + devinfo.SetAbsMtSlot(ABS_MT_PRESSURE, 0, 128);
|
| +
|
| + // Initialize the device.
|
| + dev->Initialize(devinfo);
|
| +
|
| + // Any report should suffice to dispatch the update.. do an empty one.
|
| + struct input_event mock_kernel_queue_empty_report[] = {
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| +
|
| + dev->ConfigureReadMock(mock_kernel_queue_empty_report,
|
| + arraysize(mock_kernel_queue_empty_report), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| +
|
| + ui::TouchEventParams ev = dispatched_event(0);
|
| + EXPECT_EQ(ET_TOUCH_PRESSED, ev.type);
|
| + EXPECT_EQ(0, ev.slot);
|
| + EXPECT_FLOAT_EQ(50.f, ev.radii.x());
|
| + EXPECT_FLOAT_EQ(0.f, ev.radii.y());
|
| + EXPECT_FLOAT_EQ(0.50196081f, ev.pressure);
|
| +}
|
| +
|
| +TEST_F(TouchEventConverterEvdevTest, ShouldReleaseContactsOnStop) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + InitPixelTouchscreen(dev);
|
| +
|
| + // Captured from Chromebook Pixel (Link).
|
| + timeval time;
|
| + time = {1429651083, 686882};
|
| + struct input_event mock_kernel_queue_press[] = {
|
| + {time, EV_ABS, ABS_MT_TRACKING_ID, 0},
|
| + {time, EV_ABS, ABS_MT_POSITION_X, 1003},
|
| + {time, EV_ABS, ABS_MT_POSITION_Y, 749},
|
| + {time, EV_ABS, ABS_MT_PRESSURE, 50},
|
| + {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116},
|
| + {time, EV_KEY, BTN_TOUCH, 1},
|
| + {time, EV_ABS, ABS_X, 1003},
|
| + {time, EV_ABS, ABS_Y, 749},
|
| + {time, EV_ABS, ABS_PRESSURE, 50},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| +
|
| + dev->ConfigureReadMock(mock_kernel_queue_press,
|
| + arraysize(mock_kernel_queue_press), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| +
|
| + ui::TouchEventParams ev1 = dispatched_event(0);
|
| + EXPECT_EQ(ET_TOUCH_PRESSED, ev1.type);
|
| + EXPECT_EQ(0, ev1.slot);
|
| +
|
| + DestroyDevice();
|
| + EXPECT_EQ(2u, size());
|
| +
|
| + ui::TouchEventParams ev2 = dispatched_event(1);
|
| + EXPECT_EQ(ET_TOUCH_RELEASED, ev2.type);
|
| + EXPECT_EQ(0, ev2.slot);
|
| +}
|
| +
|
| +TEST_F(TouchEventConverterEvdevTest, ShouldRemoveContactsWhenDisabled) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + EventDeviceInfo devinfo;
|
| + EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &devinfo));
|
| +
|
| + // Captured from Chromebook Pixel (Link).
|
| + timeval time;
|
| + time = {1429651083, 686882};
|
| + struct input_event mock_kernel_queue_press[] = {
|
| + {time, EV_ABS, ABS_MT_TRACKING_ID, 0},
|
| + {time, EV_ABS, ABS_MT_POSITION_X, 1003},
|
| + {time, EV_ABS, ABS_MT_POSITION_Y, 749},
|
| + {time, EV_ABS, ABS_MT_PRESSURE, 50},
|
| + {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 116},
|
| + {time, EV_KEY, BTN_TOUCH, 1},
|
| + {time, EV_ABS, ABS_X, 1003},
|
| + {time, EV_ABS, ABS_Y, 749},
|
| + {time, EV_ABS, ABS_PRESSURE, 50},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| +
|
| + // Initialize the device.
|
| + dev->Initialize(devinfo);
|
| +
|
| + dev->ConfigureReadMock(mock_kernel_queue_press,
|
| + arraysize(mock_kernel_queue_press), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| +
|
| + ui::TouchEventParams ev1 = dispatched_event(0);
|
| + EXPECT_EQ(ET_TOUCH_PRESSED, ev1.type);
|
| + EXPECT_EQ(0, ev1.slot);
|
| + EXPECT_EQ(1003, ev1.location.x());
|
| + EXPECT_EQ(749, ev1.location.y());
|
| +
|
| + // Disable the device (should release the contact).
|
| + dev->SetEnabled(false);
|
| + EXPECT_EQ(2u, size());
|
| +
|
| + ui::TouchEventParams ev2 = dispatched_event(1);
|
| + EXPECT_EQ(ET_TOUCH_RELEASED, ev2.type);
|
| + EXPECT_EQ(0, ev2.slot);
|
| +
|
| + // Set up the previous contact in slot 0.
|
| + devinfo.SetAbsMtSlot(ABS_MT_TRACKING_ID, 0, 0);
|
| + devinfo.SetAbsMtSlot(ABS_MT_TOUCH_MAJOR, 0, 116);
|
| + devinfo.SetAbsMtSlot(ABS_MT_POSITION_X, 0, 1003);
|
| + devinfo.SetAbsMtSlot(ABS_MT_POSITION_Y, 0, 749);
|
| + devinfo.SetAbsMtSlot(ABS_MT_PRESSURE, 0, 50);
|
| +
|
| + // Re-enable the device (should re-apply the contact).
|
| + dev->SimulateReinitialize(devinfo);
|
| + dev->SetEnabled(true);
|
| + EXPECT_EQ(3u, size());
|
| +
|
| + ui::TouchEventParams ev3 = dispatched_event(2);
|
| + EXPECT_EQ(ET_TOUCH_PRESSED, ev3.type);
|
| + EXPECT_EQ(0, ev3.slot);
|
| + EXPECT_EQ(1003, ev3.location.x());
|
| + EXPECT_EQ(749, ev3.location.y());
|
| +}
|
| +
|
| +// crbug.com/477695
|
| +TEST_F(TouchEventConverterEvdevTest, ShouldUseLeftButtonIfNoTouchButton) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + InitEloTouchscreen(dev);
|
| +
|
| + // Captured from Elo TouchSystems 2700.
|
| + timeval time;
|
| + time = {1433965490, 837958};
|
| + struct input_event mock_kernel_queue_press[] = {
|
| + {time, EV_ABS, ABS_X, 3654},
|
| + {time, EV_ABS, ABS_Y, 1054},
|
| + {time, EV_ABS, ABS_MISC, 18},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| +
|
| + {time, EV_MSC, MSC_SCAN, 90001},
|
| + {time, EV_KEY, BTN_LEFT, 1},
|
| + {time, EV_ABS, ABS_Y, 1055},
|
| + {time, EV_ABS, ABS_MISC, 25},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| + time = {1433965491, 1953};
|
| + struct input_event mock_kernel_queue_move[] = {
|
| + {time, EV_ABS, ABS_X, 3644},
|
| + {time, EV_ABS, ABS_Y, 1059},
|
| + {time, EV_ABS, ABS_MISC, 36},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| + time = {1433965491, 225959};
|
| + struct input_event mock_kernel_queue_release[] = {
|
| + {time, EV_MSC, MSC_SCAN, 90001},
|
| + {time, EV_KEY, BTN_LEFT, 0},
|
| + {time, EV_ABS, ABS_MISC, 0},
|
| + {time, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| +
|
| + // Press.
|
| + dev->ConfigureReadMock(mock_kernel_queue_press,
|
| + arraysize(mock_kernel_queue_press), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(1u, size());
|
| + ui::TouchEventParams event = dispatched_event(0);
|
| + EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965490837958),
|
| + event.timestamp);
|
| + EXPECT_EQ(3654, event.location.x());
|
| + EXPECT_EQ(1055, event.location.y());
|
| + EXPECT_EQ(0, event.slot);
|
| + EXPECT_FLOAT_EQ(0.f, event.radii.x());
|
| + EXPECT_FLOAT_EQ(0.f, event.pressure);
|
| +
|
| + // Move.
|
| + dev->ConfigureReadMock(mock_kernel_queue_move,
|
| + arraysize(mock_kernel_queue_move), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(2u, size());
|
| + event = dispatched_event(1);
|
| + EXPECT_EQ(ui::ET_TOUCH_MOVED, event.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965491001953),
|
| + event.timestamp);
|
| + EXPECT_EQ(3644, event.location.x());
|
| + EXPECT_EQ(1059, event.location.y());
|
| + EXPECT_EQ(0, event.slot);
|
| + EXPECT_FLOAT_EQ(0.f, event.radii.x());
|
| + EXPECT_FLOAT_EQ(0.f, event.pressure);
|
| +
|
| + // Release.
|
| + dev->ConfigureReadMock(mock_kernel_queue_release,
|
| + arraysize(mock_kernel_queue_release), 0);
|
| + dev->ReadNow();
|
| + EXPECT_EQ(3u, size());
|
| + event = dispatched_event(2);
|
| + EXPECT_EQ(ui::ET_TOUCH_RELEASED, event.type);
|
| + EXPECT_EQ(base::TimeDelta::FromMicroseconds(1433965491225959),
|
| + event.timestamp);
|
| + EXPECT_EQ(3644, event.location.x());
|
| + EXPECT_EQ(1059, event.location.y());
|
| + EXPECT_EQ(0, event.slot);
|
| + EXPECT_FLOAT_EQ(0.f, event.radii.x());
|
| + EXPECT_FLOAT_EQ(0.f, event.pressure);
|
| +
|
| + // No dispatch on destruction.
|
| + DestroyDevice();
|
| + EXPECT_EQ(3u, size());
|
| +}
|
| +
|
| +// crbug.com/407386
|
| +TEST_F(TouchEventConverterEvdevTest,
|
| + DontChangeMultitouchPositionFromLegacyAxes) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + InitPixelTouchscreen(dev);
|
| +
|
| + struct input_event mock_kernel_queue[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_SLOT, 0},
|
| + {{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_PRESSURE, 55},
|
| + {{0, 0}, EV_ABS, ABS_MT_SLOT, 1},
|
| + {{0, 0}, EV_ABS, ABS_MT_TRACKING_ID, 200},
|
| + {{0, 0}, EV_ABS, ABS_MT_PRESSURE, 44},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_X, 777},
|
| + {{0, 0}, EV_ABS, ABS_MT_POSITION_Y, 666},
|
| + {{0, 0}, EV_ABS, ABS_X, 999},
|
| + {{0, 0}, EV_ABS, ABS_Y, 888},
|
| + {{0, 0}, EV_ABS, ABS_PRESSURE, 55},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| +
|
| + // Check that two events are generated.
|
| + dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
|
| + dev->ReadNow();
|
| +
|
| + const unsigned int kExpectedEventCount = 2;
|
| + EXPECT_EQ(kExpectedEventCount, size());
|
| + if (kExpectedEventCount != size())
|
| + return;
|
| +
|
| + ui::TouchEventParams ev0 = dispatched_event(0);
|
| + ui::TouchEventParams ev1 = dispatched_event(1);
|
| +
|
| + EXPECT_EQ(0, ev0.slot);
|
| + EXPECT_EQ(999, ev0.location.x());
|
| + EXPECT_EQ(888, ev0.location.y());
|
| + EXPECT_FLOAT_EQ(0.21568628f, ev0.pressure);
|
| +
|
| + EXPECT_EQ(1, ev1.slot);
|
| + EXPECT_EQ(777, ev1.location.x());
|
| + EXPECT_EQ(666, ev1.location.y());
|
| + EXPECT_FLOAT_EQ(0.17254902f, ev1.pressure);
|
| +}
|
| +
|
| +// crbug.com/446939
|
| +TEST_F(TouchEventConverterEvdevTest, CheckSlotLimit) {
|
| + ui::MockTouchEventConverterEvdev* dev = device();
|
| +
|
| + struct input_event mock_kernel_queue[] = {
|
| + {{0, 0}, EV_ABS, ABS_MT_SLOT, 0},
|
| + {{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::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},
|
| + {{0, 0}, EV_SYN, SYN_REPORT, 0},
|
| + };
|
| +
|
| + // Check that one 1 event is generated
|
| + dev->ConfigureReadMock(mock_kernel_queue, arraysize(mock_kernel_queue), 0);
|
| + 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
|
|
|