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