xref: /aosp_15_r20/external/libchrome-gestures/src/sensor_jump_filter_interpreter.cc (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
1 // Copyright 2012 The ChromiumOS Authors
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 "include/sensor_jump_filter_interpreter.h"
6 
7 #include "include/tracer.h"
8 #include "include/util.h"
9 
10 namespace gestures {
11 
SensorJumpFilterInterpreter(PropRegistry * prop_reg,Interpreter * next,Tracer * tracer)12 SensorJumpFilterInterpreter::SensorJumpFilterInterpreter(PropRegistry* prop_reg,
13                                                          Interpreter* next,
14                                                          Tracer* tracer)
15     : FilterInterpreter(nullptr, next, tracer, false),
16       enabled_(prop_reg, "Sensor Jump Filter Enable", false),
17       min_warp_dist_non_move_(prop_reg, "Sensor Jump Min Dist Non-Move", 0.9),
18       max_warp_dist_non_move_(prop_reg, "Sensor Jump Max Dist Non-Move", 7.5),
19       similar_multiplier_non_move_(prop_reg,
20                                    "Sensor Jump Similar Multiplier Non-Move",
21                                    0.9),
22       min_warp_dist_move_(prop_reg, "Sensor Jump Min Dist Move", 0.9),
23       max_warp_dist_move_(prop_reg, "Sensor Jump Max Dist Move", 7.5),
24       similar_multiplier_move_(prop_reg,
25                                "Sensor Jump Similar Multiplier Move",
26                                0.9),
27       no_warp_min_dist_move_(prop_reg,
28                              "Sensor Jump No Warp Min Dist Move",
29                              0.21) {
30   InitName();
31 }
32 
SyncInterpretImpl(HardwareState & hwstate,stime_t * timeout)33 void SensorJumpFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
34                                                         stime_t* timeout) {
35   const char name[] = "SensorJumpFilterInterpreter::SyncInterpretImpl";
36   LogHardwareStatePre(name, hwstate);
37 
38   if (!enabled_.val_) {
39     next_->SyncInterpret(hwstate, timeout);
40     return;
41   }
42 
43   RemoveMissingIdsFromMap(&previous_input_[0], hwstate);
44   RemoveMissingIdsFromMap(&previous_input_[1], hwstate);
45   RemoveMissingIdsFromSet(&first_flag_[0], hwstate);
46   RemoveMissingIdsFromSet(&first_flag_[1], hwstate);
47   RemoveMissingIdsFromSet(&first_flag_[2], hwstate);
48   RemoveMissingIdsFromSet(&first_flag_[3], hwstate);
49 
50   std::map<short, FingerState> current_input;
51 
52   for (size_t i = 0; i < hwstate.finger_cnt; i++)
53     current_input[hwstate.fingers[i].tracking_id] = hwstate.fingers[i];
54 
55   for (size_t i = 0; i < hwstate.finger_cnt; i++) {
56     short tracking_id = hwstate.fingers[i].tracking_id;
57     if (!MapContainsKey(previous_input_[1], tracking_id) ||
58         !MapContainsKey(previous_input_[0], tracking_id))
59       continue;
60     FingerState* fs[] = {
61       &hwstate.fingers[i],  // newest
62       &previous_input_[0][tracking_id],
63       &previous_input_[1][tracking_id],  // oldest
64     };
65     float FingerState::* const fields[] = { &FingerState::position_x,
66                                             &FingerState::position_y,
67                                             &FingerState::position_x,
68                                             &FingerState::position_y };
69 
70     unsigned warp[] = { GESTURES_FINGER_WARP_X_NON_MOVE,
71                         GESTURES_FINGER_WARP_Y_NON_MOVE,
72                         GESTURES_FINGER_WARP_X_MOVE,
73                         GESTURES_FINGER_WARP_Y_MOVE };
74 
75     for (size_t f_idx = 0; f_idx < arraysize(fields); f_idx++) {
76       float FingerState::* const field = fields[f_idx];
77       const float val[] = {
78         fs[0]->*field,  // newest
79         fs[1]->*field,
80         fs[2]->*field,  // oldest
81       };
82       const float delta[] = {
83         val[0] - val[1],  // newer
84         val[1] - val[2],  // older
85       };
86 
87       bool warp_move = (warp[f_idx] == GESTURES_FINGER_WARP_X_MOVE ||
88                         warp[f_idx] == GESTURES_FINGER_WARP_Y_MOVE);
89       float min_warp_dist = warp_move ? min_warp_dist_move_.val_ :
90           min_warp_dist_non_move_.val_;
91       float max_warp_dist = warp_move ? max_warp_dist_move_.val_ :
92           max_warp_dist_non_move_.val_;
93       float similar_multiplier = warp_move ? similar_multiplier_move_.val_ :
94           similar_multiplier_non_move_.val_;
95 
96       const float kAllowableChange = fabsf(delta[1] * similar_multiplier);
97 
98       bool should_warp = false;
99       bool should_store_flag = false;
100       if (delta[0] * delta[1] < 0.0) {
101         // switched direction
102         // Don't mark direction change with small delta with WARP_*_MOVE.
103         if (!warp_move || !(fabsf(delta[0]) < no_warp_min_dist_move_.val_ &&
104                             fabsf(delta[1]) < no_warp_min_dist_move_.val_))
105           should_store_flag = should_warp = true;
106       } else if (fabsf(delta[0]) < min_warp_dist ||
107                  fabsf(delta[0]) > max_warp_dist) {
108         // acceptable movement
109       } else if (fabsf(delta[0] - delta[1]) <= kAllowableChange) {
110         if (SetContainsValue(first_flag_[f_idx], tracking_id)) {
111           // Was flagged last time. Flag one more time
112           should_warp = true;
113         }
114       } else {
115         should_store_flag = should_warp = true;
116       }
117       if (should_warp) {
118         fs[0]->flags |= (warp[f_idx] | GESTURES_FINGER_WARP_TELEPORTATION);
119         // Warping moves here get tap warped, too
120         if (warp_move) {
121           fs[0]->flags |= warp[f_idx] == GESTURES_FINGER_WARP_X_MOVE ?
122               GESTURES_FINGER_WARP_X_TAP_MOVE : GESTURES_FINGER_WARP_Y_TAP_MOVE;
123         }
124       }
125       if (should_store_flag)
126         first_flag_[f_idx].insert(tracking_id);
127       else
128         first_flag_[f_idx].erase(tracking_id);
129     }
130   }
131 
132   // Update previous input/output state
133   previous_input_[1] = previous_input_[0];
134   previous_input_[0] = current_input;
135 
136   LogHardwareStatePost(name, hwstate);
137   next_->SyncInterpret(hwstate, timeout);
138 }
139 
140 }  // namespace gestures
141