// 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/touch_event_converter_evdev.h"

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

#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/message_loop/message_loop.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/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_filter/false_touch_finder.h"
#include "ui/events/ozone/evdev/touch_filter/touch_filter.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 ui {

namespace {

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

// Returns a fake TimeTicks based on the given microsecond offset.
base::TimeTicks ToTestTimeTicks(int64_t micros) {
  return base::TimeTicks() + base::TimeDelta::FromMicroseconds(micros);
}

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);
}

enum class GenericEventParamsType { MOUSE_MOVE, MOUSE_BUTTON, TOUCH };

struct GenericEventParams {
  GenericEventParams() {}
  GenericEventParams(const GenericEventParams& other) {
    type = other.type;
    switch (type) {
      case GenericEventParamsType::MOUSE_MOVE:
        mouse_move = other.mouse_move;
        break;
      case GenericEventParamsType::MOUSE_BUTTON:
        mouse_button = other.mouse_button;
        break;
      case GenericEventParamsType::TOUCH:
        touch = other.touch;
        break;
    }
  }
  ~GenericEventParams() {}

  GenericEventParamsType type;
  union {
    MouseMoveEventParams mouse_move;
    MouseButtonEventParams mouse_button;
    TouchEventParams touch;
  };
};

}  // namespace

class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
 public:
  MockTouchEventConverterEvdev(base::ScopedFD 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 {}

  FalseTouchFinder* false_touch_finder() { return false_touch_finder_.get(); }

 private:
  int read_pipe_;
  int write_pipe_;

  DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev);
};

class MockDeviceEventDispatcherEvdev : public DeviceEventDispatcherEvdev {
 public:
  MockDeviceEventDispatcherEvdev(
      const base::RepeatingCallback<void(const GenericEventParams& params)>&
          callback)
      : callback_(callback) {}
  ~MockDeviceEventDispatcherEvdev() override {}

  // DeviceEventDispatcherEvdev:
  void DispatchKeyEvent(const KeyEventParams& params) override {}
  void DispatchMouseMoveEvent(const MouseMoveEventParams& params) override {
    GenericEventParams generic;
    generic.type = GenericEventParamsType::MOUSE_MOVE;
    generic.mouse_move = params;
    callback_.Run(generic);
  }
  void DispatchMouseButtonEvent(const MouseButtonEventParams& params) override {
    GenericEventParams generic;
    generic.type = GenericEventParamsType::MOUSE_BUTTON;
    generic.mouse_button = params;
    callback_.Run(generic);
  }
  void DispatchMouseWheelEvent(const MouseWheelEventParams& params) override {}
  void DispatchPinchEvent(const PinchEventParams& params) override {}
  void DispatchScrollEvent(const ScrollEventParams& params) override {}
  void DispatchTouchEvent(const TouchEventParams& params) override {
    GenericEventParams generic;
    generic.type = GenericEventParamsType::TOUCH;
    generic.touch = params;
    callback_.Run(generic);
  }

  void DispatchKeyboardDevicesUpdated(
      const std::vector<InputDevice>& 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 {}
  void DispatchStylusStateChanged(StylusState stylus_state) override {}

  // Dispatch Gamepad Event.
  void DispatchGamepadEvent(const GamepadEvent& event) override {}

  void DispatchGamepadDevicesUpdated(
      const std::vector<InputDevice>& devices) override {}

 private:
  base::RepeatingCallback<void(const GenericEventParams& params)> callback_;
};

MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
    base::ScopedFD fd,
    base::FilePath path,
    const EventDeviceInfo& devinfo,
    DeviceEventDispatcherEvdev* dispatcher)
    : TouchEventConverterEvdev(std::move(fd), path, 1, 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];

  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";
    base::ScopedFD events_in(evdev_io[0]);
    events_out_.reset(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::BindRepeating(&TouchEventConverterEvdevTest::DispatchCallback,
                            base::Unretained(this))));
    device_.reset(new ui::MockTouchEventConverterEvdev(
        std::move(events_in), base::FilePath(kTestDevicePath), devinfo,
        dispatcher_.get()));
    device_->Initialize(devinfo);
    loop_ = new base::MessageLoopForUI;

    test_clock_.reset(new ui::test::ScopedEventTestTickClock());
    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_touch_event(unsigned index) {
    DCHECK_GT(dispatched_events_.size(), index);
    EXPECT_EQ(GenericEventParamsType::TOUCH, dispatched_events_[index].type);
    return dispatched_events_[index].touch;
  }
  const ui::MouseMoveEventParams& dispatched_mouse_move_event(unsigned index) {
    DCHECK_GT(dispatched_events_.size(), index);
    EXPECT_EQ(GenericEventParamsType::MOUSE_MOVE,
              dispatched_events_[index].type);
    return dispatched_events_[index].mouse_move;
  }
  const ui::MouseButtonEventParams& dispatched_mouse_button_event(
      unsigned index) {
    DCHECK_GT(dispatched_events_.size(), index);
    EXPECT_EQ(GenericEventParamsType::MOUSE_BUTTON,
              dispatched_events_[index].type);
    return dispatched_events_[index].mouse_button;
  }
  void ClearDispatchedEvents() { dispatched_events_.clear(); }

  void DestroyDevice() { device_.reset(); }

  void SetTestNowTime(timeval time) {
    base::TimeTicks ticks = base::TimeTicks() +
                            base::TimeDelta::FromSeconds(time.tv_sec) +
                            base::TimeDelta::FromMicroseconds(time.tv_usec);
    test_clock_->SetNowTicks(ticks);
  }

 private:
  base::MessageLoop* loop_;
  std::unique_ptr<ui::MockTouchEventConverterEvdev> device_;
  std::unique_ptr<ui::MockDeviceEventDispatcherEvdev> dispatcher_;
  std::unique_ptr<ui::test::ScopedEventTestTickClock> test_clock_;

  base::ScopedFD events_out_;

  void DispatchCallback(const GenericEventParams& params) {
    dispatched_events_.push_back(params);
  }
  std::vector<GenericEventParams> 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},
  };

  // Set test time to ensure above timestamps are strictly in the past.
  SetTestNowTime(time);

  // Press.
  dev->ConfigureReadMock(mock_kernel_queue_press,
                         base::size(mock_kernel_queue_press), 0);
  dev->ReadNow();
  EXPECT_EQ(1u, size());
  ui::TouchEventParams event = dispatched_touch_event(0);
  EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type);
  EXPECT_EQ(ToTestTimeTicks(1427323282019203), event.timestamp);
  EXPECT_EQ(295, event.location.x());
  EXPECT_EQ(421, event.location.y());
  EXPECT_EQ(0, event.slot);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            event.pointer_details.pointer_type);
  EXPECT_FLOAT_EQ(58.f, event.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(0.13333334f, event.pointer_details.force);

  // Move.
  dev->ConfigureReadMock(mock_kernel_queue_move,
                         base::size(mock_kernel_queue_move), 0);
  dev->ReadNow();
  EXPECT_EQ(2u, size());
  event = dispatched_touch_event(1);
  EXPECT_EQ(ui::ET_TOUCH_MOVED, event.type);
  EXPECT_EQ(ToTestTimeTicks(1427323282034693), event.timestamp);
  EXPECT_EQ(312, event.location.x());
  EXPECT_EQ(432, event.location.y());
  EXPECT_EQ(0, event.slot);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            event.pointer_details.pointer_type);
  EXPECT_FLOAT_EQ(50.f, event.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(0.16862745f, event.pointer_details.force);

  // Release.
  dev->ConfigureReadMock(mock_kernel_queue_release,
                         base::size(mock_kernel_queue_release), 0);
  dev->ReadNow();
  EXPECT_EQ(3u, size());
  event = dispatched_touch_event(2);
  EXPECT_EQ(ui::ET_TOUCH_RELEASED, event.type);
  EXPECT_EQ(ToTestTimeTicks(1427323282144540), event.timestamp);
  EXPECT_EQ(312, event.location.x());
  EXPECT_EQ(432, event.location.y());
  EXPECT_EQ(0, event.slot);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            event.pointer_details.pointer_type);
  EXPECT_FLOAT_EQ(50.f, event.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(0.16862745f, event.pointer_details.force);
}

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_touch_event(2);
  ui::TouchEventParams ev1 = dispatched_touch_event(3);

  // Move
  EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.force);

  // Press
  EXPECT_EQ(ui::ET_TOUCH_PRESSED, ev1.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.force);

  // 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_touch_event(4);

  EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.force);

  // 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_touch_event(5);

  EXPECT_EQ(ui::ET_TOUCH_MOVED, ev0.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.force);

  // 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_touch_event(6);
  ev1 = dispatched_touch_event(7);

  EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev0.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.force);

  EXPECT_EQ(ui::ET_TOUCH_MOVED, ev1.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.force);

  // 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_touch_event(8);

  EXPECT_EQ(ui::ET_TOUCH_RELEASED, ev1.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.force);
}

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,
                         base::size(mock_kernel_queue_empty_report), 0);
  dev->ReadNow();
  EXPECT_EQ(1u, size());

  ui::TouchEventParams ev = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev.type);
  EXPECT_EQ(0, ev.slot);
  EXPECT_FLOAT_EQ(50.f, ev.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(50.f, ev.pointer_details.radius_y);
  EXPECT_FLOAT_EQ(0.50196081f, ev.pointer_details.force);
}

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},
  };

  // Set test now time to ensure above timestamps are in the past.
  SetTestNowTime(time);

  dev->ConfigureReadMock(mock_kernel_queue_press,
                         base::size(mock_kernel_queue_press), 0);
  dev->ReadNow();
  EXPECT_EQ(1u, size());

  ui::TouchEventParams ev1 = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev1.type);
  EXPECT_EQ(0, ev1.slot);

  DestroyDevice();
  EXPECT_EQ(2u, size());

  ui::TouchEventParams ev2 = dispatched_touch_event(1);
  EXPECT_EQ(ET_TOUCH_CANCELLED, 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},
  };

  // Set test now time to ensure above timestamps are in the past.
  SetTestNowTime(time);

  // Initialize the device.
  dev->Initialize(devinfo);

  dev->ConfigureReadMock(mock_kernel_queue_press,
                         base::size(mock_kernel_queue_press), 0);
  dev->ReadNow();
  EXPECT_EQ(1u, size());

  ui::TouchEventParams ev1 = dispatched_touch_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_touch_event(1);
  EXPECT_EQ(ET_TOUCH_CANCELLED, 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 (touch is cancelled, should not come back)
  dev->SimulateReinitialize(devinfo);
  dev->SetEnabled(true);
  EXPECT_EQ(2u, size());

  // Send updates to touch (touch is cancelled, should not come back)
  dev->ConfigureReadMock(mock_kernel_queue_press,
                         base::size(mock_kernel_queue_press), 0);
  dev->ReadNow();
  EXPECT_EQ(2u, size());
}

TEST_F(TouchEventConverterEvdevTest, PalmShouldCancelTouch) {
  ui::MockTouchEventConverterEvdev* dev = device();

  EventDeviceInfo devinfo;
  EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkWithToolTypeTouchscreen, &devinfo));

  timeval time;
  time = {1429651083, 686882};
  int major_max = devinfo.GetAbsMaximum(ABS_MT_TOUCH_MAJOR);
  struct input_event mock_kernel_queue_max_major[] = {
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 0},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {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_ABS, ABS_MT_SLOT, 1},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 1},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {time, EV_ABS, ABS_MT_POSITION_X, 1103},
      {time, EV_ABS, ABS_MT_POSITION_Y, 649},
      {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},
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TOUCH_MAJOR, major_max},
      {time, EV_SYN, SYN_REPORT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_ABS, ABS_MT_SLOT, 1},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_SYN, SYN_REPORT, 0},
  };
  struct input_event mock_kernel_queue_tool_palm[] = {
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 2},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {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_ABS, ABS_MT_SLOT, 1},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 3},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {time, EV_ABS, ABS_MT_POSITION_X, 1103},
      {time, EV_ABS, ABS_MT_POSITION_Y, 649},
      {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},
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM},
      {time, EV_SYN, SYN_REPORT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_SYN, SYN_REPORT, 0},
  };

  // Set test now time to ensure above timestamps are in the past.
  SetTestNowTime(time);

  // Initialize the device.
  dev->Initialize(devinfo);

  dev->ConfigureReadMock(mock_kernel_queue_max_major,
                         base::size(mock_kernel_queue_max_major), 0);
  dev->ReadNow();
  EXPECT_EQ(4u, size());

  ui::TouchEventParams ev1_1 = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev1_1.type);
  EXPECT_EQ(0, ev1_1.slot);
  EXPECT_EQ(1003, ev1_1.location.x());
  EXPECT_EQ(749, ev1_1.location.y());

  ui::TouchEventParams ev1_2 = dispatched_touch_event(1);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev1_2.type);
  EXPECT_EQ(1, ev1_2.slot);
  EXPECT_EQ(1103, ev1_2.location.x());
  EXPECT_EQ(649, ev1_2.location.y());

  ui::TouchEventParams ev1_3 = dispatched_touch_event(2);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev1_3.type);
  EXPECT_EQ(0, ev1_3.slot);

  // We expect both touches to be cancelled even though
  // just one reported major at max value.
  ui::TouchEventParams ev1_4 = dispatched_touch_event(3);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev1_4.type);
  EXPECT_EQ(1, ev1_4.slot);

  dev->ConfigureReadMock(mock_kernel_queue_tool_palm,
                         base::size(mock_kernel_queue_tool_palm), 0);
  dev->ReadNow();
  EXPECT_EQ(8u, size());

  ui::TouchEventParams ev2_1 = dispatched_touch_event(4);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev2_1.type);
  EXPECT_EQ(0, ev2_1.slot);
  EXPECT_EQ(1003, ev2_1.location.x());
  EXPECT_EQ(749, ev2_1.location.y());

  ui::TouchEventParams ev2_2 = dispatched_touch_event(5);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev2_2.type);
  EXPECT_EQ(1, ev2_2.slot);
  EXPECT_EQ(1103, ev2_2.location.x());
  EXPECT_EQ(649, ev2_2.location.y());

  ui::TouchEventParams ev2_3 = dispatched_touch_event(6);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev2_3.type);
  EXPECT_EQ(0, ev2_3.slot);

  // We expect both touches to be cancelled even though
  // just one reported MT_TOOL_PALM.
  ui::TouchEventParams ev2_4 = dispatched_touch_event(7);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev2_4.type);
  EXPECT_EQ(1, ev2_4.slot);
}

// crbug.com/773087
TEST_F(TouchEventConverterEvdevTest, TrackingIdShouldNotResetCancelByPalm) {
  ui::MockTouchEventConverterEvdev* dev = device();

  EventDeviceInfo devinfo;
  EXPECT_TRUE(CapabilitiesToDeviceInfo(kLinkWithToolTypeTouchscreen, &devinfo));

  timeval time;
  time = {1429651083, 686882};
  int major_max = devinfo.GetAbsMaximum(ABS_MT_TOUCH_MAJOR);
  struct input_event mock_kernel_queue_max_major[] = {
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 0},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {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_ABS, ABS_MT_SLOT, 1},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 1},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {time, EV_ABS, ABS_MT_POSITION_X, 1103},
      {time, EV_ABS, ABS_MT_POSITION_Y, 649},
      {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},
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TOUCH_MAJOR, major_max},
      {time, EV_SYN, SYN_REPORT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_ABS, ABS_MT_SLOT, 1},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_SYN, SYN_REPORT, 0},
  };
  // No events will be generated from the following queue. Here is why:
  // The touch in SLOT 0 was identified as a palm in previous events, thus it
  // was cancelled. In the following events, there is new trcking id for slot
  // 0, but there is no MT_TOOL_FINGER and TOUCH_MAJOR saying it's a finger.
  // Thus the slot will continue to be a palm and all events will be cancelled.
  struct input_event mock_kernel_new_touch_without_new_major[] = {
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 3},
      {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_SLOT, 1},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 4},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {time, EV_ABS, ABS_MT_POSITION_X, 1103},
      {time, EV_ABS, ABS_MT_POSITION_Y, 649},
      {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},
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_SYN, SYN_REPORT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_SYN, SYN_REPORT, 0},
      {time, EV_ABS, ABS_MT_SLOT, 1},
      {time, EV_SYN, SYN_REPORT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_SYN, SYN_REPORT, 0},
  };

  // This time, there is MT_TOOL_FINGER for slot 0, thus events should be
  // dispatched.
  struct input_event mock_kernel_queue_tool_palm[] = {
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 2},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {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_ABS, ABS_MT_SLOT, 1},
      {time, EV_ABS, ABS_MT_TRACKING_ID, 3},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER},
      {time, EV_ABS, ABS_MT_POSITION_X, 1103},
      {time, EV_ABS, ABS_MT_POSITION_Y, 649},
      {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},
      {time, EV_ABS, ABS_MT_SLOT, 0},
      {time, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM},
      {time, EV_SYN, SYN_REPORT, 0},
      {time, EV_ABS, ABS_MT_TRACKING_ID, -1},
      {time, EV_SYN, SYN_REPORT, 0},
  };

  // Set test now time to ensure above timestamps are in the past.
  SetTestNowTime(time);

  // Initialize the device.
  dev->Initialize(devinfo);

  dev->ConfigureReadMock(mock_kernel_queue_max_major,
                         base::size(mock_kernel_queue_max_major), 0);
  dev->ReadNow();
  EXPECT_EQ(4u, size());

  ui::TouchEventParams ev1_1 = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev1_1.type);
  EXPECT_EQ(0, ev1_1.slot);
  EXPECT_EQ(1003, ev1_1.location.x());
  EXPECT_EQ(749, ev1_1.location.y());

  ui::TouchEventParams ev1_2 = dispatched_touch_event(1);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev1_2.type);
  EXPECT_EQ(1, ev1_2.slot);
  EXPECT_EQ(1103, ev1_2.location.x());
  EXPECT_EQ(649, ev1_2.location.y());

  ui::TouchEventParams ev1_3 = dispatched_touch_event(2);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev1_3.type);
  EXPECT_EQ(0, ev1_3.slot);

  // We expect both touches to be cancelled even though
  // just one reported major at max value.
  ui::TouchEventParams ev1_4 = dispatched_touch_event(3);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev1_4.type);
  EXPECT_EQ(1, ev1_4.slot);

  dev->ConfigureReadMock(mock_kernel_new_touch_without_new_major,
                         base::size(mock_kernel_new_touch_without_new_major),
                         0);
  dev->ReadNow();
  EXPECT_EQ(4u, size());

  dev->ConfigureReadMock(mock_kernel_queue_tool_palm,
                         base::size(mock_kernel_queue_tool_palm), 0);
  dev->ReadNow();
  EXPECT_EQ(8u, size());

  ui::TouchEventParams ev2_1 = dispatched_touch_event(4);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev2_1.type);
  EXPECT_EQ(0, ev2_1.slot);
  EXPECT_EQ(1003, ev2_1.location.x());
  EXPECT_EQ(749, ev2_1.location.y());

  ui::TouchEventParams ev2_2 = dispatched_touch_event(5);
  EXPECT_EQ(ET_TOUCH_PRESSED, ev2_2.type);
  EXPECT_EQ(1, ev2_2.slot);
  EXPECT_EQ(1103, ev2_2.location.x());
  EXPECT_EQ(649, ev2_2.location.y());

  ui::TouchEventParams ev2_3 = dispatched_touch_event(6);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev2_3.type);
  EXPECT_EQ(0, ev2_3.slot);

  // We expect both touches to be cancelled even though
  // just one reported MT_TOOL_PALM.
  ui::TouchEventParams ev2_4 = dispatched_touch_event(7);
  EXPECT_EQ(ET_TOUCH_CANCELLED, ev2_4.type);
  EXPECT_EQ(1, ev2_4.slot);
}

// 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},
  };

  // Set test now time to ensure above timestamps are in the past.
  SetTestNowTime(time);

  // Press.
  dev->ConfigureReadMock(mock_kernel_queue_press,
                         base::size(mock_kernel_queue_press), 0);
  dev->ReadNow();
  EXPECT_EQ(1u, size());
  ui::TouchEventParams event = dispatched_touch_event(0);
  EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(0.f, event.pointer_details.force);

  // Move.
  dev->ConfigureReadMock(mock_kernel_queue_move,
                         base::size(mock_kernel_queue_move), 0);
  dev->ReadNow();
  EXPECT_EQ(2u, size());
  event = dispatched_touch_event(1);
  EXPECT_EQ(ui::ET_TOUCH_MOVED, event.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(0.f, event.pointer_details.force);

  // Release.
  dev->ConfigureReadMock(mock_kernel_queue_release,
                         base::size(mock_kernel_queue_release), 0);
  dev->ReadNow();
  EXPECT_EQ(3u, size());
  event = dispatched_touch_event(2);
  EXPECT_EQ(ui::ET_TOUCH_RELEASED, event.type);
  EXPECT_EQ(ToTestTimeTicks(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.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(0.f, event.pointer_details.force);

  // 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, base::size(mock_kernel_queue), 0);
  dev->ReadNow();

  const unsigned int kExpectedEventCount = 2;
  EXPECT_EQ(kExpectedEventCount, size());
  if (kExpectedEventCount != size())
    return;

  ui::TouchEventParams ev0 = dispatched_touch_event(0);
  ui::TouchEventParams ev1 = dispatched_touch_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.pointer_details.force);

  EXPECT_EQ(1, ev1.slot);
  EXPECT_EQ(777, ev1.location.x());
  EXPECT_EQ(666, ev1.location.y());
  EXPECT_FLOAT_EQ(0.17254902f, ev1.pointer_details.force);
}

// crbug.com/446939
TEST_F(TouchEventConverterEvdevTest, CheckSlotLimit) {
  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_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, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  EXPECT_EQ(1u, size());
}

namespace {

// TouchFilter which:
// - Considers all events of type |noise_event_type| as noise.
// - Keeps track of the events that it receives.
class EventTypeTouchNoiseFilter : public TouchFilter {
 public:
  explicit EventTypeTouchNoiseFilter(EventType noise_event_type)
      : noise_event_type_(noise_event_type) {}
  ~EventTypeTouchNoiseFilter() override {}

  // TouchFilter:
  void Filter(const std::vector<InProgressTouchEvdev>& touches,
              base::TimeTicks 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 FalseTouchFinder use |filter| and only |filter| to filter out
  // touch noise. Also removes any delay filters.
  void SetTouchNoiseFilter(std::unique_ptr<TouchFilter> filter) {
    FalseTouchFinder* finder = device()->false_touch_finder();
    finder->noise_filters_.clear();
    finder->noise_filters_.push_back(std::move(filter));
    finder->delay_filters_.clear();
  }

  // Returns the first of FalseTouchFinder's filters.
  ui::TouchFilter* first_filter() {
    FalseTouchFinder* finder = device()->false_touch_finder();
    return finder->noise_filters_.empty() ?
        nullptr :
        finder->noise_filters_.begin()->get();
  }

  // TouchEventConverterEvdevTest:
  void SetUp() override {
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kExtraTouchNoiseFiltering);
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kEdgeTouchFiltering);
    TouchEventConverterEvdevTest::SetUp();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdevTouchNoiseTest);
};

// Test that if FalseTouchFinder 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(std::unique_ptr<TouchFilter>(
      new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED)));
  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  ASSERT_EQ(0u, size());

  ClearDispatchedEvents();
  SetTouchNoiseFilter(std::unique_ptr<TouchFilter>(
      new EventTypeTouchNoiseFilter(ET_TOUCH_MOVED)));
  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  ASSERT_EQ(2u, size());
  TouchEventParams event0 = dispatched_touch_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_touch_event(1).type);

  ClearDispatchedEvents();
  SetTouchNoiseFilter(std::unique_ptr<TouchFilter>(
      new EventTypeTouchNoiseFilter(ET_TOUCH_RELEASED)));
  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  ASSERT_EQ(3u, size());
  event0 = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, event0.type);
  EXPECT_EQ(40, event0.location.x());
  EXPECT_EQ(41, event0.location.y());
  TouchEventParams event1 = dispatched_touch_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_touch_event(2).type);
}

// Test that TouchEventConverterEvdev keeps sending events to
// FalseTouchFinder after the touch is canceled.
TEST_F(TouchEventConverterEvdevTouchNoiseTest,
       DoNotSendTouchCancelsToFalseTouchFinder) {
  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(std::unique_ptr<TouchFilter>(
      new EventTypeTouchNoiseFilter(ET_TOUCH_PRESSED)));
  dev->ConfigureReadMock(mock_kernel_queue, base::size(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));
}

TEST_F(TouchEventConverterEvdevTest, ActiveStylusTouchAndRelease) {
  ui::MockTouchEventConverterEvdev* dev = device();
  EventDeviceInfo devinfo;
  EXPECT_TRUE(CapabilitiesToDeviceInfo(kWilsonBeachActiveStylus, &devinfo));
  dev->Initialize(devinfo);

  struct input_event mock_kernel_queue[]{
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_ABS, ABS_X, 9170},
      {{0, 0}, EV_ABS, ABS_Y, 3658},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_KEY, BTN_TOUCH, 1},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 60},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_KEY, BTN_TOUCH, 0},
      {{0, 0}, EV_ABS, ABS_X, 9173},
      {{0, 0}, EV_ABS, ABS_Y, 3906},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  EXPECT_EQ(2u, size());

  auto down_event = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, down_event.type);
  EXPECT_EQ(9170, down_event.location.x());
  EXPECT_EQ(3658, down_event.location.y());
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            down_event.pointer_details.pointer_type);
  EXPECT_EQ(60.f / 1024, down_event.pointer_details.force);

  auto up_event = dispatched_touch_event(1);
  EXPECT_EQ(ET_TOUCH_RELEASED, up_event.type);
  EXPECT_EQ(9173, up_event.location.x());
  EXPECT_EQ(3906, up_event.location.y());
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            up_event.pointer_details.pointer_type);
  EXPECT_EQ(0.f, up_event.pointer_details.force);
}

TEST_F(TouchEventConverterEvdevTest, ActiveStylusMotion) {
  ui::MockTouchEventConverterEvdev* dev = device();
  EventDeviceInfo devinfo;
  EXPECT_TRUE(CapabilitiesToDeviceInfo(kWilsonBeachActiveStylus, &devinfo));
  dev->Initialize(devinfo);

  struct input_event mock_kernel_queue[]{
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_ABS, ABS_X, 8921},
      {{0, 0}, EV_ABS, ABS_Y, 1072},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_KEY, BTN_TOUCH, 1},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 35},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 8934},
      {{0, 0}, EV_ABS, ABS_Y, 981},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 184},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_ABS, ABS_X, 8930},
      {{0, 0}, EV_ABS, ABS_Y, 980},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 348},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_KEY, BTN_TOUCH, 0},
      {{0, 0}, EV_ABS, ABS_PRESSURE, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  EXPECT_EQ(4u, size());

  ui::TouchEventParams event = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, event.type);
  EXPECT_EQ(8921, event.location.x());
  EXPECT_EQ(1072, event.location.y());
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            event.pointer_details.pointer_type);
  EXPECT_EQ(35.f / 1024, event.pointer_details.force);

  event = dispatched_touch_event(1);
  EXPECT_EQ(ET_TOUCH_MOVED, event.type);
  EXPECT_EQ(8934, event.location.x());
  EXPECT_EQ(981, event.location.y());
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            event.pointer_details.pointer_type);
  EXPECT_EQ(184.f / 1024, event.pointer_details.force);

  event = dispatched_touch_event(2);
  EXPECT_EQ(ET_TOUCH_MOVED, event.type);
  EXPECT_EQ(8930, event.location.x());
  EXPECT_EQ(980, event.location.y());
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            event.pointer_details.pointer_type);
  EXPECT_EQ(348.f / 1024, event.pointer_details.force);

  event = dispatched_touch_event(3);
  EXPECT_EQ(ET_TOUCH_RELEASED, event.type);
  EXPECT_EQ(8930, event.location.x());
  EXPECT_EQ(980, event.location.y());
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            event.pointer_details.pointer_type);
  EXPECT_EQ(0.f / 1024, event.pointer_details.force);
}

TEST_F(TouchEventConverterEvdevTest, ActiveStylusBarrelButtonWhileHovering) {
  ui::MockTouchEventConverterEvdev* dev = device();
  EventDeviceInfo devinfo;
  EXPECT_TRUE(CapabilitiesToDeviceInfo(kEveStylus, &devinfo));
  dev->Initialize(devinfo);

  struct input_event mock_kernel_queue[]{
      // Hover
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Button pressed
      {{0, 0}, EV_KEY, BTN_STYLUS, 1},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Touching down
      {{0, 0}, EV_KEY, BTN_TOUCH, 1},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Releasing touch
      {{0, 0}, EV_KEY, BTN_TOUCH, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Releasing button
      {{0, 0}, EV_KEY, BTN_STYLUS, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Leaving hover
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  EXPECT_EQ(2u, size());

  auto down_event = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, down_event.type);
  EXPECT_TRUE(down_event.flags & ui::EventFlags::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            down_event.pointer_details.pointer_type);

  auto up_event = dispatched_touch_event(1);
  EXPECT_EQ(ET_TOUCH_RELEASED, up_event.type);
  EXPECT_TRUE(down_event.flags & ui::EventFlags::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            up_event.pointer_details.pointer_type);
}

TEST_F(TouchEventConverterEvdevTest, ActiveStylusBarrelButton) {
  ui::MockTouchEventConverterEvdev* dev = device();
  EventDeviceInfo devinfo;
  EXPECT_TRUE(CapabilitiesToDeviceInfo(kEveStylus, &devinfo));
  dev->Initialize(devinfo);

  struct input_event mock_kernel_queue[]{
      // Hover
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 1},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Touching down
      {{0, 0}, EV_KEY, BTN_TOUCH, 1},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Button pressed
      {{0, 0}, EV_KEY, BTN_STYLUS, 1},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Releasing button
      {{0, 0}, EV_KEY, BTN_STYLUS, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Releasing touch
      {{0, 0}, EV_KEY, BTN_TOUCH, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},

      // Leaving hover
      {{0, 0}, EV_KEY, BTN_TOOL_PEN, 0},
      {{0, 0}, EV_SYN, SYN_REPORT, 0},
  };

  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  EXPECT_EQ(4u, size());

  auto down_event = dispatched_touch_event(0);
  EXPECT_EQ(ET_TOUCH_PRESSED, down_event.type);
  EXPECT_FALSE(down_event.flags & ui::EventFlags::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            down_event.pointer_details.pointer_type);

  auto button_down_event = dispatched_touch_event(1);
  EXPECT_EQ(ET_TOUCH_MOVED, button_down_event.type);
  EXPECT_TRUE(button_down_event.flags & ui::EventFlags::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            button_down_event.pointer_details.pointer_type);

  auto button_up_event = dispatched_touch_event(2);
  EXPECT_EQ(ET_TOUCH_MOVED, button_up_event.type);
  EXPECT_FALSE(button_up_event.flags & ui::EventFlags::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            button_up_event.pointer_details.pointer_type);

  auto up_event = dispatched_touch_event(3);
  EXPECT_EQ(ET_TOUCH_RELEASED, up_event.type);
  EXPECT_FALSE(down_event.flags & ui::EventFlags::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            up_event.pointer_details.pointer_type);
}

// crbug.com/771374
TEST_F(TouchEventConverterEvdevTest, FingerSizeWithResolution) {
  ui::MockTouchEventConverterEvdev* dev = device();

  EventDeviceInfo devinfo;
  EXPECT_TRUE(CapabilitiesToDeviceInfo(kEveTouchScreen, &devinfo));
  dev->Initialize(devinfo);

  // Captured from Pixelbook (Eve).
  timeval time;
  time = {1507226211, 483601};
  struct input_event mock_kernel_queue[] = {
      {time, EV_ABS, ABS_MT_TRACKING_ID, 461},
      {time, EV_ABS, ABS_MT_POSITION_X, 1795},
      {time, EV_ABS, ABS_MT_POSITION_Y, 5559},
      {time, EV_ABS, ABS_MT_PRESSURE, 217},
      {time, EV_ABS, ABS_MT_TOUCH_MAJOR, 14},
      {time, EV_ABS, ABS_MT_TOUCH_MINOR, 14},
      {time, EV_KEY, BTN_TOUCH, 1},
      {time, EV_ABS, ABS_X, 1795},
      {time, EV_ABS, ABS_Y, 5559},
      {time, EV_ABS, ABS_PRESSURE, 217},
      {time, EV_MSC, MSC_TIMESTAMP, 0},
      {time, EV_SYN, SYN_REPORT, 0},
  };
  // Set test now time to ensure above timestamps are in the past.
  SetTestNowTime(time);

  // Finger pressed with major/minor reported.
  dev->ConfigureReadMock(mock_kernel_queue, base::size(mock_kernel_queue), 0);
  dev->ReadNow();
  EXPECT_EQ(1u, size());
  ui::TouchEventParams event = dispatched_touch_event(0);
  EXPECT_EQ(ui::ET_TOUCH_PRESSED, event.type);
  EXPECT_EQ(ToTestTimeTicks(1507226211483601), event.timestamp);
  EXPECT_EQ(1795, event.location.x());
  EXPECT_EQ(5559, event.location.y());
  EXPECT_EQ(0, event.slot);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            event.pointer_details.pointer_type);
  EXPECT_FLOAT_EQ(280.f, event.pointer_details.radius_x);
  EXPECT_FLOAT_EQ(0.8509804f, event.pointer_details.force);
}
}  // namespace ui
