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 |