Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: ui/events/ozone/evdev/touch_event_converter_evdev.cc

Issue 2263693003: Add palm suppression feature to EventConverterEvdev (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@stylus
Patch Set: added support for MT_TOOL_PALM to cancel events Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/ozone/evdev/touch_event_converter_evdev.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h" 5 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <linux/input.h> 9 #include <linux/input.h>
10 #include <poll.h> 10 #include <poll.h>
(...skipping 13 matching lines...) Expand all
24 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
25 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
26 #include "base/trace_event/trace_event.h" 26 #include "base/trace_event/trace_event.h"
27 #include "ui/events/devices/device_data_manager.h" 27 #include "ui/events/devices/device_data_manager.h"
28 #include "ui/events/devices/device_util_linux.h" 28 #include "ui/events/devices/device_util_linux.h"
29 #include "ui/events/event.h" 29 #include "ui/events/event.h"
30 #include "ui/events/event_constants.h" 30 #include "ui/events/event_constants.h"
31 #include "ui/events/event_switches.h" 31 #include "ui/events/event_switches.h"
32 #include "ui/events/event_utils.h" 32 #include "ui/events/event_utils.h"
33 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h" 33 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
34 #include "ui/events/ozone/evdev/palm_suppression_filter.h"
34 #include "ui/events/ozone/evdev/touch_evdev_types.h" 35 #include "ui/events/ozone/evdev/touch_evdev_types.h"
35 #include "ui/events/ozone/evdev/touch_noise/touch_noise_finder.h" 36 #include "ui/events/ozone/evdev/touch_noise/touch_noise_finder.h"
36 #include "ui/ozone/public/input_controller.h" 37 #include "ui/ozone/public/input_controller.h"
37 38
38 namespace { 39 namespace {
39 40
40 const int kMaxTrackingId = 0xffff; // TRKID_MAX in kernel. 41 const int kMaxTrackingId = 0xffff; // TRKID_MAX in kernel.
41 42
42 struct TouchCalibration { 43 struct TouchCalibration {
43 int bezel_left; 44 int bezel_left;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 int id, 107 int id,
107 const EventDeviceInfo& devinfo, 108 const EventDeviceInfo& devinfo,
108 DeviceEventDispatcherEvdev* dispatcher) 109 DeviceEventDispatcherEvdev* dispatcher)
109 : EventConverterEvdev(fd, 110 : EventConverterEvdev(fd,
110 path, 111 path,
111 id, 112 id,
112 devinfo.device_type(), 113 devinfo.device_type(),
113 devinfo.name(), 114 devinfo.name(),
114 devinfo.vendor_id(), 115 devinfo.vendor_id(),
115 devinfo.product_id()), 116 devinfo.product_id()),
116 dispatcher_(dispatcher) { 117 dispatcher_(dispatcher),
118 palm_filter_(nullptr) {
117 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 119 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kExtraTouchNoiseFiltering)) { 120 switches::kExtraTouchNoiseFiltering)) {
119 touch_noise_finder_.reset(new TouchNoiseFinder); 121 touch_noise_finder_.reset(new TouchNoiseFinder);
120 } 122 }
121 touch_evdev_debug_buffer_.Initialize(devinfo); 123 touch_evdev_debug_buffer_.Initialize(devinfo);
122 } 124 }
123 125
124 TouchEventConverterEvdev::~TouchEventConverterEvdev() { 126 TouchEventConverterEvdev::~TouchEventConverterEvdev() {
125 } 127 }
126 128
127 void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { 129 void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
128 has_mt_ = info.HasMultitouch(); 130 has_mt_ = info.HasMultitouch();
131 has_pen_ = info.HasKeyEvent(BTN_TOOL_PEN);
129 132
130 if (has_mt_) { 133 if (has_mt_) {
131 pressure_min_ = info.GetAbsMinimum(ABS_MT_PRESSURE); 134 pressure_min_ = info.GetAbsMinimum(ABS_MT_PRESSURE);
132 pressure_max_ = info.GetAbsMaximum(ABS_MT_PRESSURE); 135 pressure_max_ = info.GetAbsMaximum(ABS_MT_PRESSURE);
133 x_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_X); 136 x_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_X);
134 x_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_X) - x_min_tuxels_ + 1; 137 x_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_X) - x_min_tuxels_ + 1;
135 y_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_Y); 138 y_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_Y);
136 y_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_Y) - y_min_tuxels_ + 1; 139 y_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_Y) - y_min_tuxels_ + 1;
137 touch_points_ = 140 touch_points_ =
138 std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, kNumTouchEvdevSlots); 141 std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, kNumTouchEvdevSlots);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 events_[0].x = 0; 201 events_[0].x = 0;
199 events_[0].y = 0; 202 events_[0].y = 0;
200 events_[0].tracking_id = kTrackingIdForUnusedSlot; 203 events_[0].tracking_id = kTrackingIdForUnusedSlot;
201 events_[0].touching = false; 204 events_[0].touching = false;
202 events_[0].slot = 0; 205 events_[0].slot = 0;
203 events_[0].radius_x = 0; 206 events_[0].radius_x = 0;
204 events_[0].radius_y = 0; 207 events_[0].radius_y = 0;
205 events_[0].pressure = 0; 208 events_[0].pressure = 0;
206 events_[0].tool_code = 0; 209 events_[0].tool_code = 0;
207 } 210 }
211
212 if (palm_filter_)
213 palm_filter_->Reset();
208 } 214 }
209 215
210 void TouchEventConverterEvdev::Reinitialize() { 216 void TouchEventConverterEvdev::Reinitialize() {
211 ReleaseButtons(); 217 ReleaseButtons();
212 218
213 EventDeviceInfo info; 219 EventDeviceInfo info;
214 if (!info.Initialize(fd_, path_)) { 220 if (!info.Initialize(fd_, path_)) {
215 LOG(ERROR) << "Failed to synchronize state for touch device: " 221 LOG(ERROR) << "Failed to synchronize state for touch device: "
216 << path_.value(); 222 << path_.value();
217 Stop(); 223 Stop();
218 return; 224 return;
219 } 225 }
220 Initialize(info); 226 Initialize(info);
221 } 227 }
222 228
223 bool TouchEventConverterEvdev::HasTouchscreen() const { 229 bool TouchEventConverterEvdev::HasTouchscreen() const {
224 return true; 230 return true;
225 } 231 }
226 232
233 bool TouchEventConverterEvdev::HasPen() const {
234 return has_pen_;
235 }
236
227 gfx::Size TouchEventConverterEvdev::GetTouchscreenSize() const { 237 gfx::Size TouchEventConverterEvdev::GetTouchscreenSize() const {
228 return gfx::Size(x_num_tuxels_, y_num_tuxels_); 238 return gfx::Size(x_num_tuxels_, y_num_tuxels_);
229 } 239 }
230 240
231 int TouchEventConverterEvdev::GetTouchPoints() const { 241 int TouchEventConverterEvdev::GetTouchPoints() const {
232 return touch_points_; 242 return touch_points_;
233 } 243 }
234 244
235 void TouchEventConverterEvdev::OnEnabled() { 245 void TouchEventConverterEvdev::OnEnabled() {
236 ReportEvents(EventTimeForNow()); 246 ReportEvents(EventTimeForNow());
237 } 247 }
238 248
239 void TouchEventConverterEvdev::OnDisabled() { 249 void TouchEventConverterEvdev::OnDisabled() {
240 ReleaseTouches(); 250 ReleaseTouches();
241 ReleaseButtons(); 251 ReleaseButtons();
252 if (palm_filter_)
253 palm_filter_->Reset();
242 } 254 }
243 255
244 void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { 256 void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
245 TRACE_EVENT1("evdev", 257 TRACE_EVENT1("evdev",
246 "TouchEventConverterEvdev::OnFileCanReadWithoutBlocking", "fd", 258 "TouchEventConverterEvdev::OnFileCanReadWithoutBlocking", "fd",
247 fd); 259 fd);
248 260
249 input_event inputs[kNumTouchEvdevSlots * 6 + 1]; 261 input_event inputs[kNumTouchEvdevSlots * 6 + 1];
250 ssize_t read_size = read(fd, inputs, sizeof(inputs)); 262 ssize_t read_size = read(fd, inputs, sizeof(inputs));
251 if (read_size < 0) { 263 if (read_size < 0) {
(...skipping 22 matching lines...) Expand all
274 } 286 }
275 287
276 void TouchEventConverterEvdev::DumpTouchEventLog(const char* filename) { 288 void TouchEventConverterEvdev::DumpTouchEventLog(const char* filename) {
277 touch_evdev_debug_buffer_.DumpLog(filename); 289 touch_evdev_debug_buffer_.DumpLog(filename);
278 } 290 }
279 291
280 void TouchEventConverterEvdev::SetTouchEventLoggingEnabled(bool enabled) { 292 void TouchEventConverterEvdev::SetTouchEventLoggingEnabled(bool enabled) {
281 touch_logging_enabled_ = enabled; 293 touch_logging_enabled_ = enabled;
282 } 294 }
283 295
296 void TouchEventConverterEvdev::SetPalmSuppressionFilter(
297 PalmSuppressionFilter* palm_filter) {
298 palm_filter_ = palm_filter;
299 }
300
284 void TouchEventConverterEvdev::ProcessMultitouchEvent( 301 void TouchEventConverterEvdev::ProcessMultitouchEvent(
285 const input_event& input) { 302 const input_event& input) {
286 if (touch_logging_enabled_) 303 if (touch_logging_enabled_)
287 touch_evdev_debug_buffer_.ProcessEvent(current_slot_, &input); 304 touch_evdev_debug_buffer_.ProcessEvent(current_slot_, &input);
288 305
289 if (input.type == EV_SYN) { 306 if (input.type == EV_SYN) {
290 ProcessSyn(input); 307 ProcessSyn(input);
291 } else if (dropped_events_) { 308 } else if (dropped_events_) {
292 // Do nothing. This branch indicates we have lost sync with the driver. 309 // Do nothing. This branch indicates we have lost sync with the driver.
293 } else if (input.type == EV_ABS) { 310 } else if (input.type == EV_ABS) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 // Do not change tool types while touching to prevent inconsistencies 362 // Do not change tool types while touching to prevent inconsistencies
346 // from switching between Mouse and TouchEvents. 363 // from switching between Mouse and TouchEvents.
347 if (events_[current_slot_].was_touching) 364 if (events_[current_slot_].was_touching)
348 break; 365 break;
349 366
350 if (input.value > 0) { 367 if (input.value > 0) {
351 events_[current_slot_].tool_code = input.code; 368 events_[current_slot_].tool_code = input.code;
352 } else { 369 } else {
353 events_[current_slot_].tool_code = 0; 370 events_[current_slot_].tool_code = 0;
354 } 371 }
372 events_[current_slot_].altered = true;
355 break; 373 break;
356 default: 374 default:
357 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; 375 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code;
358 } 376 }
359 } 377 }
360 378
361 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) { 379 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) {
362 switch (input.code) { 380 switch (input.code) {
363 case ABS_MT_TOUCH_MAJOR: 381 case ABS_MT_TOUCH_MAJOR:
364 // TODO(spang): If we have all of major, minor, and orientation, 382 // TODO(spang): If we have all of major, minor, and orientation,
(...skipping 18 matching lines...) Expand all
383 break; 401 break;
384 case ABS_MT_SLOT: 402 case ABS_MT_SLOT:
385 if (input.value >= 0 && 403 if (input.value >= 0 &&
386 static_cast<size_t>(input.value) < events_.size()) { 404 static_cast<size_t>(input.value) < events_.size()) {
387 current_slot_ = input.value; 405 current_slot_ = input.value;
388 } else { 406 } else {
389 LOG(ERROR) << "invalid touch event index: " << input.value; 407 LOG(ERROR) << "invalid touch event index: " << input.value;
390 return; 408 return;
391 } 409 }
392 break; 410 break;
411 case ABS_MT_TOOL_TYPE:
412 if (input.value == MT_TOOL_PALM)
413 events_[current_slot_].is_palm = true;
393 default: 414 default:
394 DVLOG(5) << "unhandled code for EV_ABS: " << input.code; 415 DVLOG(5) << "unhandled code for EV_ABS: " << input.code;
395 return; 416 return;
396 } 417 }
397 events_[current_slot_].altered = true; 418 events_[current_slot_].altered = true;
398 } 419 }
399 420
400 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) { 421 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) {
401 switch (input.code) { 422 switch (input.code) {
402 case SYN_REPORT: 423 case SYN_REPORT:
403 ReportEvents(EventConverterEvdev::TimeTicksFromInputEvent(input)); 424 ReportEvents(EventConverterEvdev::TimeTicksFromInputEvent(input));
404 break; 425 break;
405 case SYN_DROPPED: 426 case SYN_DROPPED:
406 // Some buffer has overrun. We ignore all events up to and 427 // Some buffer has overrun. We ignore all events up to and
407 // including the next SYN_REPORT. 428 // including the next SYN_REPORT.
408 dropped_events_ = true; 429 dropped_events_ = true;
409 break; 430 break;
410 default: 431 default:
411 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code; 432 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code;
412 } 433 }
413 } 434 }
414 435
415 EventType TouchEventConverterEvdev::GetEventTypeForTouch( 436 EventType TouchEventConverterEvdev::GetEventTypeForTouch(
416 const InProgressTouchEvdev& touch) { 437 const InProgressTouchEvdev& touch) {
417 if (touch.cancelled) 438 if (touch.cancelled)
418 return ET_UNKNOWN; 439 return ET_UNKNOWN;
419 440
441 if (touch.is_palm)
442 return ET_TOUCH_CANCELLED;
443
420 if (touch_noise_finder_ && touch_noise_finder_->SlotHasNoise(touch.slot)) { 444 if (touch_noise_finder_ && touch_noise_finder_->SlotHasNoise(touch.slot)) {
421 if (touch.touching && !touch.was_touching) 445 if (touch.touching && !touch.was_touching)
spang 2016/08/22 20:52:13 Do we need this same check so that a new slot does
denniskempin 2016/08/23 22:28:12 Done.
422 return ET_UNKNOWN; 446 return ET_UNKNOWN;
423 return ET_TOUCH_CANCELLED; 447 return ET_TOUCH_CANCELLED;
424 } 448 }
425 449
426 if (touch.touching) 450 if (touch.touching)
427 return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED; 451 return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED;
428 return touch.was_touching ? ET_TOUCH_RELEASED : ET_UNKNOWN; 452 return touch.was_touching ? ET_TOUCH_RELEASED : ET_UNKNOWN;
429 } 453 }
430 454
431 void TouchEventConverterEvdev::ReportTouchEvent( 455 void TouchEventConverterEvdev::ReportTouchEvent(
432 const InProgressTouchEvdev& event, 456 const InProgressTouchEvdev& event,
433 EventType event_type, 457 EventType event_type,
434 base::TimeTicks timestamp) { 458 base::TimeTicks timestamp) {
435 dispatcher_->DispatchTouchEvent(TouchEventParams( 459 TouchEventParams params(input_device_.id, event.slot, event_type,
436 input_device_.id, event.slot, event_type, gfx::PointF(event.x, event.y), 460 gfx::PointF(event.x, event.y),
437 GetEventPointerDetails(event), timestamp)); 461 GetEventPointerDetails(event), timestamp);
462 if (!palm_filter_ || palm_filter_->FilterTouch(params))
463 dispatcher_->DispatchTouchEvent(params);
438 } 464 }
439 465
440 void TouchEventConverterEvdev::ReportStylusEvent( 466 void TouchEventConverterEvdev::ReportStylusEvent(
441 const InProgressTouchEvdev& event, 467 const InProgressTouchEvdev& event,
442 base::TimeTicks timestamp) { 468 base::TimeTicks timestamp) {
443 if (event.btn_left.changed) 469 if (event.btn_left.changed)
444 ReportButton(BTN_LEFT, event.btn_left.down, event, timestamp); 470 ReportButton(BTN_LEFT, event.btn_left.down, event, timestamp);
445 if (event.btn_right.changed) 471 if (event.btn_right.changed)
446 ReportButton(BTN_RIGHT, event.btn_right.down, event, timestamp); 472 ReportButton(BTN_RIGHT, event.btn_right.down, event, timestamp);
447 if (event.btn_middle.changed) 473 if (event.btn_middle.changed)
(...skipping 20 matching lines...) Expand all
468 } 494 }
469 495
470 if (touch_noise_finder_) 496 if (touch_noise_finder_)
471 touch_noise_finder_->HandleTouches(events_, timestamp); 497 touch_noise_finder_->HandleTouches(events_, timestamp);
472 498
473 for (size_t i = 0; i < events_.size(); i++) { 499 for (size_t i = 0; i < events_.size(); i++) {
474 InProgressTouchEvdev* event = &events_[i]; 500 InProgressTouchEvdev* event = &events_[i];
475 if (!event->altered) 501 if (!event->altered)
476 continue; 502 continue;
477 503
504 if (has_pen_ && palm_filter_) {
505 palm_filter_->EnableSuppression(event->tool_code > 0, timestamp);
506 }
507
478 if (event->tool_code > 0) { 508 if (event->tool_code > 0) {
479 ReportStylusEvent(*event, timestamp); 509 ReportStylusEvent(*event, timestamp);
480 } else { 510 } else {
481 EventType event_type = GetEventTypeForTouch(*event); 511 EventType event_type = GetEventTypeForTouch(*event);
482 if (event_type == ET_UNKNOWN || event_type == ET_TOUCH_CANCELLED) 512 if (event_type == ET_UNKNOWN || event_type == ET_TOUCH_CANCELLED)
483 event->cancelled = true; 513 event->cancelled = true;
484 514
485 if (event_type != ET_UNKNOWN) 515 if (event_type != ET_UNKNOWN)
486 ReportTouchEvent(*event, event_type, timestamp); 516 ReportTouchEvent(*event, event_type, timestamp);
487 } 517 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 if (pressure_max_ - pressure_min_) 571 if (pressure_max_ - pressure_min_)
542 pressure /= pressure_max_ - pressure_min_; 572 pressure /= pressure_max_ - pressure_min_;
543 return pressure; 573 return pressure;
544 } 574 }
545 575
546 int TouchEventConverterEvdev::NextTrackingId() { 576 int TouchEventConverterEvdev::NextTrackingId() {
547 return next_tracking_id_++ & kMaxTrackingId; 577 return next_tracking_id_++ & kMaxTrackingId;
548 } 578 }
549 579
550 } // namespace ui 580 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/touch_event_converter_evdev.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698