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

Side by Side 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 unified diff | Download patch
OLDNEW
(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/single_position_touch_noise_filter.h "
6
7 #include "base/logging.h"
8 #include "base/strings/stringprintf.h"
9
10 namespace ui {
11
12 namespace {
13
14 // Max squared distance between fingers for the fingers to be considered in the
15 // same position.
16 const int kSamePositionMaxDistance2 = 2 * 2;
17
18 // Max squared movement of a finger before it's no longer considered noise.
19 const int kNoiseMaxMovement2 = 2 * 2;
20
21 // Min duration in milliseconds after which touches in the same position are
22 // considered noise.
23 const int kMinDurationMs = 2000;
24
25 // Max duration in milliseconds to check for common positions with previous
26 // touches.
27 const int kMaxDurationMs = 4000;
28
29 // Returns the squared distance between (|x1|, |y1|) and (|x2|, |y2|)
30 int Distance2(int x1, int y1, int x2, int y2) {
31 int offset_x = x2 - x1;
32 int offset_y = y2 - y1;
33 return offset_x * offset_x + offset_y * offset_y;
34 }
35
36 } // namespace
37
38 SinglePositionTouchNoiseFilter::SinglePositionTouchNoiseFilter()
39 : tracked_touches_start_(0), tracked_touches_end_(0) {
40 for (size_t i = 0; i < kNumTouchEvdevSlots; ++i)
41 tracked_slots_[i] = kNumTrackedTouches;
42 }
43
44 void SinglePositionTouchNoiseFilter::Filter(
45 const std::vector<InProgressTouchEvdev>& touches,
46 base::TimeDelta time,
47 std::bitset<kNumTouchEvdevSlots>* slots_with_noise) {
48 // Forget old touches which will no longer be considered for overlap.
49 base::TimeDelta touch_cutoff =
50 time - base::TimeDelta::FromMilliseconds(kMaxDurationMs);
51 for (size_t i = tracked_touches_start_; i != tracked_touches_end_;
52 i = (i + 1) % kNumTrackedTouches) {
53 if (!tracked_touches_[i].valid)
54 continue;
55 if (tracked_touches_[i].end < touch_cutoff)
56 StopTrackingTouch(i);
57 }
58
59 for (const InProgressTouchEvdev& touch : touches) {
60 size_t slot = touch.slot;
61
62 bool arrived = touch.touching && !touch.was_touching;
63 bool departed = !touch.touching && touch.was_touching;
64 if (departed)
65 tracked_slots_[slot] = kNumTrackedTouches;
66 if (!touch.touching)
67 continue;
68
69 // Track all new touches until they move too far.
70 if (arrived)
71 TrackTouch(touch, time);
72
73 size_t t_ind = tracked_slots_[slot];
74 if (t_ind != kNumTrackedTouches) {
75 tracked_touches_[t_ind].end = time;
76 // Stop tracking if touch moves more than sqrt(kNoiseMaxMovement2).
77 if (Distance2(touch.x, touch.y, tracked_touches_[t_ind].x,
78 tracked_touches_[t_ind].y) > kNoiseMaxMovement2) {
79 StopTrackingTouch(t_ind);
80 } else {
81 // Determine duration over which touches have been occuring in this
82 // position.
83 base::TimeDelta max_duration;
84 for (size_t i = tracked_touches_start_; i != tracked_touches_end_;
85 i = (i + 1) % kNumTrackedTouches) {
86 TrackedTouch* tracked_touch = &tracked_touches_[i];
87 if (!tracked_touch->valid)
88 continue;
89 if (Distance2(touch.x, touch.y, tracked_touch->x, tracked_touch->y) <=
90 kSamePositionMaxDistance2) {
91 base::TimeDelta duration = time - tracked_touch->begin;
92 if (duration > max_duration)
93 max_duration = duration;
94 }
95 }
96
97 if (max_duration.InMilliseconds() > kMinDurationMs) {
98 VLOG(2) << base::StringPrintf(
99 "Cancel tracking id %d, in position occurring for %ldms",
100 touch.tracking_id, max_duration.InMilliseconds());
101 slots_with_noise->set(slot);
102 }
103 }
104 }
105 }
106 }
107
108 void SinglePositionTouchNoiseFilter::StopTrackingTouch(size_t index) {
109 size_t slot = tracked_touches_[index].slot;
110 if (tracked_slots_[slot] == index)
111 tracked_slots_[slot] = kNumTrackedTouches;
112 tracked_touches_[index].valid = false;
113
114 // If first touch is canceled, remove all dead touches.
115 if (index == tracked_touches_start_) {
116 while (!tracked_touches_[tracked_touches_start_].valid &&
117 tracked_touches_start_ != tracked_touches_end_) {
118 tracked_touches_start_ =
119 (tracked_touches_start_ + 1) % kNumTrackedTouches;
120 }
121 }
122 }
123
124 void SinglePositionTouchNoiseFilter::TrackTouch(
125 const InProgressTouchEvdev& touch,
126 base::TimeDelta time) {
127 size_t index = (tracked_touches_end_ + 1) % kNumTrackedTouches;
128 // If we would reach the start touch index, we cannot track any more touches.
129 if (index == tracked_touches_start_)
130 return;
131
132 tracked_touches_end_ = index;
133 tracked_touches_[index].valid = true;
134 tracked_touches_[index].slot = touch.slot;
135 tracked_touches_[index].x = touch.x;
136 tracked_touches_[index].y = touch.y;
137 tracked_touches_[index].begin = time;
138 tracked_touches_[index].end = time;
139 tracked_slots_[touch.slot] = index;
140 }
141
142 SinglePositionTouchNoiseFilter::SinglePositionTouchNoiseFilter::TrackedTouch::
143 TrackedTouch()
144 : valid(false), slot(0), x(0), y(0) {
145 }
146
147 SinglePositionTouchNoiseFilter::SinglePositionTouchNoiseFilter::TrackedTouch::
148 ~TrackedTouch() {
149 }
150
151 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698