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