• 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 "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(NULL, 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   if (!enabled_.val_) {
36     next_->SyncInterpret(hwstate, timeout);
37     return;
38   }
39 
40   RemoveMissingIdsFromMap(&previous_input_[0], *hwstate);
41   RemoveMissingIdsFromMap(&previous_input_[1], *hwstate);
42   RemoveMissingIdsFromSet(&first_flag_[0], *hwstate);
43   RemoveMissingIdsFromSet(&first_flag_[1], *hwstate);
44   RemoveMissingIdsFromSet(&first_flag_[2], *hwstate);
45   RemoveMissingIdsFromSet(&first_flag_[3], *hwstate);
46 
47   std::map<short, FingerState> current_input;
48 
49   for (size_t i = 0; i < hwstate->finger_cnt; i++)
50     current_input[hwstate->fingers[i].tracking_id] = hwstate->fingers[i];
51 
52   for (size_t i = 0; i < hwstate->finger_cnt; i++) {
53     short tracking_id = hwstate->fingers[i].tracking_id;
54     if (!MapContainsKey(previous_input_[1], tracking_id) ||
55         !MapContainsKey(previous_input_[0], tracking_id))
56       continue;
57     FingerState* fs[] = {
58       &hwstate->fingers[i],  // newest
59       &previous_input_[0][tracking_id],
60       &previous_input_[1][tracking_id],  // oldest
61     };
62     float FingerState::* const fields[] = { &FingerState::position_x,
63                                             &FingerState::position_y,
64                                             &FingerState::position_x,
65                                             &FingerState::position_y };
66 
67     unsigned warp[] = { GESTURES_FINGER_WARP_X_NON_MOVE,
68                         GESTURES_FINGER_WARP_Y_NON_MOVE,
69                         GESTURES_FINGER_WARP_X_MOVE,
70                         GESTURES_FINGER_WARP_Y_MOVE };
71 
72     for (size_t f_idx = 0; f_idx < arraysize(fields); f_idx++) {
73       float FingerState::* const field = fields[f_idx];
74       const float val[] = {
75         fs[0]->*field,  // newest
76         fs[1]->*field,
77         fs[2]->*field,  // oldest
78       };
79       const float delta[] = {
80         val[0] - val[1],  // newer
81         val[1] - val[2],  // older
82       };
83 
84       bool warp_move = (warp[f_idx] == GESTURES_FINGER_WARP_X_MOVE ||
85                         warp[f_idx] == GESTURES_FINGER_WARP_Y_MOVE);
86       float min_warp_dist = warp_move ? min_warp_dist_move_.val_ :
87           min_warp_dist_non_move_.val_;
88       float max_warp_dist = warp_move ? max_warp_dist_move_.val_ :
89           max_warp_dist_non_move_.val_;
90       float similar_multiplier = warp_move ? similar_multiplier_move_.val_ :
91           similar_multiplier_non_move_.val_;
92 
93       const float kAllowableChange = fabsf(delta[1] * similar_multiplier);
94 
95       bool should_warp = false;
96       bool should_store_flag = false;
97       if (delta[0] * delta[1] < 0.0) {
98         // switched direction
99         // Don't mark direction change with small delta with WARP_*_MOVE.
100         if (!warp_move || !(fabsf(delta[0]) < no_warp_min_dist_move_.val_ &&
101                             fabsf(delta[1]) < no_warp_min_dist_move_.val_))
102           should_store_flag = should_warp = true;
103       } else if (fabsf(delta[0]) < min_warp_dist ||
104                  fabsf(delta[0]) > max_warp_dist) {
105         // acceptable movement
106       } else if (fabsf(delta[0] - delta[1]) <= kAllowableChange) {
107         if (SetContainsValue(first_flag_[f_idx], tracking_id)) {
108           // Was flagged last time. Flag one more time
109           should_warp = true;
110         }
111       } else {
112         should_store_flag = should_warp = true;
113       }
114       if (should_warp) {
115         fs[0]->flags |= (warp[f_idx] | GESTURES_FINGER_WARP_TELEPORTATION);
116         // Warping moves here get tap warped, too
117         if (warp_move) {
118           fs[0]->flags |= warp[f_idx] == GESTURES_FINGER_WARP_X_MOVE ?
119               GESTURES_FINGER_WARP_X_TAP_MOVE : GESTURES_FINGER_WARP_Y_TAP_MOVE;
120         }
121       }
122       if (should_store_flag)
123         first_flag_[f_idx].insert(tracking_id);
124       else
125         first_flag_[f_idx].erase(tracking_id);
126     }
127   }
128 
129   // Update previous input/output state
130   previous_input_[1] = previous_input_[0];
131   previous_input_[0] = current_input;
132 
133   next_->SyncInterpret(hwstate, timeout);
134 }
135 
136 }  // namespace gestures
137