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