Chromium Code Reviews| Index: ui/events/ozone/evdev/touch_noise/far_apart_taps_touch_noise_filter.cc |
| diff --git a/ui/events/ozone/evdev/touch_noise/far_apart_taps_touch_noise_filter.cc b/ui/events/ozone/evdev/touch_noise/far_apart_taps_touch_noise_filter.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..93d49bcee51f35a7e62aeef0967b578536265651 |
| --- /dev/null |
| +++ b/ui/events/ozone/evdev/touch_noise/far_apart_taps_touch_noise_filter.cc |
| @@ -0,0 +1,93 @@ |
| +// 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/far_apart_taps_touch_noise_filter.h" |
| + |
| +#include <cmath> |
| + |
| +#include "base/logging.h" |
| +#include "base/strings/stringprintf.h" |
| + |
| +namespace ui { |
| + |
| +namespace { |
| + |
| +// Minimum squared distance between taps to be considered far apart. |
| +const int kMinDistance2 = 1500 * 1500; |
| + |
| +// Max time between taps considered. |
| +const int kMaxTapDeltaMs = 30; |
| + |
| +// Maximum squared movement of a touch to still be considered a tap. |
| +const int kMaxTapMovement2 = 20 * 20; |
| + |
| +// 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 |
| + |
| +void FarApartTapsTouchNoiseFilter::FilterFrame(Frame* previous, |
| + Frame* current) { |
| + // Remove old taps and touches moving more than min delta. |
| + base::TimeDelta tap_cutoff = |
| + current->timestamp - base::TimeDelta::FromMilliseconds(kMaxTapDeltaMs); |
| + for (size_t i = 0; i < kNumSlots; ++i) { |
| + if (tracked_taps_[i].start < tap_cutoff) |
| + tracked_taps_[i].Invalidate(); |
| + } |
| + |
| + for (size_t slot = 0; slot < kNumSlots; ++slot) { |
| + Finger* cur = ¤t->fingers[slot]; |
| + Finger* prev = &previous->fingers[slot]; |
| + |
| + // Only look at slots with active touches. |
| + if (cur->tracking_id == -1 && prev->tracking_id == -1) |
| + continue; |
| + |
| + bool arrived = prev->tracking_id == -1 && cur->tracking_id > 0; |
| + bool departing = prev->tracking_id >= 0 && cur->tracking_id == -1; |
| + |
| + if (arrived) { |
| + // Track new finger info. |
| + tracked_taps_[slot] = Tap(current->timestamp, cur->location); |
| + } else if (tracked_taps_[slot].is_valid()) { |
| + // Check if this finger has moved too far to be considered a tap. |
| + if (kMaxTapMovement2 < |
| + Distance2(cur->location, tracked_taps_[slot].location)) { |
| + tracked_taps_[slot].Invalidate(); |
| + } |
| + } |
| + |
| + if (tracked_taps_[slot].is_valid()) { |
| + // Check distance from other tracked taps. |
| + int min_distance2 = -1; |
| + for (size_t i = 0; i < kNumSlots; ++i) { |
| + if (i == slot || !tracked_taps_[i].is_valid()) |
| + continue; |
| + |
| + int dist2 = Distance2(tracked_taps_[i].location, cur->location); |
| + if (min_distance2 < 0 || dist2 < min_distance2) |
| + min_distance2 = dist2; |
| + } |
| + |
| + if (min_distance2 > kMinDistance2) { |
| + // The other finger should see this one on its next frame and also |
| + // get canceled. |
| + VLOG(2) << base::StringPrintf( |
| + "Cancel tracking id %d %.0fpx from other current taps.", |
| + departing ? prev->tracking_id : cur->tracking_id, |
| + sqrt(min_distance2)); |
| + cur->canceled = true; |
|
flackr
2015/03/10 05:23:40
Since we're in chrome codebase now, we should add
pkotwicz
2015/03/13 03:53:16
I'd rather do this in a separate CL. I have filed
flackr
2015/03/13 15:08:36
Of course, we may also want to track a histogram o
|
| + } |
| + } |
| + |
| + if (departing) |
| + tracked_taps_[slot].Invalidate(); |
| + } |
| +} |
| + |
| +} // namespace ui |