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

Unified Diff: ui/events/ozone/evdev/touch_noise/single_position_touch_noise_filter.cc

Issue 991533002: Port Chromium OS touch noise filtering to Chromium (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: ui/events/ozone/evdev/touch_noise/single_position_touch_noise_filter.cc
diff --git a/ui/events/ozone/evdev/touch_noise/single_position_touch_noise_filter.cc b/ui/events/ozone/evdev/touch_noise/single_position_touch_noise_filter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b5e14823e98ceff1eb9ef240e9485608e81bebd9
--- /dev/null
+++ b/ui/events/ozone/evdev/touch_noise/single_position_touch_noise_filter.cc
@@ -0,0 +1,144 @@
+// Copyright 2015 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_noise/single_position_touch_noise_filter.h"
+
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+
+namespace ui {
+
+namespace {
+
+// Max squared distance between fingers for the fingers to be considered in the
+// same position.
+const int kSamePositionMaxDistance2 = 2 * 2;
+
+// Max squared movement of a finger before it's no longer considered noise.
+const int kNoiseMaxMovement2 = 2 * 2;
+
+// Min duration in milliseconds after which touches in the same position are
+// considered noise.
+const int kMinDurationMs = 2000;
+
+// Max duration in milliseconds to check for common positions with previous
+// touches.
+const int kMaxDurationMs = 4000;
+
+// Returns the squared distance between |p1| and |p2|.
+int Distance2(const gfx::PointF& p1, const gfx::PointF& p2) {
+ gfx::Vector2dF offset = p2 - p1;
+ return offset.x() * offset.x() + offset.y() * offset.y();
+}
+
+} // namespace
+
+SinglePositionTouchNoiseFilter::SinglePositionTouchNoiseFilter()
+ : touches_start_(0), touches_end_(0) {
+ for (size_t i = 0; i < kNumSlots; i++)
+ tracked_slots_[i] = kNumTrackedTouches;
+}
+
+void SinglePositionTouchNoiseFilter::FilterFrame(Frame* previous,
+ Frame* current) {
+ // Forget old touches which will no longer be considered for overlap.
+ base::TimeDelta touch_cutoff =
+ current->timestamp - base::TimeDelta::FromMilliseconds(kMaxDurationMs);
+ for (size_t i = touches_start_; i != touches_end_;
+ i = (i + 1) % kNumTrackedTouches) {
+ if (!tracked_touches_[i].valid)
+ continue;
+ if (tracked_touches_[i].end < touch_cutoff)
+ StopTrackingTouch(i);
+ }
+
+ for (size_t slot = 0; slot < kNumSlots; ++slot) {
+ Finger* cur = &current->fingers[slot];
+ Finger* prev = &previous->fingers[slot];
+
+ bool arrived = prev->tracking_id == -1 && cur->tracking_id >= 0;
+ bool departed = prev->tracking_id >= 0 && cur->tracking_id == -1;
+ if (departed)
+ tracked_slots_[slot] = kNumTrackedTouches;
+ if (cur->tracking_id == -1)
+ continue;
+
+ // Track all new touches until they move too far.
+ if (arrived)
+ TrackTouch(slot, current);
+
+ size_t t_ind = tracked_slots_[slot];
+ if (t_ind != kNumTrackedTouches) {
+ tracked_touches_[t_ind].end = current->timestamp;
+ // Stop tracking if touch moves more than sqrt(kNoiseMaxMovement2).
+ if (Distance2(cur->location, tracked_touches_[t_ind].location) >
+ kNoiseMaxMovement2) {
+ StopTrackingTouch(t_ind);
+ } else {
+ // Determine duration over which touches have been occuring in this
+ // position.
+ base::TimeDelta max_duration;
+ for (size_t i = touches_start_; i != touches_end_;
+ i = (i + 1) % kNumTrackedTouches) {
+ Touch* touch = &tracked_touches_[i];
+ if (!touch->valid)
+ continue;
+ if (Distance2(cur->location, touch->location) <=
+ kSamePositionMaxDistance2) {
+ base::TimeDelta duration = current->timestamp - touch->begin;
+ if (duration > max_duration)
+ max_duration = duration;
+ }
+ }
+
+ if (max_duration.InMilliseconds() > kMinDurationMs) {
+ VLOG(2) << base::StringPrintf(
+ "Cancel tracking id %d, in position occurring for %ldms",
+ cur->tracking_id, max_duration.InMilliseconds());
+ cur->canceled = true;
+ }
+ }
+ }
+ }
+}
+
+void SinglePositionTouchNoiseFilter::StopTrackingTouch(size_t index) {
+ size_t slot = tracked_touches_[index].slot;
+ if (tracked_slots_[slot] == index)
+ tracked_slots_[slot] = kNumTrackedTouches;
+ tracked_touches_[index].valid = false;
+
+ // If first touch is canceled, remove all dead touches.
+ if (index == touches_start_) {
+ while (!tracked_touches_[touches_start_].valid &&
+ touches_start_ != touches_end_) {
+ touches_start_ = (touches_start_ + 1) % kNumTrackedTouches;
+ }
+ }
+}
+
+void SinglePositionTouchNoiseFilter::TrackTouch(size_t slot, Frame* frame) {
+ size_t index = (touches_end_ + 1) % kNumTrackedTouches;
+ // If we would reach the start touch index, we cannot track any more touches.
+ if (index == touches_start_)
+ return;
+
+ touches_end_ = index;
+ tracked_touches_[index].valid = true;
+ tracked_touches_[index].location = frame->fingers[slot].location;
+ tracked_touches_[index].begin = frame->timestamp;
+ tracked_touches_[index].end = frame->timestamp;
+ tracked_touches_[index].slot = slot;
+ tracked_slots_[slot] = index;
+}
+
+SinglePositionTouchNoiseFilter::SinglePositionTouchNoiseFilter::Touch::Touch()
+ : valid(false), slot(0) {
+}
+
+SinglePositionTouchNoiseFilter::SinglePositionTouchNoiseFilter::Touch::
+ ~Touch() {
+}
+
+} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698