|
| 1 | +From c4adbc9eadd04909e5275cfdd22c4b87dd9f1f9d Mon Sep 17 00:00:00 2001 |
| 2 | +From: yibo <yibo@fydeos.io> |
| 3 | +Date: Tue, 23 Sep 2025 15:57:29 +0800 |
| 4 | +Subject: [PATCH] add distance filter to gestures fix touchpad warp issue |
| 5 | + |
| 6 | +Change-Id: I8de6a0d86b207601022ece3271bddc3084a5dd25 |
| 7 | +--- |
| 8 | + Android.bp | 1 + |
| 9 | + Makefile | 1 + |
| 10 | + include/distance_filter_interpreter.h | 51 +++++++++++++++++++ |
| 11 | + src/distance_filter_interpreter.cc | 70 +++++++++++++++++++++++++++ |
| 12 | + src/gestures.cc | 3 ++ |
| 13 | + 5 files changed, 126 insertions(+) |
| 14 | + create mode 100644 include/distance_filter_interpreter.h |
| 15 | + create mode 100644 src/distance_filter_interpreter.cc |
| 16 | + |
| 17 | +diff --git a/Android.bp b/Android.bp |
| 18 | +index 082af5b..52ad66b 100644 |
| 19 | +--- a/Android.bp |
| 20 | ++++ b/Android.bp |
| 21 | +@@ -89,6 +89,7 @@ cc_library_static { |
| 22 | + "src/activity_log.cc", |
| 23 | + "src/box_filter_interpreter.cc", |
| 24 | + "src/click_wiggle_filter_interpreter.cc", |
| 25 | ++ "src/distance_filter_interpreter.cc", |
| 26 | + "src/file_util.cc", |
| 27 | + "src/filter_interpreter.cc", |
| 28 | + "src/finger_merge_filter_interpreter.cc", |
| 29 | +diff --git a/Makefile b/Makefile |
| 30 | +index 65eccc7..b606b43 100644 |
| 31 | +--- a/Makefile |
| 32 | ++++ b/Makefile |
| 33 | +@@ -11,6 +11,7 @@ SO_OBJECTS=\ |
| 34 | + $(OBJDIR)/activity_log.o \ |
| 35 | + $(OBJDIR)/box_filter_interpreter.o \ |
| 36 | + $(OBJDIR)/click_wiggle_filter_interpreter.o \ |
| 37 | ++ $(OBJDIR)/distance_filter_interpreter.o \ |
| 38 | + $(OBJDIR)/file_util.o \ |
| 39 | + $(OBJDIR)/filter_interpreter.o \ |
| 40 | + $(OBJDIR)/finger_merge_filter_interpreter.o \ |
| 41 | +diff --git a/include/distance_filter_interpreter.h b/include/distance_filter_interpreter.h |
| 42 | +new file mode 100644 |
| 43 | +index 0000000..7661584 |
| 44 | +--- /dev/null |
| 45 | ++++ b/include/distance_filter_interpreter.h |
| 46 | +@@ -0,0 +1,51 @@ |
| 47 | ++// Copyright 2012 The ChromiumOS Authors |
| 48 | ++// Use of this source code is governed by a BSD-style license that can be |
| 49 | ++// found in the LICENSE file. |
| 50 | ++ |
| 51 | ++#include <map> |
| 52 | ++ |
| 53 | ++#include <gtest/gtest.h> // For FRIEND_TEST |
| 54 | ++ |
| 55 | ++#include "include/filter_interpreter.h" |
| 56 | ++#include "include/finger_metrics.h" |
| 57 | ++#include "include/gestures.h" |
| 58 | ++#include "include/prop_registry.h" |
| 59 | ++#include "include/tracer.h" |
| 60 | ++ |
| 61 | ++#ifndef GESTURES_DISTANCE_FILTER_INTERPRETER_H_ |
| 62 | ++#define GESTURES_DISTANCE_FILTER_INTERPRETER_H_ |
| 63 | ++ |
| 64 | ++namespace gestures { |
| 65 | ++ |
| 66 | ++// This filter interpreter suppresses fingers that move too far between frames. |
| 67 | ++// This provides simple distance-based suppression to catch obvious sensor |
| 68 | ++// errors and large jumps. |
| 69 | ++ |
| 70 | ++class DistanceFilterInterpreter : public FilterInterpreter, |
| 71 | ++ public PropertyDelegate { |
| 72 | ++ FRIEND_TEST(DistanceFilterInterpreterTest, SimpleTest); |
| 73 | ++ public: |
| 74 | ++ // Takes ownership of |next|: |
| 75 | ++ DistanceFilterInterpreter(PropRegistry* prop_reg, Interpreter* next, |
| 76 | ++ Tracer* tracer); |
| 77 | ++ virtual ~DistanceFilterInterpreter() {} |
| 78 | ++ |
| 79 | ++ protected: |
| 80 | ++ virtual void SyncInterpretImpl(HardwareState& hwstate, stime_t* timeout); |
| 81 | ++ |
| 82 | ++ private: |
| 83 | ++ // Fingers from the previous SyncInterpret call |
| 84 | ++ std::map<short, FingerState> previous_input_; |
| 85 | ++ |
| 86 | ++ // Whether or not this filter is enabled. If disabled, it behaves as a |
| 87 | ++ // simple passthrough. |
| 88 | ++ BoolProperty enabled_; |
| 89 | ++ |
| 90 | ++ // Maximum distance a finger can move between frames before being flagged |
| 91 | ++ // as a teleportation warp. This provides simple distance-based suppression. |
| 92 | ++ DoubleProperty max_frame_distance_; |
| 93 | ++}; |
| 94 | ++ |
| 95 | ++} // namespace gestures |
| 96 | ++ |
| 97 | ++#endif // GESTURES_DISTANCE_FILTER_INTERPRETER_H_ |
| 98 | +\ No newline at end of file |
| 99 | +diff --git a/src/distance_filter_interpreter.cc b/src/distance_filter_interpreter.cc |
| 100 | +new file mode 100644 |
| 101 | +index 0000000..3c94b58 |
| 102 | +--- /dev/null |
| 103 | ++++ b/src/distance_filter_interpreter.cc |
| 104 | +@@ -0,0 +1,70 @@ |
| 105 | ++// Copyright 2012 The ChromiumOS Authors |
| 106 | ++// Use of this source code is governed by a BSD-style license that can be |
| 107 | ++// found in the LICENSE file. |
| 108 | ++ |
| 109 | ++#include "include/distance_filter_interpreter.h" |
| 110 | ++ |
| 111 | ++#include "include/tracer.h" |
| 112 | ++#include "include/util.h" |
| 113 | ++ |
| 114 | ++namespace gestures { |
| 115 | ++ |
| 116 | ++DistanceFilterInterpreter::DistanceFilterInterpreter(PropRegistry* prop_reg, |
| 117 | ++ Interpreter* next, |
| 118 | ++ Tracer* tracer) |
| 119 | ++ : FilterInterpreter(nullptr, next, tracer, false), |
| 120 | ++ enabled_(prop_reg, "Distance Filter Enable", false), |
| 121 | ++ max_frame_distance_(prop_reg, "Distance Filter Max Frame Distance", 5.0) { |
| 122 | ++ InitName(); |
| 123 | ++} |
| 124 | ++ |
| 125 | ++void DistanceFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate, |
| 126 | ++ stime_t* timeout) { |
| 127 | ++ const char name[] = "DistanceFilterInterpreter::SyncInterpretImpl"; |
| 128 | ++ LogHardwareStatePre(name, hwstate); |
| 129 | ++ |
| 130 | ++ if (!enabled_.val_) { |
| 131 | ++ next_->SyncInterpret(hwstate, timeout); |
| 132 | ++ return; |
| 133 | ++ } |
| 134 | ++ |
| 135 | ++ RemoveMissingIdsFromMap(&previous_input_, hwstate); |
| 136 | ++ |
| 137 | ++ for (size_t i = 0; i < hwstate.finger_cnt; i++) { |
| 138 | ++ short tracking_id = hwstate.fingers[i].tracking_id; |
| 139 | ++ |
| 140 | ++ // Check if we have previous frame data for this finger |
| 141 | ++ if (MapContainsKey(previous_input_, tracking_id)) { |
| 142 | ++ const FingerState& current_fs = hwstate.fingers[i]; |
| 143 | ++ const FingerState& prev_fs = previous_input_[tracking_id]; |
| 144 | ++ |
| 145 | ++ float dx = current_fs.position_x - prev_fs.position_x; |
| 146 | ++ float dy = current_fs.position_y - prev_fs.position_y; |
| 147 | ++ float distance = sqrtf(dx * dx + dy * dy); |
| 148 | ++ |
| 149 | ++ if (distance > max_frame_distance_.val_) { |
| 150 | ++ unsigned old_flags = hwstate.fingers[i].flags; |
| 151 | ++ |
| 152 | ++ hwstate.fingers[i].flags |= (GESTURES_FINGER_WARP_X_MOVE | |
| 153 | ++ GESTURES_FINGER_WARP_Y_MOVE | |
| 154 | ++ GESTURES_FINGER_WARP_X_NON_MOVE | |
| 155 | ++ GESTURES_FINGER_WARP_Y_NON_MOVE | |
| 156 | ++ GESTURES_FINGER_WARP_TELEPORTATION); |
| 157 | ++ |
| 158 | ++ Log("DISTANCE_SUPPRESS: finger_id=%d, distance=%.3f > max=%.3f, " |
| 159 | ++ "movement=(%.3f,%.3f), old_flags=0x%x, new_flags=0x%x", |
| 160 | ++ tracking_id, distance, max_frame_distance_.val_, |
| 161 | ++ dx, dy, old_flags, hwstate.fingers[i].flags); |
| 162 | ++ } |
| 163 | ++ } |
| 164 | ++ } |
| 165 | ++ |
| 166 | ++ // Update previous input state |
| 167 | ++ for (size_t i = 0; i < hwstate.finger_cnt; i++) |
| 168 | ++ previous_input_[hwstate.fingers[i].tracking_id] = hwstate.fingers[i]; |
| 169 | ++ |
| 170 | ++ LogHardwareStatePost(name, hwstate); |
| 171 | ++ next_->SyncInterpret(hwstate, timeout); |
| 172 | ++} |
| 173 | ++ |
| 174 | ++} // namespace gestures |
| 175 | +\ No newline at end of file |
| 176 | +diff --git a/src/gestures.cc b/src/gestures.cc |
| 177 | +index 2907e3e..73ac141 100644 |
| 178 | +--- a/src/gestures.cc |
| 179 | ++++ b/src/gestures.cc |
| 180 | +@@ -10,6 +10,7 @@ |
| 181 | + #include "include/accel_filter_interpreter.h" |
| 182 | + #include "include/box_filter_interpreter.h" |
| 183 | + #include "include/click_wiggle_filter_interpreter.h" |
| 184 | ++#include "include/distance_filter_interpreter.h" |
| 185 | + #include "include/finger_merge_filter_interpreter.h" |
| 186 | + #include "include/finger_metrics.h" |
| 187 | + #include "include/fling_stop_filter_interpreter.h" |
| 188 | +@@ -548,6 +549,7 @@ void GestureInterpreter::InitializeTouchpad(void) { |
| 189 | + temp = new IirFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 190 | + temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 191 | + temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 192 | ++ temp = new DistanceFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 193 | + temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp, |
| 194 | + tracer_.get()); |
| 195 | + temp = new SensorJumpFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 196 | +@@ -584,6 +586,7 @@ void GestureInterpreter::InitializeTouchpad2(void) { |
| 197 | + tracer_.get()); |
| 198 | + temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 199 | + temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 200 | ++ temp = new DistanceFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 201 | + temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp, |
| 202 | + tracer_.get()); |
| 203 | + temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get()); |
| 204 | +-- |
| 205 | +2.34.1 |
| 206 | + |
0 commit comments