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