OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/events/ozone/evdev/touch_noise/far_apart_taps_touch_noise_filter.h" |
| 6 |
| 7 #include <cmath> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "base/strings/stringprintf.h" |
| 11 |
| 12 namespace ui { |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Minimum squared distance between taps to be considered far apart. |
| 17 const int kMinDistance2 = 1500 * 1500; |
| 18 |
| 19 // Max time between taps considered. |
| 20 const int kMaxTapDeltaMs = 30; |
| 21 |
| 22 // Maximum squared movement of a touch to still be considered a tap. |
| 23 const int kMaxTapMovement2 = 20 * 20; |
| 24 |
| 25 // Returns the squared distance between (|x1|, |y1|) and (|x2|, |y2|). |
| 26 int Distance2(int x1, int y1, int x2, int y2) { |
| 27 int offset_x = x2 - x1; |
| 28 int offset_y = y2 - y1; |
| 29 return offset_x * offset_x + offset_y * offset_y; |
| 30 } |
| 31 |
| 32 } // namespace |
| 33 |
| 34 void FarApartTapsTouchNoiseFilter::Filter( |
| 35 const std::vector<InProgressTouchEvdev>& touches, |
| 36 base::TimeDelta time, |
| 37 std::bitset<kNumTouchEvdevSlots>* slots_with_noise) { |
| 38 // Remove old taps. |
| 39 base::TimeDelta tap_cutoff = |
| 40 time - base::TimeDelta::FromMilliseconds(kMaxTapDeltaMs); |
| 41 for (size_t i = 0; i < arraysize(tracked_taps_); ++i) { |
| 42 if (tracked_taps_[i].start < tap_cutoff) |
| 43 tracked_taps_[i].Invalidate(); |
| 44 } |
| 45 |
| 46 for (const InProgressTouchEvdev& touch : touches) { |
| 47 // Only look at slots with active touches. |
| 48 if (!touch.touching && !touch.was_touching) |
| 49 continue; |
| 50 |
| 51 size_t slot = touch.slot; |
| 52 if (!touch.was_touching) { |
| 53 // Track new finger info. |
| 54 tracked_taps_[slot] = Tap(time, touch.x, touch.y); |
| 55 } else if (tracked_taps_[slot].is_valid()) { |
| 56 // Check if this finger has moved too far to be considered a tap. |
| 57 if (kMaxTapMovement2 < Distance2(touch.x, touch.y, tracked_taps_[slot].x, |
| 58 tracked_taps_[slot].y)) { |
| 59 tracked_taps_[slot].Invalidate(); |
| 60 } |
| 61 } |
| 62 |
| 63 if (tracked_taps_[slot].is_valid()) { |
| 64 // Check distance from other tracked taps. |
| 65 int min_distance2 = -1; |
| 66 for (size_t i = 0; i < arraysize(tracked_taps_); ++i) { |
| 67 if (i == slot || !tracked_taps_[i].is_valid()) |
| 68 continue; |
| 69 |
| 70 int dist2 = |
| 71 Distance2(tracked_taps_[i].x, tracked_taps_[i].y, touch.x, touch.y); |
| 72 if (min_distance2 < 0 || dist2 < min_distance2) |
| 73 min_distance2 = dist2; |
| 74 } |
| 75 |
| 76 if (min_distance2 > kMinDistance2) { |
| 77 // The other finger should see this one on its next frame and also |
| 78 // get canceled. |
| 79 VLOG(2) << base::StringPrintf( |
| 80 "Cancel tracking id %d %.0fpx from other current taps.", |
| 81 touch.tracking_id, sqrt(min_distance2)); |
| 82 slots_with_noise->set(slot); |
| 83 } |
| 84 } |
| 85 |
| 86 if (!touch.touching) |
| 87 tracked_taps_[slot].Invalidate(); |
| 88 } |
| 89 } |
| 90 |
| 91 } // namespace ui |
OLD | NEW |