• 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/gestures.h"
6 
7 #include <cstring>
8 #include <sys/time.h>
9 
10 #include "include/accel_filter_interpreter.h"
11 #include "include/box_filter_interpreter.h"
12 #include "include/click_wiggle_filter_interpreter.h"
13 #include "include/finger_merge_filter_interpreter.h"
14 #include "include/finger_metrics.h"
15 #include "include/fling_stop_filter_interpreter.h"
16 #include "include/haptic_button_generator_filter_interpreter.h"
17 #include "include/iir_filter_interpreter.h"
18 #include "include/immediate_interpreter.h"
19 #include "include/integral_gesture_filter_interpreter.h"
20 #include "include/logging.h"
21 #include "include/logging_filter_interpreter.h"
22 #include "include/lookahead_filter_interpreter.h"
23 #include "include/metrics_filter_interpreter.h"
24 #include "include/mouse_interpreter.h"
25 #include "include/multitouch_mouse_interpreter.h"
26 #include "include/non_linearity_filter_interpreter.h"
27 #include "include/palm_classifying_filter_interpreter.h"
28 #include "include/prop_registry.h"
29 #include "include/scaling_filter_interpreter.h"
30 #include "include/sensor_jump_filter_interpreter.h"
31 #include "include/split_correcting_filter_interpreter.h"
32 #include "include/stationary_wiggle_filter_interpreter.h"
33 #include "include/string_util.h"
34 #include "include/stuck_button_inhibitor_filter_interpreter.h"
35 #include "include/t5r2_correcting_filter_interpreter.h"
36 #include "include/timestamp_filter_interpreter.h"
37 #include "include/trace_marker.h"
38 #include "include/tracer.h"
39 #include "include/trend_classifying_filter_interpreter.h"
40 #include "include/util.h"
41 
42 using std::string;
43 using std::min;
44 using gestures::StringPrintf;
45 
46 // C API:
47 
48 static const int kMinSupportedVersion = 1;
49 static const int kMaxSupportedVersion = 1;
50 
StimeFromTimeval(const struct timeval * tv)51 stime_t StimeFromTimeval(const struct timeval* tv) {
52   return static_cast<stime_t>(tv->tv_sec) +
53       static_cast<stime_t>(tv->tv_usec) / 1000000.0;
54 }
55 
StimeFromTimespec(const struct timespec * ts)56 stime_t StimeFromTimespec(const struct timespec* ts) {
57   return static_cast<stime_t>(ts->tv_sec) +
58       static_cast<stime_t>(ts->tv_nsec) / 1000000000.0;
59 }
60 
String() const61 std::string HardwareProperties::String() const {
62   return StringPrintf("%f,  // left edge\n"
63                       "%f,  // top edge\n"
64                       "%f,  // right edge\n"
65                       "%f,  // bottom edge\n"
66                       "%f,  // x pixels/TP width\n"
67                       "%f,  // y pixels/TP height\n"
68                       "%f,  // x screen DPI\n"
69                       "%f,  // y screen DPI\n"
70                       "%f,  // orientation minimum\n"
71                       "%f,  // orientation maximum\n"
72                       "%u,  // max fingers\n"
73                       "%u,  // max touch\n"
74                       "%u,  // t5r2\n"
75                       "%u,  // semi-mt\n"
76                       "%u   // is button pad\n",
77                       left, top, right, bottom,
78                       res_x,
79                       res_y,
80                       screen_x_dpi,
81                       screen_y_dpi,
82                       orientation_minimum,
83                       orientation_maximum,
84                       max_finger_cnt,
85                       max_touch_cnt,
86                       supports_t5r2,
87                       support_semi_mt,
88                       is_button_pad);
89 }
90 
91 namespace {
NameForFingerStateFlag(unsigned flag)92 string NameForFingerStateFlag(unsigned flag) {
93 #define CASERET(name)                           \
94   case name: return #name
95   switch (flag) {
96     CASERET(GESTURES_FINGER_WARP_X_NON_MOVE);
97     CASERET(GESTURES_FINGER_WARP_Y_NON_MOVE);
98     CASERET(GESTURES_FINGER_NO_TAP);
99     CASERET(GESTURES_FINGER_POSSIBLE_PALM);
100     CASERET(GESTURES_FINGER_PALM);
101     CASERET(GESTURES_FINGER_WARP_X_MOVE);
102     CASERET(GESTURES_FINGER_WARP_Y_MOVE);
103     CASERET(GESTURES_FINGER_WARP_X_TAP_MOVE);
104     CASERET(GESTURES_FINGER_WARP_Y_TAP_MOVE);
105     CASERET(GESTURES_FINGER_MERGE);
106     CASERET(GESTURES_FINGER_TREND_INC_X);
107     CASERET(GESTURES_FINGER_TREND_DEC_X);
108     CASERET(GESTURES_FINGER_TREND_INC_Y);
109     CASERET(GESTURES_FINGER_TREND_DEC_Y);
110     CASERET(GESTURES_FINGER_TREND_INC_PRESSURE);
111     CASERET(GESTURES_FINGER_TREND_DEC_PRESSURE);
112     CASERET(GESTURES_FINGER_TREND_INC_TOUCH_MAJOR);
113     CASERET(GESTURES_FINGER_TREND_DEC_TOUCH_MAJOR);
114     CASERET(GESTURES_FINGER_INSTANTANEOUS_MOVING);
115     CASERET(GESTURES_FINGER_WARP_TELEPORTATION);
116   }
117 #undef CASERET
118   return "";
119 }
120 }  // namespace {}
121 
FlagsString(unsigned flags)122 string FingerState::FlagsString(unsigned flags) {
123   string ret;
124   const char kPipeSeparator[] = " | ";
125   for (unsigned i = 0; i < 8 * sizeof(flags); i++) {
126     const unsigned flag = 1 << i;
127     const string name = NameForFingerStateFlag(flag);
128     if ((flags & flag) && !name.empty()) {
129       ret += kPipeSeparator;
130       ret += name;
131       flags &= ~flag;
132     }
133   }
134   if (flags) {
135     // prepend remaining number
136     ret = StringPrintf("%u%s", flags, ret.c_str());
137   } else if (ret.rfind(kPipeSeparator, 0) == 0) {
138     // strip extra pipe
139     ret = ret.substr(strlen(kPipeSeparator));
140   } else {
141     ret = "0";
142   }
143   return ret;
144 }
145 
String() const146 string FingerState::String() const {
147   return StringPrintf("{ %f, %f, %f, %f, %f, %f, %f, %f, %d, %s }",
148                       touch_major, touch_minor,
149                       width_major, width_minor,
150                       pressure,
151                       orientation,
152                       position_x,
153                       position_y,
154                       tracking_id,
155                       FlagsString(flags).c_str());
156 }
157 
GetFingerState(short tracking_id)158 FingerState* HardwareState::GetFingerState(short tracking_id) {
159   return const_cast<FingerState*>(
160       const_cast<const HardwareState*>(this)->GetFingerState(tracking_id));
161 }
162 
GetFingerState(short tracking_id) const163 const FingerState* HardwareState::GetFingerState(short tracking_id) const {
164   for (short i = 0; i < finger_cnt; i++) {
165     if (fingers[i].tracking_id == tracking_id)
166       return &fingers[i];
167   }
168   return nullptr;
169 }
170 
String() const171 string HardwareState::String() const {
172   string ret = StringPrintf("{ %f, %d, %d, %d, {",
173                             timestamp,
174                             buttons_down,
175                             finger_cnt,
176                             touch_cnt);
177   for (size_t i = 0; i < finger_cnt; i++) {
178     if (i != 0)
179       ret += ",";
180     ret += " ";
181     ret += fingers[i].String();
182   }
183   if (finger_cnt > 0)
184     ret += " ";
185   ret += "} }";
186   return ret;
187 }
188 
SameFingersAs(const HardwareState & that) const189 bool HardwareState::SameFingersAs(const HardwareState& that) const {
190   if (finger_cnt != that.finger_cnt || touch_cnt != that.touch_cnt)
191     return false;
192   // For now, require fingers to be in the same slots
193   for (size_t i = 0; i < finger_cnt; i++)
194     if (fingers[i].tracking_id != that.fingers[i].tracking_id)
195       return false;
196   return true;
197 }
198 
DeepCopy(const HardwareState & that,unsigned short max_finger_cnt)199 void HardwareState::DeepCopy(const HardwareState& that,
200                              unsigned short max_finger_cnt) {
201   timestamp = that.timestamp;
202   buttons_down = that.buttons_down;
203   touch_cnt = that.touch_cnt;
204   finger_cnt = min(that.finger_cnt, max_finger_cnt);
205   if(that.fingers != nullptr) {
206     memcpy(fingers, that.fingers, finger_cnt * sizeof(FingerState));
207   } else if (finger_cnt > 0) {
208     Err("HardwareState with no finger data but %d finger count", finger_cnt);
209   }
210   rel_x = that.rel_x;
211   rel_y = that.rel_y;
212   rel_wheel = that.rel_wheel;
213   rel_wheel_hi_res = that.rel_wheel_hi_res;
214   rel_hwheel = that.rel_hwheel;
215   msc_timestamp = that.msc_timestamp;
216 }
217 
String() const218 string Gesture::String() const {
219   switch (type) {
220     case kGestureTypeNull:
221       return "(Gesture type: null)";
222     case kGestureTypeContactInitiated:
223       return StringPrintf("(Gesture type: contactInitiated "
224                           "start: %f stop: %f)", start_time, end_time);
225     case kGestureTypeMove:
226       return StringPrintf("(Gesture type: move start: %f stop: %f "
227                           "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
228                           start_time, end_time,
229                           details.move.dx, details.move.dy,
230                           details.move.ordinal_dx, details.move.ordinal_dy);
231     case kGestureTypeScroll:
232       return StringPrintf("(Gesture type: scroll start: %f stop: %f "
233                           "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
234                           start_time, end_time,
235                           details.scroll.dx, details.scroll.dy,
236                           details.scroll.ordinal_dx, details.scroll.ordinal_dy);
237     case kGestureTypeMouseWheel:
238       return StringPrintf("(Gesture type: wheel start: %f stop %f "
239                           "dx: %f dy: %f "
240                           "tick_120ths_dx: %d tick_120ths_dy: %d)",
241                           start_time, end_time,
242                           details.wheel.dx, details.wheel.dy,
243                           details.wheel.tick_120ths_dx,
244                           details.wheel.tick_120ths_dy);
245     case kGestureTypePinch:
246       return StringPrintf("(Gesture type: pinch start: %f stop: %f "
247                           "dz: %f ordinal_dz: %f, state: %d)", start_time,
248                           end_time, details.pinch.dz, details.pinch.ordinal_dz,
249                           details.pinch.zoom_state);
250     case kGestureTypeButtonsChange:
251       return StringPrintf("(Gesture type: buttons start: %f stop: "
252                           "%f down: %d up: %d)", start_time, end_time,
253                           details.buttons.down, details.buttons.up);
254     case kGestureTypeFling:
255       return StringPrintf("(Gesture type: fling start: %f stop: "
256                           "%f vx: %f vy: %f ordinal_dx: %f ordinal_dy: %f "
257                           "state: %s)", start_time, end_time,
258                           details.fling.vx, details.fling.vy,
259                           details.fling.ordinal_vx, details.fling.ordinal_vy,
260                           details.fling.fling_state == GESTURES_FLING_START ?
261                           "start" : "tapdown");
262     case kGestureTypeSwipe:
263       return StringPrintf("(Gesture type: swipe start: %f stop: %f "
264                           "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
265                           start_time, end_time,
266                           details.swipe.dx, details.swipe.dy,
267                           details.swipe.ordinal_dx, details.swipe.ordinal_dy);
268     case kGestureTypeSwipeLift:
269       return StringPrintf("(Gesture type: swipeLift start: %f stop: %f)",
270                           start_time, end_time);
271     case kGestureTypeFourFingerSwipe:
272       return StringPrintf("(Gesture type: fourFingerSwipe start: %f stop: %f "
273                           "dx: %f dy: %f ordinal_dx: %f ordinal_dy: %f)",
274                           start_time, end_time,
275                           details.four_finger_swipe.dx,
276                           details.four_finger_swipe.dy,
277                           details.four_finger_swipe.ordinal_dx,
278                           details.four_finger_swipe.ordinal_dy);
279     case kGestureTypeFourFingerSwipeLift:
280       return StringPrintf("(Gesture type: fourFingerSwipeLift start: %f "
281                           "stop: %f)", start_time, end_time);
282     case kGestureTypeMetrics:
283       return StringPrintf("(Gesture type: metrics start: %f stop: %f "
284                           "type: %d d1: %f d2: %f)", start_time, end_time,
285                           details.metrics.type,
286                           details.metrics.data[0], details.metrics.data[1]);
287   }
288   return "(Gesture type: unknown)";
289 }
290 
operator ==(const Gesture & that) const291 bool Gesture::operator==(const Gesture& that) const {
292   if (type != that.type)
293     return false;
294   bool times_equal = gestures::DoubleEq(start_time, that.start_time) &&
295                      gestures::DoubleEq(end_time, that.end_time);
296   switch (type) {
297     case kGestureTypeNull:  // fall through
298     case kGestureTypeContactInitiated:
299       return true;
300     case kGestureTypeMove:
301       return times_equal &&
302           gestures::FloatEq(details.move.dx, that.details.move.dx) &&
303           gestures::FloatEq(details.move.dy, that.details.move.dy);
304     case kGestureTypeScroll:
305       return times_equal &&
306           gestures::FloatEq(details.scroll.dx, that.details.scroll.dx) &&
307           gestures::FloatEq(details.scroll.dy, that.details.scroll.dy);
308     case kGestureTypeMouseWheel:
309       return times_equal &&
310           gestures::FloatEq(details.wheel.dx, that.details.wheel.dx) &&
311           gestures::FloatEq(details.wheel.dy, that.details.wheel.dy) &&
312           details.wheel.tick_120ths_dx == that.details.wheel.tick_120ths_dx &&
313           details.wheel.tick_120ths_dy == that.details.wheel.tick_120ths_dy;
314     case kGestureTypePinch:
315       return times_equal &&
316           gestures::FloatEq(details.pinch.dz, that.details.pinch.dz);
317     case kGestureTypeButtonsChange:
318       return times_equal &&
319           details.buttons.down == that.details.buttons.down &&
320           details.buttons.up == that.details.buttons.up;
321     case kGestureTypeFling:
322       return times_equal &&
323           gestures::FloatEq(details.fling.vx, that.details.fling.vx) &&
324           gestures::FloatEq(details.fling.vy, that.details.fling.vy);
325     case kGestureTypeSwipe:
326       return times_equal &&
327           gestures::FloatEq(details.swipe.dx, that.details.swipe.dx);
328     case kGestureTypeSwipeLift:
329       return times_equal;
330     case kGestureTypeFourFingerSwipe:
331       return times_equal &&
332           gestures::FloatEq(details.four_finger_swipe.dx,
333               that.details.four_finger_swipe.dx);
334     case kGestureTypeFourFingerSwipeLift:
335       return times_equal;
336     case kGestureTypeMetrics:
337       return times_equal &&
338           details.metrics.type == that.details.metrics.type &&
339           gestures::FloatEq(details.metrics.data[0],
340               that.details.metrics.data[0]) &&
341           gestures::FloatEq(details.metrics.data[1],
342               that.details.metrics.data[1]);
343   }
344   return true;
345 }
346 
NewGestureInterpreterImpl(int version)347 GestureInterpreter* NewGestureInterpreterImpl(int version) {
348   if (version < kMinSupportedVersion) {
349     Err("Client too old. It's using version %d"
350         ", but library has min supported version %d",
351         version,
352         kMinSupportedVersion);
353     return nullptr;
354   }
355   if (version > kMaxSupportedVersion) {
356     Err("Client too new. It's using version %d"
357         ", but library has max supported version %d",
358         version,
359         kMaxSupportedVersion);
360     return nullptr;
361   }
362   return new gestures::GestureInterpreter(version);
363 }
364 
DeleteGestureInterpreter(GestureInterpreter * obj)365 void DeleteGestureInterpreter(GestureInterpreter* obj) {
366   delete obj;
367 }
368 
GestureInterpreterPushHardwareState(GestureInterpreter * obj,struct HardwareState * hwstate)369 void GestureInterpreterPushHardwareState(GestureInterpreter* obj,
370                                          struct HardwareState* hwstate) {
371   obj->PushHardwareState(hwstate);
372 }
373 
GestureInterpreterSetHardwareProperties(GestureInterpreter * obj,const struct HardwareProperties * hwprops)374 void GestureInterpreterSetHardwareProperties(
375     GestureInterpreter* obj,
376     const struct HardwareProperties* hwprops) {
377   obj->SetHardwareProperties(*hwprops);
378 }
379 
GestureInterpreterSetCallback(GestureInterpreter * obj,GestureReadyFunction fn,void * user_data)380 void GestureInterpreterSetCallback(GestureInterpreter* obj,
381                                    GestureReadyFunction fn,
382                                    void* user_data) {
383   obj->SetCallback(fn, user_data);
384 }
385 
GestureInterpreterSetTimerProvider(GestureInterpreter * obj,GesturesTimerProvider * tp,void * data)386 void GestureInterpreterSetTimerProvider(GestureInterpreter* obj,
387                                         GesturesTimerProvider* tp,
388                                         void* data) {
389   obj->SetTimerProvider(tp, data);
390 }
391 
GestureInterpreterSetPropProvider(GestureInterpreter * obj,GesturesPropProvider * pp,void * data)392 void GestureInterpreterSetPropProvider(GestureInterpreter* obj,
393                                        GesturesPropProvider* pp,
394                                        void* data) {
395   obj->SetPropProvider(pp, data);
396 }
397 
GestureInterpreterInitialize(GestureInterpreter * obj,enum GestureInterpreterDeviceClass cls)398 void GestureInterpreterInitialize(GestureInterpreter* obj,
399                                   enum GestureInterpreterDeviceClass cls) {
400   obj->Initialize(cls);
401 }
402 
403 // C++ API:
404 namespace gestures {
405 class GestureInterpreterConsumer : public GestureConsumer {
406  public:
GestureInterpreterConsumer(GestureReadyFunction callback,void * callback_data)407   GestureInterpreterConsumer(GestureReadyFunction callback,
408                              void* callback_data)
409       : callback_(callback),
410         callback_data_(callback_data) {}
411 
SetCallback(GestureReadyFunction callback,void * callback_data)412   void SetCallback(GestureReadyFunction callback, void* callback_data) {
413     callback_ = callback;
414     callback_data_ = callback_data;
415   }
416 
ConsumeGesture(const Gesture & gesture)417   void ConsumeGesture(const Gesture& gesture) {
418     AssertWithReturn(gesture.type != kGestureTypeNull);
419     if (callback_)
420       callback_(callback_data_, &gesture);
421   }
422 
423  private:
424   GestureReadyFunction callback_;
425   void* callback_data_;
426 };
427 }
428 
GestureInterpreter(int version)429 GestureInterpreter::GestureInterpreter(int version)
430     : callback_(nullptr),
431       callback_data_(nullptr),
432       timer_provider_(nullptr),
433       timer_provider_data_(nullptr),
434       interpret_timer_(nullptr),
435       loggingFilter_(nullptr) {
436   prop_reg_.reset(new PropRegistry);
437   tracer_.reset(new Tracer(prop_reg_.get(), TraceMarker::StaticTraceWrite));
438   TraceMarker::CreateTraceMarker();
439 }
440 
~GestureInterpreter()441 GestureInterpreter::~GestureInterpreter() {
442   SetTimerProvider(nullptr, nullptr);
443   SetPropProvider(nullptr, nullptr);
444   TraceMarker::DeleteTraceMarker();
445 }
446 
447 namespace {
InternalTimerCallback(stime_t now,void * callback_data)448 stime_t InternalTimerCallback(stime_t now, void* callback_data) {
449   Log("TimerCallback called");
450   GestureInterpreter* gi = reinterpret_cast<GestureInterpreter*>(callback_data);
451   stime_t next = NO_DEADLINE;
452   gi->TimerCallback(now, &next);
453   return next;
454 }
455 }
456 
PushHardwareState(HardwareState * hwstate)457 void GestureInterpreter::PushHardwareState(HardwareState* hwstate) {
458   if (!interpreter_.get()) {
459     Err("Filters are not composed yet!");
460     return;
461   }
462   stime_t timeout = NO_DEADLINE;
463   interpreter_->SyncInterpret(*hwstate, &timeout);
464   if (timer_provider_ && interpret_timer_) {
465     if (timeout == NO_DEADLINE) {
466       timer_provider_->cancel_fn(timer_provider_data_, interpret_timer_);
467     } else {
468       timer_provider_->set_fn(timer_provider_data_,
469                               interpret_timer_,
470                               timeout,
471                               InternalTimerCallback,
472                               this);
473       Log("Setting timer for %f s out.", timeout);
474     }
475   } else {
476     ErrOnce("No timer provider has been set, so some features won't work.");
477   }
478 }
479 
SetHardwareProperties(const HardwareProperties & hwprops)480 void GestureInterpreter::SetHardwareProperties(
481     const HardwareProperties& hwprops) {
482   if (!interpreter_.get()) {
483     Err("Filters are not composed yet!");
484     return;
485   }
486   hwprops_ = hwprops;
487   if (consumer_)
488     interpreter_->Initialize(&hwprops_, nullptr, mprops_.get(),
489                              consumer_.get());
490 }
491 
TimerCallback(stime_t now,stime_t * timeout)492 void GestureInterpreter::TimerCallback(stime_t now, stime_t* timeout) {
493   if (!interpreter_.get()) {
494     Err("Filters are not composed yet!");
495     return;
496   }
497   interpreter_->HandleTimer(now, timeout);
498 }
499 
SetTimerProvider(GesturesTimerProvider * tp,void * data)500 void GestureInterpreter::SetTimerProvider(GesturesTimerProvider* tp,
501                                           void* data) {
502   if (timer_provider_ == tp && timer_provider_data_ == data)
503     return;
504   if (timer_provider_ && interpret_timer_) {
505     timer_provider_->free_fn(timer_provider_data_, interpret_timer_);
506     interpret_timer_ = nullptr;
507   }
508   if (interpret_timer_)
509     Err("How was interpret_timer_ not null?!");
510   timer_provider_ = tp;
511   timer_provider_data_ = data;
512   if (timer_provider_)
513     interpret_timer_ = timer_provider_->create_fn(timer_provider_data_);
514 }
515 
SetPropProvider(GesturesPropProvider * pp,void * data)516 void GestureInterpreter::SetPropProvider(GesturesPropProvider* pp,
517                                          void* data) {
518   prop_reg_->SetPropProvider(pp, data);
519 }
520 
SetCallback(GestureReadyFunction callback,void * client_data)521 void GestureInterpreter::SetCallback(GestureReadyFunction callback,
522                                      void* client_data) {
523   callback_ = callback;
524   callback_data_ = client_data;
525 
526   if (consumer_)
527     consumer_->SetCallback(callback, client_data);
528 }
529 
set_callback(GestureReadyFunction callback,void * client_data)530 void GestureInterpreter::set_callback(GestureReadyFunction callback,
531                                       void* client_data) {
532   SetCallback(callback, client_data);
533 }
534 
InitializeTouchpad(void)535 void GestureInterpreter::InitializeTouchpad(void) {
536   if (prop_reg_.get()) {
537     stack_version_ = std::make_unique<IntProperty>(prop_reg_.get(),
538                                                    "Touchpad Stack Version", 2);
539     if (stack_version_->val_ == 2) {
540       InitializeTouchpad2();
541       return;
542     }
543   }
544 
545   Interpreter* temp = new ImmediateInterpreter(prop_reg_.get(), tracer_.get());
546   temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
547                                         GESTURES_DEVCLASS_TOUCHPAD);
548   temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
549   temp = new PalmClassifyingFilterInterpreter(prop_reg_.get(), temp,
550                                               tracer_.get());
551   temp = new IirFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
552   temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
553   temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
554   temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp,
555                                                tracer_.get());
556   temp = new SensorJumpFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
557   temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
558   temp = new SplitCorrectingFilterInterpreter(prop_reg_.get(), temp,
559                                               tracer_.get());
560   temp = new TrendClassifyingFilterInterpreter(prop_reg_.get(), temp,
561                                                tracer_.get());
562   temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
563                                       GESTURES_DEVCLASS_TOUCHPAD);
564   temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
565                                       GESTURES_DEVCLASS_TOUCHPAD);
566   temp = new FingerMergeFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
567   temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
568   temp = new HapticButtonGeneratorFilterInterpreter(prop_reg_.get(), temp,
569                                                     tracer_.get());
570   temp = new T5R2CorrectingFilterInterpreter(prop_reg_.get(), temp,
571                                              tracer_.get());
572   temp = new NonLinearityFilterInterpreter(prop_reg_.get(), temp,
573                                            tracer_.get());
574   temp = new TimestampFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
575   temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
576                                                        tracer_.get());
577   interpreter_.reset(temp);
578   temp = nullptr;
579 }
580 
InitializeTouchpad2(void)581 void GestureInterpreter::InitializeTouchpad2(void) {
582   Interpreter* temp = new ImmediateInterpreter(prop_reg_.get(), tracer_.get());
583   temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
584                                         GESTURES_DEVCLASS_TOUCHPAD);
585   temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
586   temp = new PalmClassifyingFilterInterpreter(prop_reg_.get(), temp,
587                                               tracer_.get());
588   temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
589   temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
590   temp = new StationaryWiggleFilterInterpreter(prop_reg_.get(), temp,
591                                                tracer_.get());
592   temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
593   temp = new TrendClassifyingFilterInterpreter(prop_reg_.get(), temp,
594                                                tracer_.get());
595   temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
596                                       GESTURES_DEVCLASS_TOUCHPAD);
597   temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
598                                       GESTURES_DEVCLASS_TOUCHPAD);
599   temp = new FingerMergeFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
600   temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
601   temp = new HapticButtonGeneratorFilterInterpreter(prop_reg_.get(), temp,
602                                                     tracer_.get());
603   temp = new TimestampFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
604   temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
605                                                        tracer_.get());
606   interpreter_.reset(temp);
607   temp = nullptr;
608 }
609 
InitializeMouse(GestureInterpreterDeviceClass cls)610 void GestureInterpreter::InitializeMouse(GestureInterpreterDeviceClass cls) {
611   Interpreter* temp = new MouseInterpreter(prop_reg_.get(), tracer_.get());
612   // TODO(clchiou;chromium-os:36321): Use mouse acceleration algorithm for mice
613   temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
614   temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
615                                       cls);
616   temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
617                                       cls);
618   temp = new IntegralGestureFilterInterpreter(temp, tracer_.get());
619   temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
620                                                        tracer_.get());
621   interpreter_.reset(temp);
622   temp = nullptr;
623 }
624 
InitializeMultitouchMouse(void)625 void GestureInterpreter::InitializeMultitouchMouse(void) {
626   Interpreter* temp = new MultitouchMouseInterpreter(prop_reg_.get(),
627                                                      tracer_.get());
628   temp = new FlingStopFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
629                                         GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
630   temp = new ClickWiggleFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
631   temp = new LookaheadFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
632   temp = new BoxFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
633   // TODO(clchiou;chromium-os:36321): Use mouse acceleration algorithm for mice
634   temp = new AccelFilterInterpreter(prop_reg_.get(), temp, tracer_.get());
635   temp = new ScalingFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
636                                       GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
637   temp = new MetricsFilterInterpreter(prop_reg_.get(), temp, tracer_.get(),
638                                       GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
639   temp = new IntegralGestureFilterInterpreter(temp, tracer_.get());
640   temp = new StuckButtonInhibitorFilterInterpreter(temp, tracer_.get());
641   temp = new NonLinearityFilterInterpreter(prop_reg_.get(), temp,
642                                            tracer_.get());
643   temp = loggingFilter_ = new LoggingFilterInterpreter(prop_reg_.get(), temp,
644                                                        tracer_.get());
645   interpreter_.reset(temp);
646   temp = nullptr;
647 }
648 
Initialize(GestureInterpreterDeviceClass cls)649 void GestureInterpreter::Initialize(GestureInterpreterDeviceClass cls) {
650   if (cls == GESTURES_DEVCLASS_TOUCHPAD ||
651       cls == GESTURES_DEVCLASS_TOUCHSCREEN)
652     InitializeTouchpad();
653   else if (cls == GESTURES_DEVCLASS_MOUSE ||
654            cls == GESTURES_DEVCLASS_POINTING_STICK)
655     InitializeMouse(cls);
656   else if (cls == GESTURES_DEVCLASS_MULTITOUCH_MOUSE)
657     InitializeMultitouchMouse();
658   else
659     Err("Couldn't recognize device class: %d", cls);
660 
661   mprops_.reset(new MetricsProperties(prop_reg_.get()));
662   consumer_.reset(new GestureInterpreterConsumer(callback_,
663                                                    callback_data_));
664 }
665 
EncodeActivityLog()666 std::string GestureInterpreter::EncodeActivityLog() {
667   return loggingFilter_->EncodeActivityLog();
668 }
669 
670 const GestureMove kGestureMove = { 0, 0, 0, 0 };
671 const GestureScroll kGestureScroll = { 0, 0, 0, 0, 0 };
672 const GestureMouseWheel kGestureMouseWheel = { 0, 0, 0, 0 };
673 const GestureButtonsChange kGestureButtonsChange = { 0, 0, 0 };
674 const GestureFling kGestureFling = { 0, 0, 0, 0, 0 };
675 const GestureSwipe kGestureSwipe = { 0, 0, 0, 0 };
676 const GestureFourFingerSwipe kGestureFourFingerSwipe = { 0, 0, 0, 0 };
677 const GesturePinch kGesturePinch = { 0, 0, 0 };
678 const GestureSwipeLift kGestureSwipeLift = { };
679 const GestureFourFingerSwipeLift kGestureFourFingerSwipeLift = { };
680 const GestureMetrics kGestureMetrics = { kGestureMetricsTypeUnknown, {0, 0} };
681