summaryrefslogtreecommitdiffstats
path: root/ui/events
diff options
context:
space:
mode:
authorspang <spang@chromium.org>2015-06-23 10:57:08 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-23 17:58:53 +0000
commit0a07c2c4a195cacbda8ccf360e874c5270792941 (patch)
tree1a18273449b845d927e9a9f965fc43e70ad0bc1a /ui/events
parent8ed03e3b769dd2e2a366866012c67f9faac96d06 (diff)
downloadchromium_src-0a07c2c4a195cacbda8ccf360e874c5270792941.zip
chromium_src-0a07c2c4a195cacbda8ccf360e874c5270792941.tar.gz
chromium_src-0a07c2c4a195cacbda8ccf360e874c5270792941.tar.bz2
ozone: evdev: Enhance support for disabling devices
This adds a new state for device objects where we still read events from the kernel but we don't dispatch them to UI. It will be used for: (1) Disabling some devices based on policy decisions (such as internal touchpad in touchview mode based on hinge rotation). (2) Disabling all devices when we release control of the display. It is an extension of the previous "set_ignore_events" method. The difference is that we provide some hooks to clean up outstanding activity (presses) on disable and recover state properly on enable. It might be better to close the devices altogether, but there are a couple of reasons not do do that: (a) The model of attached devices would be updated. Disabling a device is not the same as removing it from the system, especially for (1) above. It's possible to fix this issue but doing so adds complexity. (b) We currently divide devices into a few classes based upon required processing and build different objects depending on the result. Closing and reopening a device races hotplug and would therefore require revisiting this classification and rebuilding the object. It seems better to do something lighter weight. Note that this will mean chrome will wakeup on input even when we release control of the display. It probably doesn't matter; having chrome running at all is quite costly and this feature is intended mainly to support a lightweight debug console (frecon). BUG=457077, 462743 TEST=events_unittests Review URL: https://codereview.chromium.org/1195123002 Cr-Commit-Position: refs/heads/master@{#335695}
Diffstat (limited to 'ui/events')
-rw-r--r--ui/events/ozone/evdev/event_converter_evdev.cc23
-rw-r--r--ui/events/ozone/evdev/event_converter_evdev.h19
-rw-r--r--ui/events/ozone/evdev/event_converter_evdev_impl.cc8
-rw-r--r--ui/events/ozone/evdev/event_converter_evdev_impl.h2
-rw-r--r--ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc28
-rw-r--r--ui/events/ozone/evdev/input_device_factory_evdev.cc6
-rw-r--r--ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc7
-rw-r--r--ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h2
-rw-r--r--ui/events/ozone/evdev/tablet_event_converter_evdev.cc4
-rw-r--r--ui/events/ozone/evdev/tablet_event_converter_evdev.h3
-rw-r--r--ui/events/ozone/evdev/touch_event_converter_evdev.cc45
-rw-r--r--ui/events/ozone/evdev/touch_event_converter_evdev.h9
-rw-r--r--ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc77
13 files changed, 183 insertions, 50 deletions
diff --git a/ui/events/ozone/evdev/event_converter_evdev.cc b/ui/events/ozone/evdev/event_converter_evdev.cc
index ff7bbc0..d3660f0 100644
--- a/ui/events/ozone/evdev/event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/event_converter_evdev.cc
@@ -26,23 +26,42 @@ EventConverterEvdev::EventConverterEvdev(int fd,
}
EventConverterEvdev::~EventConverterEvdev() {
- Stop();
+ DCHECK(!enabled_);
+ DCHECK(!watching_);
+ if (fd_ >= 0)
+ close(fd_);
}
void EventConverterEvdev::Start() {
base::MessageLoopForUI::current()->WatchFileDescriptor(
fd_, true, base::MessagePumpLibevent::WATCH_READ, &controller_, this);
+ watching_ = true;
}
void EventConverterEvdev::Stop() {
controller_.StopWatchingFileDescriptor();
+ watching_ = false;
+}
- OnStopped();
+void EventConverterEvdev::SetEnabled(bool enabled) {
+ if (enabled == enabled_)
+ return;
+ if (enabled)
+ OnEnabled();
+ else
+ OnDisabled();
+ enabled_ = enabled;
}
void EventConverterEvdev::OnStopped() {
}
+void EventConverterEvdev::OnEnabled() {
+}
+
+void EventConverterEvdev::OnDisabled() {
+}
+
void EventConverterEvdev::OnFileCanWriteWithoutBlocking(int fd) {
NOTREACHED();
}
diff --git a/ui/events/ozone/evdev/event_converter_evdev.h b/ui/events/ozone/evdev/event_converter_evdev.h
index d4180f2..4f00a7f 100644
--- a/ui/events/ozone/evdev/event_converter_evdev.h
+++ b/ui/events/ozone/evdev/event_converter_evdev.h
@@ -40,17 +40,25 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev
const InputDevice& input_device() const { return input_device_; }
- void set_ignore_events(bool ignore_events) { ignore_events_ = ignore_events; }
-
// Start reading events.
void Start();
// Stop reading events.
void Stop();
+ // Enable or disable this device. A disabled device still polls for
+ // input and can update state but must not dispatch any events to UI.
+ void SetEnabled(bool enabled);
+
// Cleanup after we stop reading events (release buttons, etc).
virtual void OnStopped();
+ // Prepare for disable (e.g. should release keys/buttons/touches).
+ virtual void OnDisabled();
+
+ // Start or restart (e.g. should reapply keys/buttons/touches).
+ virtual void OnEnabled();
+
// Returns true if the converter is used for a keyboard device.
virtual bool HasKeyboard() const;
@@ -99,8 +107,11 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev
// event converter) and type.
InputDevice input_device_;
- // Whether events from the device should be ignored.
- bool ignore_events_ = false;
+ // Whether we're polling for input on the device.
+ bool watching_ = false;
+
+ // Whether events should be dispatched to UI.
+ bool enabled_ = false;
// Controller for watching the input fd.
base::MessagePumpLibevent::FileDescriptorWatcher controller_;
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl.cc b/ui/events/ozone/evdev/event_converter_evdev_impl.cc
index 6fb020de..0c532d5 100644
--- a/ui/events/ozone/evdev/event_converter_evdev_impl.cc
+++ b/ui/events/ozone/evdev/event_converter_evdev_impl.cc
@@ -47,7 +47,7 @@ EventConverterEvdevImpl::EventConverterEvdevImpl(
}
EventConverterEvdevImpl::~EventConverterEvdevImpl() {
- Stop();
+ DCHECK(!enabled_);
close(fd_);
}
@@ -66,9 +66,7 @@ void EventConverterEvdevImpl::OnFileCanReadWithoutBlocking(int fd) {
return;
}
- // TODO(spang): Re-implement this by releasing buttons & temporarily closing
- // the device.
- if (ignore_events_)
+ if (!enabled_)
return;
DCHECK_EQ(read_size % sizeof(*inputs), 0u);
@@ -109,7 +107,7 @@ void EventConverterEvdevImpl::SetKeyFilter(bool enable_filter,
}
}
-void EventConverterEvdevImpl::OnStopped() {
+void EventConverterEvdevImpl::OnDisabled() {
ReleaseKeys();
ReleaseMouseButtons();
}
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl.h b/ui/events/ozone/evdev/event_converter_evdev_impl.h
index 099c380..40e0694 100644
--- a/ui/events/ozone/evdev/event_converter_evdev_impl.h
+++ b/ui/events/ozone/evdev/event_converter_evdev_impl.h
@@ -44,7 +44,7 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdevImpl
bool HasCapsLockLed() const override;
void SetKeyFilter(bool enable_filter,
std::vector<DomCode> allowed_keys) override;
- void OnStopped() override;
+ void OnDisabled() override;
void ProcessEvents(const struct input_event* inputs, int count);
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc b/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc
index bbe2cb6..f1468fe 100644
--- a/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc
+++ b/ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc
@@ -36,9 +36,9 @@ class MockEventConverterEvdevImpl : public EventConverterEvdevImpl {
EventDeviceInfo(),
cursor,
dispatcher) {
- Start();
+ SetEnabled(true);
}
- ~MockEventConverterEvdevImpl() override {}
+ ~MockEventConverterEvdevImpl() override { SetEnabled(false); }
// EventConverterEvdevImpl:
bool HasKeyboard() const override { return true; }
@@ -541,6 +541,30 @@ TEST_F(EventConverterEvdevImplTest, ShouldReleaseKeysOnSynDropped) {
EXPECT_EQ(ui::VKEY_A, event->key_code());
}
+TEST_F(EventConverterEvdevImplTest, ShouldReleaseKeysOnDisable) {
+ ui::MockEventConverterEvdevImpl* dev = device();
+
+ struct input_event mock_kernel_queue[] = {
+ {{0, 0}, EV_KEY, KEY_A, 1},
+ {{0, 0}, EV_SYN, SYN_REPORT, 0},
+ };
+
+ dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
+ EXPECT_EQ(1u, size());
+
+ dev->SetEnabled(false);
+ EXPECT_EQ(2u, size());
+
+ ui::KeyEvent* event = dispatched_event(0);
+ EXPECT_EQ(ui::ET_KEY_PRESSED, event->type());
+ EXPECT_EQ(ui::VKEY_A, event->key_code());
+
+ event = dispatched_event(1);
+ EXPECT_EQ(ui::ET_KEY_RELEASED, event->type());
+ EXPECT_EQ(ui::VKEY_A, event->key_code());
+}
+
+
// Test that SetAllowedKeys() causes events for non-allowed keys to be dropped.
TEST_F(EventConverterEvdevImplTest, SetAllowedKeys) {
ui::MockEventConverterEvdevImpl* dev = device();
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc
index 1ff24fa..56f9dd5 100644
--- a/ui/events/ozone/evdev/input_device_factory_evdev.cc
+++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -262,6 +262,9 @@ void InputDeviceFactoryEvdev::DetachInputDevice(const base::FilePath& path) {
converters_.erase(path);
if (converter) {
+ // Disable the device (to release keys/buttons/etc).
+ converter->SetEnabled(false);
+
// Cancel libevent notifications from this converter. This part must be
// on UI since the polling happens on UI.
converter->Stop();
@@ -276,7 +279,6 @@ void InputDeviceFactoryEvdev::DetachInputDevice(const base::FilePath& path) {
}
}
-
void InputDeviceFactoryEvdev::SetCapsLockLed(bool enabled) {
caps_lock_led_enabled_ = enabled;
ApplyCapsLockLed();
@@ -340,7 +342,7 @@ void InputDeviceFactoryEvdev::ApplyInputDeviceSettings() {
for (const auto& it : converters_) {
EventConverterEvdev* converter = it.second;
- converter->set_ignore_events(!IsDeviceEnabled(converter));
+ converter->SetEnabled(IsDeviceEnabled(converter));
if (converter->type() == InputDeviceType::INPUT_DEVICE_INTERNAL &&
converter->HasKeyboard()) {
diff --git a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc
index 76c4f94..b32bef05 100644
--- a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc
+++ b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc
@@ -64,8 +64,9 @@ EventReaderLibevdevCros::EventReaderLibevdevCros(int fd,
}
EventReaderLibevdevCros::~EventReaderLibevdevCros() {
- Stop();
+ DCHECK(!watching_);
EvdevClose(&evdev_);
+ fd_ = -1;
}
EventReaderLibevdevCros::Delegate::~Delegate() {}
@@ -100,7 +101,7 @@ bool EventReaderLibevdevCros::HasCapsLockLed() const {
return has_caps_lock_led_;
}
-void EventReaderLibevdevCros::OnStopped() {
+void EventReaderLibevdevCros::OnDisabled() {
delegate_->OnLibEvdevCrosStopped(&evdev_, &evstate_);
}
@@ -109,7 +110,7 @@ void EventReaderLibevdevCros::OnSynReport(void* data,
EventStateRec* evstate,
struct timeval* tv) {
EventReaderLibevdevCros* reader = static_cast<EventReaderLibevdevCros*>(data);
- if (reader->ignore_events_)
+ if (!reader->enabled_)
return;
reader->delegate_->OnLibEvdevCrosEvent(&reader->evdev_, evstate, *tv);
diff --git a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h
index e086901..6ce301e 100644
--- a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h
+++ b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h
@@ -53,7 +53,7 @@ class EventReaderLibevdevCros : public EventConverterEvdev {
bool HasMouse() const override;
bool HasTouchpad() const override;
bool HasCapsLockLed() const override;
- void OnStopped() override;
+ void OnDisabled() override;
private:
static void OnSynReport(void* data,
diff --git a/ui/events/ozone/evdev/tablet_event_converter_evdev.cc b/ui/events/ozone/evdev/tablet_event_converter_evdev.cc
index 3d7248c..8949309 100644
--- a/ui/events/ozone/evdev/tablet_event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/tablet_event_converter_evdev.cc
@@ -38,8 +38,6 @@ TabletEventConverterEvdev::TabletEventConverterEvdev(
}
TabletEventConverterEvdev::~TabletEventConverterEvdev() {
- Stop();
- close(fd_);
}
void TabletEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
@@ -58,7 +56,7 @@ void TabletEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
return;
}
- if (ignore_events_)
+ if (!enabled_)
return;
DCHECK_EQ(read_size % sizeof(*inputs), 0u);
diff --git a/ui/events/ozone/evdev/tablet_event_converter_evdev.h b/ui/events/ozone/evdev/tablet_event_converter_evdev.h
index 0136a2f..502a399 100644
--- a/ui/events/ozone/evdev/tablet_event_converter_evdev.h
+++ b/ui/events/ozone/evdev/tablet_event_converter_evdev.h
@@ -70,6 +70,9 @@ class EVENTS_OZONE_EVDEV_EXPORT TabletEventConverterEvdev
// Whether we need to move the cursor
bool abs_value_dirty_ = false;
+ // Set if we drop events in kernel (SYN_DROPPED) or in process.
+ bool dropped_events_ = false;
+
DISALLOW_COPY_AND_ASSIGN(TabletEventConverterEvdev);
};
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
index eaa693a..0c9be25 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -104,8 +104,6 @@ TouchEventConverterEvdev::TouchEventConverterEvdev(
}
TouchEventConverterEvdev::~TouchEventConverterEvdev() {
- Stop();
- close(fd_);
}
void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
@@ -188,13 +186,16 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
}
}
-bool TouchEventConverterEvdev::Reinitialize() {
+void TouchEventConverterEvdev::Reinitialize() {
EventDeviceInfo info;
- if (info.Initialize(fd_)) {
- Initialize(info);
- return true;
+ if (!info.Initialize(fd_)) {
+ LOG(ERROR) << "Failed to synchronize state for touch device: "
+ << path_.value();
+ Stop();
+ return;
}
- return false;
+
+ Initialize(info);
}
bool TouchEventConverterEvdev::HasTouchscreen() const {
@@ -209,7 +210,11 @@ int TouchEventConverterEvdev::GetTouchPoints() const {
return touch_points_;
}
-void TouchEventConverterEvdev::OnStopped() {
+void TouchEventConverterEvdev::OnEnabled() {
+ ReportEvents(EventTimeForNow());
+}
+
+void TouchEventConverterEvdev::OnDisabled() {
ReleaseTouches();
}
@@ -229,8 +234,10 @@ void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
return;
}
- if (ignore_events_)
+ if (!enabled_) {
+ dropped_events_ = true;
return;
+ }
for (unsigned i = 0; i < read_size / sizeof(*inputs); i++) {
if (!has_mt_) {
@@ -247,7 +254,7 @@ void TouchEventConverterEvdev::ProcessMultitouchEvent(
const input_event& input) {
if (input.type == EV_SYN) {
ProcessSyn(input);
- } else if (syn_dropped_) {
+ } else if (dropped_events_) {
// Do nothing. This branch indicates we have lost sync with the driver.
} else if (input.type == EV_ABS) {
if (events_.size() <= current_slot_) {
@@ -337,21 +344,12 @@ void TouchEventConverterEvdev::ProcessAbs(const input_event& input) {
void TouchEventConverterEvdev::ProcessSyn(const input_event& input) {
switch (input.code) {
case SYN_REPORT:
- if (syn_dropped_) {
- // Have to re-initialize.
- if (Reinitialize()) {
- syn_dropped_ = false;
- } else {
- LOG(ERROR) << "failed to re-initialize device info";
- }
- } else {
- ReportEvents(EventConverterEvdev::TimeDeltaFromInputEvent(input));
- }
+ ReportEvents(EventConverterEvdev::TimeDeltaFromInputEvent(input));
break;
case SYN_DROPPED:
// Some buffer has overrun. We ignore all events up to and
// including the next SYN_REPORT.
- syn_dropped_ = true;
+ dropped_events_ = true;
break;
default:
NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code;
@@ -384,6 +382,11 @@ void TouchEventConverterEvdev::ReportEvent(const InProgressTouchEvdev& event,
}
void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) {
+ if (dropped_events_) {
+ Reinitialize();
+ dropped_events_ = false;
+ }
+
if (touch_noise_finder_)
touch_noise_finder_->HandleTouches(events_, delta);
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h
index 99ce460..80938be 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.h
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -38,7 +38,8 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev
bool HasTouchscreen() const override;
gfx::Size GetTouchscreenSize() const override;
int GetTouchPoints() const override;
- void OnStopped() override;
+ void OnEnabled() override;
+ void OnDisabled() override;
// Unsafe part of initialization.
virtual void Initialize(const EventDeviceInfo& info);
@@ -49,7 +50,7 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev
// Overidden from base::MessagePumpLibevent::Watcher.
void OnFileCanReadWithoutBlocking(int fd) override;
- virtual bool Reinitialize();
+ virtual void Reinitialize();
void ProcessMultitouchEvent(const input_event& input);
void EmulateMultitouchEvent(const input_event& input);
@@ -77,8 +78,8 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev
// Dispatcher for events.
DeviceEventDispatcherEvdev* dispatcher_;
- // Set if we have seen a SYN_DROPPED and not yet re-synced with the device.
- bool syn_dropped_ = false;
+ // Set if we drop events in kernel (SYN_DROPPED) or in process.
+ bool dropped_events_ = false;
// Device has multitouch capability.
bool has_mt_ = false;
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
index 70ccc7f..da6958f 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -61,7 +61,7 @@ class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
base::FilePath path,
const EventDeviceInfo& devinfo,
DeviceEventDispatcherEvdev* dispatcher);
- ~MockTouchEventConverterEvdev() override {}
+ ~MockTouchEventConverterEvdev() override;
void ConfigureReadMock(struct input_event* queue,
long read_this_many,
@@ -73,7 +73,11 @@ class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
base::RunLoop().RunUntilIdle();
}
- bool Reinitialize() override { return true; }
+ void SimulateReinitialize(const EventDeviceInfo& devinfo) {
+ Initialize(devinfo);
+ }
+
+ void Reinitialize() override {}
TouchNoiseFinder* touch_noise_finder() { return touch_noise_finder_.get(); }
@@ -141,6 +145,12 @@ MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
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,
@@ -548,6 +558,69 @@ TEST_F(TouchEventConverterEvdevTest, ShouldReleaseContactsOnStop) {
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();