// 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 "ui/events/ozone/evdev/tablet_event_converter_evdev.h"

#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <unistd.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/memory/ptr_util.h"
#include "base/posix/eintr_wrapper.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event.h"
#include "ui/events/ozone/device/device_manager.h"
#include "ui/events/ozone/evdev/event_converter_test_util.h"
#include "ui/events/ozone/evdev/event_device_test_util.h"
#include "ui/events/ozone/evdev/event_factory_evdev.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/test/scoped_event_test_tick_clock.h"

namespace {

const char kTestDevicePath[] = "/dev/input/test-device";

const ui::DeviceAbsoluteAxis kWacomIntuos5SPenAbsAxes[] = {
    {ABS_X, {0, 0, 31496, 4, 0, 200}},
    {ABS_Y, {0, 0, 19685, 4, 0, 200}},
    {ABS_Z, {0, -900, 899, 0, 0, 0}},
    {ABS_RZ, {0, -900, 899, 0, 0, 0}},
    {ABS_THROTTLE, {0, -1023, 1023, 0, 0, 0}},
    {ABS_WHEEL, {0, 0, 1023, 0, 0, 0}},
    {ABS_PRESSURE, {0, 0, 2047, 0, 0, 0}},
    {ABS_DISTANCE, {0, 0, 63, 0, 0, 0}},
    {ABS_TILT_X, {0, 0, 127, 0, 0, 0}},
    {ABS_TILT_Y, {0, 0, 127, 0, 0, 0}},
    {ABS_MISC, {0, 0, 0, 0, 0, 0}},
};

const ui::DeviceCapabilities kWacomIntuos5SPen = {
    /* path */
    "/sys/devices/pci0000:00/0000:00:14.0/usb1/"
    "1-1/1-1:1.0/input/input19/event5",
    /* name */ "Wacom Intuos5 touch S Pen",
    /* phys */ "",
    /* uniq */ "",
    /* bustype */ "0003",
    /* vendor */ "056a",
    /* product */ "0026",
    /* version */ "0107",
    /* prop */ "1",
    /* ev */ "1f",
    /* key */ "1cdf 1f007f 0 0 0 0",
    /* rel */ "100",
    /* abs */ "1000f000167",
    /* msc */ "1",
    /* sw */ "0",
    /* led */ "0",
    /* ff */ "0",
    kWacomIntuos5SPenAbsAxes,
    base::size(kWacomIntuos5SPenAbsAxes),
};

const ui::DeviceAbsoluteAxis EpsonBrightLink1430AbsAxes[] = {
    {ABS_X, {0, 0, 32767, 0, 0, 200}},
    {ABS_Y, {0, 0, 32767, 0, 0, 200}},
    {ABS_Z, {0, 0, 32767, 0, 0, 200}},
    {ABS_RX,{0, 0, 32767, 0, 0, 200}},
    {ABS_PRESSURE, {0, 0, 32767, 0, 0, 0}},
};

const ui::DeviceCapabilities EpsonBrightLink1430 = {
    /* path */
    "/sys/devices/ff580000.usb/usb3/3-1/"
    "3-1.1/3-1.1.3/3-1.1.3:1.1/0003:04B8:061B.0006/"
    "input/input12/event6",
    /* name */ "EPSON EPSON EPSON 1430",
    /* phys */ "USB-ff580000.USB-1.1.3/input1",
    /* uniq */ "2.04",
    /* bustype */ "0003",
    /* vendor */ "04b8",
    /* product */ "061b",
    /* version */ "0200",
    /* prop */ "0",
    /* ev */ "1b",
    /* key */ "c07 30000 0 0 0 0",
    /* rel */ "0",
    /* abs */ "100000f",
    /* msc */ "10",
    /* sw */ "0",
    /* led */ "0",
    /* ff */ "0",
    EpsonBrightLink1430AbsAxes,
    base::size(EpsonBrightLink1430AbsAxes),
};

}  // namespace

namespace ui {

class MockTabletEventConverterEvdev : public TabletEventConverterEvdev {
 public:
  MockTabletEventConverterEvdev(base::ScopedFD fd,
                                base::FilePath path,
                                CursorDelegateEvdev* cursor,
                                const EventDeviceInfo& devinfo,
                                DeviceEventDispatcherEvdev* dispatcher);
  ~MockTabletEventConverterEvdev() 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();
  }

 private:
  int read_pipe_;
  int write_pipe_;

  std::vector<std::unique_ptr<Event>> dispatched_events_;

  DISALLOW_COPY_AND_ASSIGN(MockTabletEventConverterEvdev);
};

class MockTabletCursorEvdev : public CursorDelegateEvdev {
 public:
  MockTabletCursorEvdev() { cursor_confined_bounds_ = gfx::Rect(1024, 768); }
  ~MockTabletCursorEvdev() override {}

  // CursorDelegateEvdev:
  void MoveCursorTo(gfx::AcceleratedWidget widget,
                    const gfx::PointF& location) override {
    NOTREACHED();
  }
  void MoveCursorTo(const gfx::PointF& location) override {
    cursor_location_ = location;
  }
  void MoveCursor(const gfx::Vector2dF& delta) override { NOTREACHED(); }
  bool IsCursorVisible() override { return 1; }
  gfx::PointF GetLocation() override { return cursor_location_; }
  gfx::Rect GetCursorConfinedBounds() override {
    return cursor_confined_bounds_;
  }
  void InitializeOnEvdev() override {}
 private:
  gfx::PointF cursor_location_;
  gfx::Rect cursor_confined_bounds_;
  DISALLOW_COPY_AND_ASSIGN(MockTabletCursorEvdev);
};

MockTabletEventConverterEvdev::MockTabletEventConverterEvdev(
    base::ScopedFD fd,
    base::FilePath path,
    CursorDelegateEvdev* cursor,
    const EventDeviceInfo& devinfo,
    DeviceEventDispatcherEvdev* dispatcher)
    : TabletEventConverterEvdev(std::move(fd),
                                path,
                                1,
                                cursor,
                                devinfo,
                                dispatcher) {
  int fds[2];

  if (pipe(fds))
    PLOG(FATAL) << "failed pipe";

  EXPECT_TRUE(base::SetNonBlocking(fds[0]) || base::SetNonBlocking(fds[1]))
    << "failed to set non-blocking: " << strerror(errno);

  read_pipe_ = fds[0];
  write_pipe_ = fds[1];
}

void MockTabletEventConverterEvdev::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;
}

}  // namespace ui

// Test fixture.
class TabletEventConverterEvdevTest : public testing::Test {
 public:
  TabletEventConverterEvdevTest() {}

  // Overridden from testing::Test:
  void SetUp() override {
    cursor_ = std::make_unique<ui::MockTabletCursorEvdev>();
    device_manager_ = ui::CreateDeviceManagerForTest();
    keyboard_layout_engine_ = std::make_unique<ui::StubKeyboardLayoutEngine>();
    event_factory_ = ui::CreateEventFactoryEvdevForTest(
        cursor_.get(), device_manager_.get(), keyboard_layout_engine_.get(),
        base::BindRepeating(
            &TabletEventConverterEvdevTest::DispatchEventForTest,
            base::Unretained(this)));
    dispatcher_ =
        ui::CreateDeviceEventDispatcherEvdevForTest(event_factory_.get());

    test_clock_ = std::make_unique<ui::test::ScopedEventTestTickClock>();
  }

  void TearDown() override {
    cursor_.reset();
  }

  ui::MockTabletEventConverterEvdev* CreateDevice(
      const ui::DeviceCapabilities& caps) {
    // Set up pipe to satisfy message pump (unused).
    int evdev_io[2];
    if (pipe(evdev_io))
      PLOG(FATAL) << "failed pipe";
    base::ScopedFD events_in(evdev_io[0]);
    events_out_.reset(evdev_io[1]);

    ui::EventDeviceInfo devinfo;
    CapabilitiesToDeviceInfo(caps, &devinfo);
    return new ui::MockTabletEventConverterEvdev(
        std::move(events_in), base::FilePath(kTestDevicePath), cursor_.get(),
        devinfo, dispatcher_.get());
  }

  ui::CursorDelegateEvdev* cursor() { return cursor_.get(); }

  unsigned size() { return dispatched_events_.size(); }
  ui::MouseEvent* dispatched_event(unsigned index) {
    DCHECK_GT(dispatched_events_.size(), index);
    ui::Event* ev = dispatched_events_[index].get();
    DCHECK(ev->IsMouseEvent());
    return ev->AsMouseEvent();
  }

  void DispatchEventForTest(ui::Event* event) {
    std::unique_ptr<ui::Event> cloned_event = ui::Event::Clone(*event);
    dispatched_events_.push_back(std::move(cloned_event));
  }

 private:
  std::unique_ptr<ui::MockTabletCursorEvdev> cursor_;
  std::unique_ptr<ui::DeviceManager> device_manager_;
  std::unique_ptr<ui::KeyboardLayoutEngine> keyboard_layout_engine_;
  std::unique_ptr<ui::EventFactoryEvdev> event_factory_;
  std::unique_ptr<ui::DeviceEventDispatcherEvdev> dispatcher_;
  std::unique_ptr<ui::test::ScopedEventTestTickClock> test_clock_;

  std::vector<std::unique_ptr<ui::Event>> dispatched_events_;

  base::ScopedFD events_out_;

  DISALLOW_COPY_AND_ASSIGN(TabletEventConverterEvdevTest);
};

#define EPSILON 20

// Uses real data captured from Wacom Intuos 5 Pen
TEST_F(TabletEventConverterEvdevTest, MoveTopLeft) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(kWacomIntuos5SPen));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_DISTANCE, 63},
      {{0, 0}, EV_ABS, ABS_X, 477},
      {{0, 0}, EV_ABS, ABS_TILT_X, 66},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 62},
      {{0, 0}, EV_ABS, ABS_MISC, 1050626},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
      {{0, 0}, EV_ABS, ABS_TILT_X, 0},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_ABS, ABS_MISC, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(1u, size());

  ui::MouseEvent* event = dispatched_event(0);
  EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());

  EXPECT_LT(cursor()->GetLocation().x(), EPSILON);
  EXPECT_LT(cursor()->GetLocation().y(), EPSILON);
}

TEST_F(TabletEventConverterEvdevTest, MoveTopRight) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(kWacomIntuos5SPen));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_DISTANCE, 63},
      {{0, 0}, EV_ABS, ABS_X, 31496},
      {{0, 0}, EV_ABS, ABS_Y, 109},
      {{0, 0}, EV_ABS, ABS_TILT_X, 66},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 61},
      {{0, 0}, EV_ABS, ABS_MISC, 1050626},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 0},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
      {{0, 0}, EV_ABS, ABS_TILT_X, 0},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_ABS, ABS_MISC, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(1u, size());

  ui::MouseEvent* event = dispatched_event(0);
  EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());

  EXPECT_GT(cursor()->GetLocation().x(),
            cursor()->GetCursorConfinedBounds().width() - EPSILON);
  EXPECT_LT(cursor()->GetLocation().y(), EPSILON);
}

TEST_F(TabletEventConverterEvdevTest, MoveBottomLeft) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(kWacomIntuos5SPen));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_DISTANCE, 63},
      {{0, 0}, EV_ABS, ABS_Y, 19685},
      {{0, 0}, EV_ABS, ABS_TILT_X, 64},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 61},
      {{0, 0}, EV_ABS, ABS_MISC, 1050626},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 0},
      {{0, 0}, EV_ABS, ABS_Y, 0},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
      {{0, 0}, EV_ABS, ABS_TILT_X, 0},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_ABS, ABS_MISC, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(1u, size());

  ui::MouseEvent* event = dispatched_event(0);
  EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());

  EXPECT_LT(cursor()->GetLocation().x(), EPSILON);
  EXPECT_GT(cursor()->GetLocation().y(),
            cursor()->GetCursorConfinedBounds().height() - EPSILON);
}

TEST_F(TabletEventConverterEvdevTest, MoveBottomRight) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(kWacomIntuos5SPen));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_DISTANCE, 63},
      {{0, 0}, EV_ABS, ABS_X, 31496},
      {{0, 0}, EV_ABS, ABS_Y, 19685},
      {{0, 0}, EV_ABS, ABS_TILT_X, 67},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 63},
      {{0, 0}, EV_ABS, ABS_MISC, 1050626},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 0},
      {{0, 0}, EV_ABS, ABS_Y, 0},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
      {{0, 0}, EV_ABS, ABS_TILT_X, 0},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_ABS, ABS_MISC, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(1u, size());

  ui::MouseEvent* event = dispatched_event(0);
  EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());

  EXPECT_GT(cursor()->GetLocation().x(),
            cursor()->GetCursorConfinedBounds().height() - EPSILON);
  EXPECT_GT(cursor()->GetLocation().y(),
            cursor()->GetCursorConfinedBounds().height() - EPSILON);
}

TEST_F(TabletEventConverterEvdevTest, Tap) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(kWacomIntuos5SPen));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_X, 15456},
      {{0, 0}, EV_ABS, ABS_Y, 8605},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 49},
      {{0, 0}, EV_ABS, ABS_TILT_X, 68},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 64},
      {{0, 0}, EV_ABS, ABS_MISC, 1050626},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 15725},
      {{0, 0}, EV_ABS, ABS_Y, 8755},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 29},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 992},
      {{0, 0}, EV_KEY, BTN_TOUCH, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 15922},
      {{0, 0}, EV_ABS, ABS_Y, 8701},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 32},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 0},
      {{0, 0}, EV_KEY, BTN_TOUCH, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 0},
      {{0, 0}, EV_ABS, ABS_Y, 0},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
      {{0, 0}, EV_ABS, ABS_TILT_X, 0},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_ABS, ABS_MISC, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(3u, size());

  ui::MouseEvent* event = dispatched_event(0);
  EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
  EXPECT_EQ(ui::EventPointerType::POINTER_TYPE_PEN,
            event->pointer_details().pointer_type);
  EXPECT_FLOAT_EQ(5.625f, event->pointer_details().tilt_x);
  EXPECT_FLOAT_EQ(0.f, event->pointer_details().tilt_y);
  event = dispatched_event(1);
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type());
  EXPECT_EQ(ui::EventPointerType::POINTER_TYPE_PEN,
            event->pointer_details().pointer_type);
  EXPECT_FLOAT_EQ((float)992 / 2047, event->pointer_details().force);
  EXPECT_EQ(true, event->IsLeftMouseButton());
  event = dispatched_event(2);
  EXPECT_EQ(ui::EventPointerType::POINTER_TYPE_PEN,
            event->pointer_details().pointer_type);
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type());
  EXPECT_FLOAT_EQ(0.0f, event->pointer_details().force);
  EXPECT_EQ(true, event->IsLeftMouseButton());
}

TEST_F(TabletEventConverterEvdevTest, StylusButtonPress) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(kWacomIntuos5SPen));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_DISTANCE, 63},
      {{0, 0}, EV_ABS, ABS_X, 18372},
      {{0, 0}, EV_ABS, ABS_Y, 9880},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 61},
      {{0, 0}, EV_ABS, ABS_TILT_X, 60},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 63},
      {{0, 0}, EV_ABS, ABS_MISC, 1050626},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 18294},
      {{0, 0}, EV_ABS, ABS_Y, 9723},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 20},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 1015},
      {{0, 0}, EV_KEY, BTN_STYLUS2, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 18516},
      {{0, 0}, EV_ABS, ABS_Y, 9723},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 23},
      {{0, 0}, EV_KEY, BTN_STYLUS2, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 0},
      {{0, 0}, EV_ABS, ABS_Y, 0},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
      {{0, 0}, EV_ABS, ABS_TILT_X, 0},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_ABS, ABS_MISC, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(3u, size());

  ui::MouseEvent* event = dispatched_event(0);
  EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());
  event = dispatched_event(1);
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type());
  EXPECT_EQ(true, event->IsRightMouseButton());
  event = dispatched_event(2);
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type());
  EXPECT_EQ(true, event->IsRightMouseButton());
}

// Should only get an event if BTN_TOOL received
TEST_F(TabletEventConverterEvdevTest, CheckStylusFiltering) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(kWacomIntuos5SPen));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_X, 0},
      {{0, 0}, EV_ABS, ABS_Y, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(0u, size());
}

// for digitizer pen with only one side button
TEST_F(TabletEventConverterEvdevTest, DigitizerPenOneSideButtonPress) {
  std::unique_ptr<ui::MockTabletEventConverterEvdev> dev =
      base::WrapUnique(CreateDevice(EpsonBrightLink1430));

  struct input_event mock_kernel_queue[] = {
      {{0, 0}, EV_ABS, ABS_DISTANCE, 63},
      {{0, 0}, EV_ABS, ABS_X, 18372},
      {{0, 0}, EV_ABS, ABS_Y, 9880},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 61},
      {{0, 0}, EV_ABS, ABS_TILT_X, 60},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 63},
      {{0, 0}, EV_ABS, ABS_MISC, 1050626},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      {{0, 0}, EV_ABS, ABS_X, 18294},
      {{0, 0}, EV_ABS, ABS_Y, 9723},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 20},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 1015},
      {{0, 0}, EV_KEY, BTN_STYLUS, 1},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      {{0, 0}, EV_ABS, ABS_X, 18516},
      {{0, 0}, EV_ABS, ABS_Y, 9723},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 23},
      {{0, 0}, EV_KEY, BTN_STYLUS, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      {{0, 0}, EV_ABS, ABS_X, 0},
      {{0, 0}, EV_ABS, ABS_Y, 0},
      {{0, 0}, EV_ABS, ABS_DISTANCE, 0},
      {{0, 0}, EV_ABS, ABS_TILT_X, 0},
      {{0, 0}, EV_ABS, ABS_TILT_Y, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_ABS, ABS_MISC, 0},
      {{0, 0}, EV_MSC, MSC_SERIAL, 897618290},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ProcessEvents(mock_kernel_queue, base::size(mock_kernel_queue));
  EXPECT_EQ(3u, size());

  ui::MouseEvent* event = dispatched_event(0);
  EXPECT_EQ(ui::ET_MOUSE_MOVED, event->type());

  event = dispatched_event(1);
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, event->type());
  EXPECT_EQ(true, event->IsRightMouseButton());

  event = dispatched_event(2);
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, event->type());
  EXPECT_EQ(true, event->IsRightMouseButton());

}
