xref: /aosp_15_r20/external/libchrome-gestures/include/lookahead_filter_interpreter.h (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 <algorithm>
6 #include <map>
7 #include <memory>
8 
9 #include <gtest/gtest.h>  // For FRIEND_TEST
10 
11 #include "include/filter_interpreter.h"
12 #include "include/finger_metrics.h"
13 #include "include/gestures.h"
14 #include "include/prop_registry.h"
15 #include "include/tracer.h"
16 #include "include/util.h"
17 
18 #ifndef GESTURES_LOOKAHEAD_FILTER_INTERPRETER_H_
19 #define GESTURES_LOOKAHEAD_FILTER_INTERPRETER_H_
20 
21 namespace gestures {
22 
23 class LookaheadFilterInterpreter : public FilterInterpreter {
24   FRIEND_TEST(LookaheadFilterInterpreterTest, CyapaQuickTwoFingerMoveTest);
25   FRIEND_TEST(LookaheadFilterInterpreterTest, DrumrollTest);
26   FRIEND_TEST(LookaheadFilterInterpreterTest, InterpolateHwStateTest);
27   FRIEND_TEST(LookaheadFilterInterpreterTest, InterpolateTest);
28   FRIEND_TEST(LookaheadFilterInterpreterTest, InterpolationOverdueTest);
29   FRIEND_TEST(LookaheadFilterInterpreterTest, NoTapSetTest);
30   FRIEND_TEST(LookaheadFilterInterpreterTest, QuickMoveTest);
31   FRIEND_TEST(LookaheadFilterInterpreterTest, QuickSwipeTest);
32   FRIEND_TEST(LookaheadFilterInterpreterTest, SemiMtNoTrackingIdAssignmentTest);
33   FRIEND_TEST(LookaheadFilterInterpreterParmTest, SimpleTest);
34   FRIEND_TEST(LookaheadFilterInterpreterTest, SpuriousCallbackTest);
35   FRIEND_TEST(LookaheadFilterInterpreterTest, VariableDelayTest);
36   FRIEND_TEST(LookaheadFilterInterpreterTest, AddFingerFlingTest);
37   FRIEND_TEST(LookaheadFilterInterpreterTest, ConsumeGestureTest);
38 
39  public:
40   LookaheadFilterInterpreter(PropRegistry* prop_reg, Interpreter* next,
41                              Tracer* tracer);
~LookaheadFilterInterpreter()42   virtual ~LookaheadFilterInterpreter() {}
43 
44  protected:
45   virtual void SyncInterpretImpl(HardwareState& hwstate,
46                                  stime_t* timeout);
47 
48   virtual void HandleTimerImpl(stime_t now, stime_t* timeout);
49 
50   virtual void Initialize(const HardwareProperties* hwprops,
51                           Metrics* metrics, MetricsProperties* mprops,
52                           GestureConsumer* consumer);
53 
54  private:
55   struct QState {
56     QState();
57     explicit QState(unsigned short max_fingers);
58 
59     // Deep copy of new_state to state_
60     void set_state(const HardwareState& new_state);
61 
62     HardwareState state_;
63     unsigned short max_fingers_;
64     std::unique_ptr<FingerState[]> fs_;
65     std::map<short, short> output_ids_;  // input tracking ids -> output
66 
67     stime_t due_;
68     bool completed_ = false;
69   };
70 
71   void LogVectors();
72 
73   // Produces a tapdown fling gesture if we just got a new hardware state
74   // with a finger missing from the previous, or a null gesture otherwise.
75   void TapDownOccurringGesture(stime_t now);
76 
77   // Looks at the most recent 2 states in the queue (one of which may have
78   // already completed), and if they are separated by split_min_period_ time,
79   // tries to insert an interpolated event in the middle.
80   void AttemptInterpolation();
81 
82   // Reassigns tracking IDs, assigning them in such a way to avoid problems
83   // of drumroll.
84   void AssignTrackingIds();
85 
86   // For drumroll. Edits a QState node's fingerstate to have a new tracking id.
87   void SeparateFinger(QState* node, FingerState* fs, short input_id);
88 
89   // Looks for a finger possibly lifting off the pad. If found, returns true.
90   bool LiftoffJumpStarting(const HardwareState& hs,
91                            const HardwareState& prev_hs,
92                            const HardwareState& prev2_hs) const;
93 
94   // Returns a new tracking id for a contact.
95   short NextTrackingId();
96 
97   // Interpolates first and second, storing the result into out.
98   // first and second must have the same the same number of fingers and
99   // have the same tracking_ids for all fingers.
100   static void Interpolate(const HardwareState& first,
101                           const HardwareState& second,
102                           HardwareState* out);
103 
104   void UpdateInterpreterDue(stime_t new_interpreter_due,
105                             stime_t now,
106                             stime_t* timeout);
107   void ConsumeGesture(const Gesture& gesture);
108 
109   stime_t ExtraVariableDelay() const;
110 
111   List<QState> queue_;
112 
113   // The last id assigned to a contact (part of drumroll suppression)
114   short last_id_;
115 
116   unsigned short max_fingers_per_hwstate_;
117 
118   // Last detected due_ time as an absolute deadline
119   stime_t interpreter_due_deadline_;
120 
121   // We want to present time to next_ in a monotonically increasing manner,
122   // so this keeps track of the most recent timestamp we've given next_.
123   stime_t last_interpreted_time_;
124 
125   Gesture result_;
126 
127   DoubleProperty min_nonsuppress_speed_;
128   DoubleProperty min_delay_;
129   // On some platforms, min_delay_ is very small, and sometimes we would like
130   // temporary extra delay to avoid problems, so we can in those cases add
131   // a delay specified by max_delay_. It's okay for max_delay_ to be less
132   // than min_delay_. In that case, it simply has no effect.
133   DoubleProperty max_delay_;
134   // If this much time passes between consecutive events, interpolate.
135   DoubleProperty split_min_period_;
136   // If set to false, tracking IDs are not reassigned
137   BoolProperty drumroll_suppression_enable_;
138   // If a contact appears to move faster than this, the drumroll detector may
139   // consider it a new contact.
140   DoubleProperty drumroll_speed_thresh_;
141   // If one contact's speed is more than drumroll_max_speed_ratio_ times the
142   // previous speed, the drumroll detector may consider it a new contact.
143   DoubleProperty drumroll_max_speed_ratio_;
144   // If during 3 consecutive HardwareState, one contact moves more than
145   // quick_move_thresh_ distance along the same direction on either x or y
146   // axis, both between the 1st and 2nd HardwareState, and the 2nd and 3rd
147   // HardwareState, it is considered to be a quick move and the tracking ID
148   // reassignment due to drumroll detection may get corrected.
149   DoubleProperty quick_move_thresh_;
150   // If we're going to drumroll-suppress a finger that is moving too much,
151   // we abort said suppression if it's moving less than co_move_ratio_ *
152   // distance of another non-drumroll-suppressed finger.
153   DoubleProperty co_move_ratio_;
154   // Temporary property to turn on/off the generation of TapDown gestures
155   // (i.e., stop flinging gestures).
156   BoolProperty suppress_immediate_tapdown_;
157   // If we should add extra delay when we think a finger may be lifting off.
158   BoolProperty delay_on_possible_liftoff_;
159   // If looking for a possible liftoff-move, the speed a finger is moving
160   // relative to the previous speed, such that it's a possible leave.
161   DoubleProperty liftoff_speed_increase_threshold_;
162 };
163 
164 }  // namespace gestures
165 
166 #endif  // GESTURES_LOOKAHEAD_FILTER_INTERPRETER_H_
167