xref: /aosp_15_r20/external/libchrome-gestures/src/accel_filter_interpreter_unittest.cc (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
1 // Copyright 2011 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 <deque>
6 #include <math.h>
7 #include <utility>
8 #include <vector>
9 
10 #include <gtest/gtest.h>
11 
12 #include "include/accel_filter_interpreter.h"
13 #include "include/gestures.h"
14 #include "include/macros.h"
15 #include "include/unittest_util.h"
16 #include "include/util.h"
17 
18 using std::deque;
19 using std::make_pair;
20 using std::pair;
21 using std::vector;
22 
23 namespace gestures {
24 
25 using EventDebug = ActivityLog::EventDebug;
26 
27 class AccelFilterInterpreterTest : public ::testing::Test {
28  protected:
29   HardwareState empty_hwstate_ = {};
30 };
31 
32 class AccelFilterInterpreterTestInterpreter : public Interpreter {
33  public:
AccelFilterInterpreterTestInterpreter()34   AccelFilterInterpreterTestInterpreter()
35       : Interpreter(nullptr, nullptr, false) {}
36 
SyncInterpret(HardwareState & hwstate,stime_t * timeout)37   virtual void SyncInterpret(HardwareState& hwstate, stime_t* timeout) {
38     if (return_values_.empty())
39       return;
40     return_value_ = return_values_.front();
41     return_values_.pop_front();
42     if (return_value_.type == kGestureTypeNull)
43       return;
44     ProduceGesture(return_value_);
45   }
46 
HandleTimer(stime_t now,stime_t * timeout)47   virtual void HandleTimer(stime_t now, stime_t* timeout) {
48     FAIL() << "This interpreter doesn't use timers";
49   }
50 
51   Gesture return_value_;
52   deque<Gesture> return_values_;
53 };
54 
TEST_F(AccelFilterInterpreterTest,SimpleTest)55 TEST_F(AccelFilterInterpreterTest, SimpleTest) {
56   AccelFilterInterpreterTestInterpreter* base_interpreter =
57       new AccelFilterInterpreterTestInterpreter;
58   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
59   TestInterpreterWrapper interpreter(&accel_interpreter);
60 
61   accel_interpreter.scroll_x_out_scale_.val_ =
62       accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
63 
64   float last_move_dx = 0.0;
65   float last_move_dy = 0.0;
66   float last_scroll_dx = 0.0;
67   float last_scroll_dy = 0.0;
68   float last_fling_vx = 0.0;
69   float last_fling_vy = 0.0;
70 
71   for (int i = 1; i <= 5; ++i) {
72     accel_interpreter.pointer_sensitivity_.val_ = i;
73     accel_interpreter.scroll_sensitivity_.val_ = i;
74 
75     base_interpreter->return_values_.push_back(Gesture());  // Null type
76     base_interpreter->return_values_.push_back(Gesture(kGestureMove,
77                                                        1,  // start time
78                                                        1.001,  // end time
79                                                        -4,  // dx
80                                                        2.8));  // dy
81     base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
82                                                        2,  // start time
83                                                        2.1,  // end time
84                                                        4.1,  // dx
85                                                        -10.3));  // dy
86     base_interpreter->return_values_.push_back(Gesture(kGestureFling,
87                                                        3,  // start time
88                                                        3.1,  // end time
89                                                        100.1,  // vx
90                                                        -10.3,  // vy
91                                                        0));  // state
92 
93     Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
94     ASSERT_EQ(nullptr, out);
95     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
96     ASSERT_NE(nullptr, out);
97     EXPECT_EQ(kGestureTypeMove, out->type);
98     if (i == 1) {
99       // Expect no acceleration
100       EXPECT_FLOAT_EQ(-4.0, out->details.move.dx) << "i = " << i;
101       EXPECT_FLOAT_EQ(2.8, out->details.move.dy);
102     } else {
103       // Expect increasing acceleration
104       EXPECT_GT(fabsf(out->details.move.dx), fabsf(last_move_dx));
105       EXPECT_GT(fabsf(out->details.move.dy), fabsf(last_move_dy));
106     }
107     last_move_dx = out->details.move.dx;
108     last_move_dy = out->details.move.dy;
109 
110     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
111     ASSERT_NE(nullptr, out);
112     EXPECT_EQ(kGestureTypeScroll, out->type);
113     if (i == 1) {
114       // Expect no acceleration
115       EXPECT_FLOAT_EQ(4.1, out->details.scroll.dx);
116       EXPECT_FLOAT_EQ(-10.3, out->details.scroll.dy);
117     } else if (i > 2) {
118       // Expect increasing acceleration
119       EXPECT_GT(fabsf(out->details.scroll.dx), fabsf(last_scroll_dx));
120       EXPECT_GT(fabsf(out->details.scroll.dy), fabsf(last_scroll_dy));
121     }
122     last_scroll_dx = out->details.scroll.dx;
123     last_scroll_dy = out->details.scroll.dy;
124     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
125     ASSERT_NE(nullptr, out);
126     EXPECT_EQ(kGestureTypeFling, out->type);
127     if (i == 1) {
128       // Expect no acceleration
129       EXPECT_FLOAT_EQ(100.1, out->details.fling.vx);
130       EXPECT_FLOAT_EQ(-10.3, out->details.fling.vy);
131     } else if (i > 2) {
132       // Expect increasing acceleration
133       EXPECT_GT(fabsf(out->details.fling.vx), fabsf(last_fling_vx));
134       EXPECT_GT(fabsf(out->details.fling.vy), fabsf(last_fling_vy));
135     }
136     last_fling_vx = out->details.fling.vx;
137     last_fling_vy = out->details.fling.vy;
138   }
139 }
140 
TEST_F(AccelFilterInterpreterTest,TinyMoveTest)141 TEST_F(AccelFilterInterpreterTest, TinyMoveTest) {
142   AccelFilterInterpreterTestInterpreter* base_interpreter =
143       new AccelFilterInterpreterTestInterpreter;
144   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
145   TestInterpreterWrapper interpreter(&accel_interpreter);
146   accel_interpreter.scroll_x_out_scale_.val_ =
147       accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
148 
149   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
150                                                      1,  // start time
151                                                      2,  // end time
152                                                      4,  // dx
153                                                      0));  // dy
154   base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
155                                                      2,  // start time
156                                                      3,  // end time
157                                                      4,  // dx
158                                                      0));  // dy
159   base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
160                                                      2,  // start time
161                                                      3,  // end time
162                                                      4,  // dx
163                                                      0));  // dy
164 
165   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
166   ASSERT_NE(nullptr, out);
167   EXPECT_EQ(kGestureTypeMove, out->type);
168   EXPECT_GT(fabsf(out->details.move.dx), 2);
169   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
170   ASSERT_NE(nullptr, out);
171   EXPECT_EQ(kGestureTypeScroll, out->type);
172   EXPECT_GT(fabsf(out->details.scroll.dx), 2);
173   float orig_x_scroll = out->details.scroll.dx;
174   accel_interpreter.scroll_x_out_scale_.val_ = 2.0;
175   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
176   ASSERT_NE(nullptr, out);
177   EXPECT_EQ(kGestureTypeScroll, out->type);
178   EXPECT_FLOAT_EQ(orig_x_scroll * accel_interpreter.scroll_x_out_scale_.val_,
179                   out->details.scroll.dx);
180 }
181 
TEST_F(AccelFilterInterpreterTest,BadGestureTest)182 TEST_F(AccelFilterInterpreterTest, BadGestureTest) {
183   PropRegistry prop_reg;
184   AccelFilterInterpreterTestInterpreter* base_interpreter =
185       new AccelFilterInterpreterTestInterpreter;
186   AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
187                                            nullptr);
188   TestInterpreterWrapper interpreter(&accel_interpreter);
189 
190   accel_interpreter.SetEventLoggingEnabled(true);
191   accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
192   accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
193   accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
194 
195   // AccelFilterInterpreter should not add gain to a ButtonsChange gesture.
196   base_interpreter->return_values_.push_back(Gesture(kGestureButtonsChange,
197                                                      1,  // start time
198                                                      2,  // end time
199                                                      0, // down
200                                                      0, // up
201                                                      false)); // is_tap
202 
203   // Send the ButtonsChange into AccelFilterInterpreter. The filter
204   // should send it right back out.
205   EXPECT_EQ(accel_interpreter.log_->size(), 0);
206   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
207   ASSERT_NE(nullptr, out);
208   EXPECT_EQ(kGestureTypeButtonsChange, out->type);
209 
210   // Encode the log into Json
211   Json::Value node;
212   Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
213 
214   // Verify the Json information
215   EXPECT_EQ(accel_interpreter.log_->size(), 5);
216   node = tree[ActivityLog::kKeyRoot][0];
217   EXPECT_EQ(node[ActivityLog::kKeyType],
218             Json::Value(ActivityLog::kKeyHardwareState));
219   node = tree[ActivityLog::kKeyRoot][1];
220   EXPECT_EQ(node[ActivityLog::kKeyType],
221             Json::Value(ActivityLog::kKeyGestureConsume));
222   node = tree[ActivityLog::kKeyRoot][2];
223   EXPECT_EQ(node[ActivityLog::kKeyType],
224             Json::Value(ActivityLog::kKeyAccelGestureDebug));
225   node = tree[ActivityLog::kKeyRoot][3];
226   EXPECT_EQ(node[ActivityLog::kKeyType],
227             Json::Value(ActivityLog::kKeyGestureProduce));
228   node = tree[ActivityLog::kKeyRoot][4];
229   EXPECT_EQ(node[ActivityLog::kKeyType],
230             Json::Value(ActivityLog::kKeyGesture));
231   accel_interpreter.log_->Clear();
232 }
233 
TEST_F(AccelFilterInterpreterTest,BadDeltaTTest)234 TEST_F(AccelFilterInterpreterTest, BadDeltaTTest) {
235   PropRegistry prop_reg;
236   AccelFilterInterpreterTestInterpreter* base_interpreter =
237       new AccelFilterInterpreterTestInterpreter;
238   AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
239                                            nullptr);
240   TestInterpreterWrapper interpreter(&accel_interpreter);
241 
242   accel_interpreter.SetEventLoggingEnabled(true);
243   accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
244   accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
245   accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
246 
247   // Change the bounds for reasonable minimum Dt.  This will allow the filter
248   // to keep a very small Dt without adjusting it.
249   accel_interpreter.min_reasonable_dt_.val_ = 0;
250 
251   // Send the filter a very small Dt and have the logic catch that it
252   // is too small.  This will not allow a fictitious Dt to be used but
253   // will just not apply gain to this specific gesture.
254   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
255                                                      1,  // start time
256                                                      1.000001, // end time
257                                                      4,  // dx
258                                                      0));  // dy
259 
260   // Send the Move into AccelFilterInterpreter. No gain should be applied
261   // to Dx, even though this small of a Dt would normally have added a lot
262   // of gain.
263   EXPECT_EQ(accel_interpreter.log_->size(), 0);
264   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
265   ASSERT_NE(nullptr, out);
266   EXPECT_EQ(kGestureTypeMove, out->type);
267   EXPECT_EQ(fabsf(out->details.move.dx), 4);
268 
269   // Encode the log into Json
270   Json::Value node;
271   Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
272 
273   // Verify the Json information
274   EXPECT_EQ(accel_interpreter.log_->size(), 5);
275   node = tree[ActivityLog::kKeyRoot][0];
276   EXPECT_EQ(node[ActivityLog::kKeyType],
277             Json::Value(ActivityLog::kKeyHardwareState));
278   node = tree[ActivityLog::kKeyRoot][1];
279   EXPECT_EQ(node[ActivityLog::kKeyType],
280             Json::Value(ActivityLog::kKeyGestureConsume));
281   node = tree[ActivityLog::kKeyRoot][2];
282   EXPECT_EQ(node[ActivityLog::kKeyType],
283             Json::Value(ActivityLog::kKeyAccelGestureDebug));
284   node = tree[ActivityLog::kKeyRoot][3];
285   EXPECT_EQ(node[ActivityLog::kKeyType],
286             Json::Value(ActivityLog::kKeyGestureProduce));
287   node = tree[ActivityLog::kKeyRoot][4];
288   EXPECT_EQ(node[ActivityLog::kKeyType],
289             Json::Value(ActivityLog::kKeyGesture));
290   accel_interpreter.log_->Clear();
291 }
292 
TEST_F(AccelFilterInterpreterTest,BadSpeedFlingTest)293 TEST_F(AccelFilterInterpreterTest, BadSpeedFlingTest) {
294   PropRegistry prop_reg;
295   AccelFilterInterpreterTestInterpreter* base_interpreter =
296       new AccelFilterInterpreterTestInterpreter;
297   AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
298                                            nullptr);
299   TestInterpreterWrapper interpreter(&accel_interpreter);
300 
301   accel_interpreter.SetEventLoggingEnabled(true);
302   accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
303   accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
304   accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
305 
306   // Change the bounds for reasonable maximum Dt.  This will allow the filter
307   // to keep a large Dt without adjusting it.
308   accel_interpreter.max_reasonable_dt_.val_ = 1000;
309 
310   // Send the filter a Fling with a large Dt and have the logic catch that it
311   // is too big.  This will not allow a fictitious Dt to be used but will
312   // just not apply gain to this specific gesture.
313   base_interpreter->return_values_.push_back(Gesture(kGestureFling,
314                                                      1,  // start time
315                                                      2,  // end time
316                                                      0.000001,  // vx
317                                                      0,   // vy
318                                                      0)); // state
319 
320   // Send the Fling into AccelFilterInterpreter. No gain should be applied
321   // to Vx.
322   EXPECT_EQ(accel_interpreter.log_->size(), 0);
323   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
324   ASSERT_NE(nullptr, out);
325   EXPECT_EQ(kGestureTypeFling, out->type);
326   EXPECT_NEAR(fabsf(out->details.fling.vx), 0.000001, 0.0000001);
327 
328   // Encode the log into Json
329   Json::Value node;
330   Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
331 
332   // Verify the Json information
333   EXPECT_EQ(accel_interpreter.log_->size(), 5);
334   node = tree[ActivityLog::kKeyRoot][0];
335   EXPECT_EQ(node[ActivityLog::kKeyType],
336             Json::Value(ActivityLog::kKeyHardwareState));
337   node = tree[ActivityLog::kKeyRoot][1];
338   EXPECT_EQ(node[ActivityLog::kKeyType],
339             Json::Value(ActivityLog::kKeyGestureConsume));
340   node = tree[ActivityLog::kKeyRoot][2];
341   EXPECT_EQ(node[ActivityLog::kKeyType],
342             Json::Value(ActivityLog::kKeyAccelGestureDebug));
343   node = tree[ActivityLog::kKeyRoot][3];
344   EXPECT_EQ(node[ActivityLog::kKeyType],
345             Json::Value(ActivityLog::kKeyGestureProduce));
346   node = tree[ActivityLog::kKeyRoot][4];
347   EXPECT_EQ(node[ActivityLog::kKeyType],
348             Json::Value(ActivityLog::kKeyGesture));
349   accel_interpreter.log_->Clear();
350 }
351 
TEST_F(AccelFilterInterpreterTest,BadSpeedMoveTest)352 TEST_F(AccelFilterInterpreterTest, BadSpeedMoveTest) {
353   PropRegistry prop_reg;
354   AccelFilterInterpreterTestInterpreter* base_interpreter =
355       new AccelFilterInterpreterTestInterpreter;
356   AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
357                                            nullptr);
358   TestInterpreterWrapper interpreter(&accel_interpreter);
359 
360   accel_interpreter.SetEventLoggingEnabled(true);
361   accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
362   accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
363   accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
364 
365   // Change the bounds for reasonable maximum Dt.  This will allow the filter
366   // to keep a large Dt without adjusting it.
367   accel_interpreter.max_reasonable_dt_.val_ = 1000;
368 
369   // Send the filter a Move with a large Dt and have the logic catch that it
370   // is too big.  This will not allow a fictitious Dt to be used but will
371   // just not apply gain to this specific gesture.
372   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
373                                                      1,  // start time
374                                                      1000, // end time
375                                                      0.0001,  // dx
376                                                      0));  // dy
377 
378   // Send the Move into AccelFilterInterpreter. The gesture should be dropped.
379   EXPECT_EQ(accel_interpreter.log_->size(), 0);
380   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
381   ASSERT_EQ(nullptr, out);
382 
383   // Encode the log into Json
384   Json::Value node;
385   Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
386 
387   // Verify the Json information
388   EXPECT_EQ(accel_interpreter.log_->size(), 3);
389   node = tree[ActivityLog::kKeyRoot][0];
390   EXPECT_EQ(node[ActivityLog::kKeyType],
391             Json::Value(ActivityLog::kKeyHardwareState));
392   node = tree[ActivityLog::kKeyRoot][1];
393   EXPECT_EQ(node[ActivityLog::kKeyType],
394             Json::Value(ActivityLog::kKeyGestureConsume));
395   node = tree[ActivityLog::kKeyRoot][2];
396   EXPECT_EQ(node[ActivityLog::kKeyType],
397             Json::Value(ActivityLog::kKeyAccelGestureDebug));
398   accel_interpreter.log_->Clear();
399 }
400 
TEST_F(AccelFilterInterpreterTest,TimingTest)401 TEST_F(AccelFilterInterpreterTest, TimingTest) {
402   AccelFilterInterpreterTestInterpreter* base_interpreter =
403       new AccelFilterInterpreterTestInterpreter;
404   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
405   TestInterpreterWrapper interpreter(&accel_interpreter);
406   accel_interpreter.scroll_x_out_scale_.val_ =
407       accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
408   accel_interpreter.min_reasonable_dt_.val_ = 0.0;
409   accel_interpreter.max_reasonable_dt_.val_ = INFINITY;
410 
411   accel_interpreter.pointer_sensitivity_.val_ = 3;  // standard sensitivity
412   accel_interpreter.scroll_sensitivity_.val_ = 3;  // standard sensitivity
413 
414   float last_dx = 0.0;
415   float last_dy = 0.0;
416 
417   base_interpreter->return_values_.push_back(Gesture());  // Null type
418   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
419                                                      1,  // start time
420                                                      1.001,  // end time
421                                                      -4,  // dx
422                                                      2.8));  // dy
423   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
424                                                      2,  // start time
425                                                      3,  // end time
426                                                      -4,  // dx
427                                                      2.8));  // dy
428   base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
429                                                      3,  // start time
430                                                      3.001,  // end time
431                                                      4.1,  // dx
432                                                      -10.3));  // dy
433   base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
434                                                      4,  // start time
435                                                      5,  // end time
436                                                      4.1,  // dx
437                                                      -10.3));  // dy
438 
439   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
440   ASSERT_EQ(nullptr, out);
441   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
442   ASSERT_NE(nullptr, out);
443   EXPECT_EQ(kGestureTypeMove, out->type);
444   // Expect less accel for same movement over more time
445   last_dx = out->details.move.dx;
446   last_dy = out->details.move.dy;
447   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
448   ASSERT_NE(nullptr, out);
449   EXPECT_EQ(kGestureTypeMove, out->type);
450   EXPECT_GT(fabsf(last_dx), fabsf(out->details.move.dx));
451   EXPECT_GT(fabsf(last_dy), fabsf(out->details.move.dy));
452 
453 
454   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
455   ASSERT_NE(nullptr, out);
456   EXPECT_EQ(kGestureTypeScroll, out->type);
457   // Expect less accel for same movement over more time
458   last_dx = out->details.scroll.dx;
459   last_dy = out->details.scroll.dy;
460   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
461   ASSERT_NE(nullptr, out);
462   EXPECT_EQ(kGestureTypeScroll, out->type);
463   EXPECT_GT(fabsf(last_dx), fabsf(out->details.scroll.dx));
464   EXPECT_GT(fabsf(last_dy), fabsf(out->details.scroll.dy));
465 }
466 
TEST_F(AccelFilterInterpreterTest,NotSmoothingTest)467 TEST_F(AccelFilterInterpreterTest, NotSmoothingTest) {
468   AccelFilterInterpreterTestInterpreter* base_interpreter =
469       new AccelFilterInterpreterTestInterpreter;
470   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
471   TestInterpreterWrapper interpreter(&accel_interpreter);
472   accel_interpreter.scroll_x_out_scale_.val_ =
473       accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
474   accel_interpreter.min_reasonable_dt_.val_ = 0.0;
475   accel_interpreter.max_reasonable_dt_.val_ = INFINITY;
476 
477   accel_interpreter.pointer_sensitivity_.val_ = 3;  // standard sensitivity
478   accel_interpreter.scroll_sensitivity_.val_ = 3;  // standard sensitivity
479 
480   accel_interpreter.smooth_accel_.val_ = false;
481 
482   float last_dx = 0.0;
483   float last_dy = 0.0;
484 
485   base_interpreter->return_values_.push_back(Gesture());  // Null type
486   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
487                                                      /*start=*/1,
488                                                      /*end=*/1.001,
489                                                      /*dx=*/-4,
490                                                      /*dy=*/2.8));
491   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
492                                                      /*start=*/2,
493                                                      /*end=*/3,
494                                                      /*dx=*/-4,
495                                                      /*dy=*/2.8));
496   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
497                                                      /*start=*/3,
498                                                      /*end=*/3.001,
499                                                      /*dx=*/4.1,
500                                                      /*dy=*/-10.3));
501   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
502                                                      /*start=*/4,
503                                                      /*end=*/5,
504                                                      /*dx=*/4.1,
505                                                      /*dy=*/-10.3));
506 
507   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
508   ASSERT_EQ(nullptr, out);
509   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
510   ASSERT_NE(nullptr, out);
511   EXPECT_EQ(kGestureTypeMove, out->type);
512   // Expect less accel for same movement over more time
513   last_dx = out->details.move.dx;
514   last_dy = out->details.move.dy;
515   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
516   ASSERT_NE(nullptr, out);
517   EXPECT_EQ(kGestureTypeMove, out->type);
518   EXPECT_GT(fabsf(last_dx), fabsf(out->details.move.dx));
519   EXPECT_GT(fabsf(last_dy), fabsf(out->details.move.dy));
520 
521   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
522   ASSERT_NE(nullptr, out);
523   EXPECT_EQ(kGestureTypeMove, out->type);
524   // Expect less accel for same movement over more time
525   last_dx = out->details.move.dx;
526   last_dy = out->details.move.dy;
527   ASSERT_GT(fabsf(last_dx), 32.5780);
528   ASSERT_LT(fabsf(last_dx), 32.5782);
529   ASSERT_GT(fabsf(last_dy), 81.8424);
530   ASSERT_LT(fabsf(last_dy), 81.8426);
531 
532   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
533   ASSERT_NE(nullptr, out);
534   EXPECT_EQ(kGestureTypeMove, out->type);
535   EXPECT_GT(fabsf(last_dx), fabsf(out->details.move.dx));
536   EXPECT_GT(fabsf(last_dy), fabsf(out->details.move.dy));
537 }
538 
TEST_F(AccelFilterInterpreterTest,SmoothingTest)539 TEST_F(AccelFilterInterpreterTest, SmoothingTest) {
540   AccelFilterInterpreterTestInterpreter* base_interpreter =
541       new AccelFilterInterpreterTestInterpreter;
542   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
543   TestInterpreterWrapper interpreter(&accel_interpreter);
544   accel_interpreter.scroll_x_out_scale_.val_ =
545       accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
546   accel_interpreter.min_reasonable_dt_.val_ = 0.0;
547   accel_interpreter.max_reasonable_dt_.val_ = INFINITY;
548 
549   accel_interpreter.pointer_sensitivity_.val_ = 3;  // standard sensitivity
550   accel_interpreter.scroll_sensitivity_.val_ = 3;  // standard sensitivity
551 
552   accel_interpreter.smooth_accel_.val_ = true;
553 
554   float last_dx = 0.0;
555   float last_dy = 0.0;
556 
557   base_interpreter->return_values_.push_back(Gesture());  // Null type
558   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
559                                                      /*start=*/1,
560                                                      /*end=*/1.001,
561                                                      /*dx=*/-4,
562                                                      /*dy=*/2.8));
563   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
564                                                      /*start=*/2,
565                                                      /*end=*/3,
566                                                      /*dx=*/-4,
567                                                      /*dy=*/2.8));
568   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
569                                                      /*start=*/3,
570                                                      /*end=*/3.001,
571                                                      /*dx=*/4.1,
572                                                      /*dy=*/-10.3));
573   base_interpreter->return_values_.push_back(Gesture(kGestureMove,
574                                                      /*start=*/4,
575                                                      /*end=*/5,
576                                                      /*dx=*/4.1,
577                                                      /*dy=*/-10.3));
578 
579   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
580   ASSERT_EQ(nullptr, out);
581   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
582   ASSERT_NE(nullptr, out);
583   EXPECT_EQ(kGestureTypeMove, out->type);
584   // Expect less accel for same movement over more time
585   last_dx = out->details.move.dx;
586   last_dy = out->details.move.dy;
587   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
588   ASSERT_NE(nullptr, out);
589   EXPECT_EQ(kGestureTypeMove, out->type);
590   EXPECT_GT(fabsf(last_dx), fabsf(out->details.move.dx));
591   EXPECT_GT(fabsf(last_dy), fabsf(out->details.move.dy));
592 
593   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
594   ASSERT_NE(nullptr, out);
595   EXPECT_EQ(kGestureTypeMove, out->type);
596   // Expect less accel for same movement over more time
597   last_dx = out->details.move.dx;
598   last_dy = out->details.move.dy;
599   ASSERT_GT(fabsf(last_dx), 32.3563);
600   ASSERT_LT(fabsf(last_dx), 32.3565);
601   ASSERT_GT(fabsf(last_dy), 81.2855);
602   ASSERT_LT(fabsf(last_dy), 81.2857);
603 
604   out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
605   ASSERT_NE(nullptr, out);
606   EXPECT_EQ(kGestureTypeMove, out->type);
607   EXPECT_GT(fabsf(last_dx), fabsf(out->details.move.dx));
608   EXPECT_GT(fabsf(last_dy), fabsf(out->details.move.dy));
609 }
610 
TEST_F(AccelFilterInterpreterTest,CurveSegmentInitializerTest)611 TEST_F(AccelFilterInterpreterTest, CurveSegmentInitializerTest) {
612   AccelFilterInterpreter::CurveSegment temp1 =
613       AccelFilterInterpreter::CurveSegment(INFINITY, 0.0, 2.0, -2.0);
614   AccelFilterInterpreter::CurveSegment temp2 =
615       AccelFilterInterpreter::CurveSegment(temp1);
616 
617   ASSERT_EQ(temp1.x_, temp2.x_);
618 
619   temp1 = AccelFilterInterpreter::CurveSegment(0.0, 0.0, 0.0, 0.0);
620   ASSERT_NE(temp1.x_, temp2.x_);
621 }
622 
TEST_F(AccelFilterInterpreterTest,CustomAccelTest)623 TEST_F(AccelFilterInterpreterTest, CustomAccelTest) {
624   AccelFilterInterpreterTestInterpreter* base_interpreter =
625       new AccelFilterInterpreterTestInterpreter;
626   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
627   TestInterpreterWrapper interpreter(&accel_interpreter);
628   accel_interpreter.scroll_x_out_scale_.val_ =
629       accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
630   accel_interpreter.min_reasonable_dt_.val_ = 0.0;
631   accel_interpreter.max_reasonable_dt_.val_ = INFINITY;
632 
633   // custom sensitivity
634   accel_interpreter.use_custom_tp_point_curve_.val_ = 1;
635   accel_interpreter.use_custom_tp_scroll_curve_.val_ = 1;
636   accel_interpreter.tp_custom_point_[0] =
637       AccelFilterInterpreter::CurveSegment(2.0, 0.0, 0.5, 0.0);
638   accel_interpreter.tp_custom_point_[1] =
639       AccelFilterInterpreter::CurveSegment(3.0, 0.0, 2.0, -3.0);
640   accel_interpreter.tp_custom_point_[2] =
641       AccelFilterInterpreter::CurveSegment(INFINITY, 0.0, 0.0, 3.0);
642   accel_interpreter.tp_custom_scroll_[0] =
643       AccelFilterInterpreter::CurveSegment(0.5, 0.0, 2.0, 0.0);
644   accel_interpreter.tp_custom_scroll_[1] =
645       AccelFilterInterpreter::CurveSegment(1.0, 0.0, 2.0, 0.0);
646   accel_interpreter.tp_custom_scroll_[2] =
647       AccelFilterInterpreter::CurveSegment(2.0, 0.0, 0.0, 2.0);
648   accel_interpreter.tp_custom_scroll_[3] =
649       AccelFilterInterpreter::CurveSegment(INFINITY, 0.0, 2.0, -2.0);
650 
651   float move_in[]  = { 1.0, 2.5, 3.5, 5.0 };
652   float move_out[] = { 0.5, 2.0, 3.0, 3.0 };
653 
654   for (size_t i = 0; i < arraysize(move_in); ++i) {
655     float dist = move_in[i];
656     float expected = move_out[i];
657     base_interpreter->return_values_.push_back(Gesture(kGestureMove,
658                                                        1,  // start time
659                                                        2,  // end time
660                                                        dist,  // dx
661                                                        0));  // dy
662     base_interpreter->return_values_.push_back(Gesture(kGestureMove,
663                                                        1,  // start time
664                                                        2,  // end time
665                                                        0,  // dx
666                                                        dist));  // dy
667     // half time, half distance = same speed
668     base_interpreter->return_values_.push_back(Gesture(kGestureMove,
669                                                        1,  // start time
670                                                        1.5,  // end time
671                                                        dist / 2.0,  // dx
672                                                        0));  // dy
673     base_interpreter->return_values_.push_back(Gesture(kGestureMove,
674                                                        1,  // start time
675                                                        1.5,  // end time
676                                                        0,  // dx
677                                                        dist / 2.0));  // dy
678 
679     Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
680     ASSERT_NE(nullptr, out) << "i=" << i;
681     EXPECT_EQ(kGestureTypeMove, out->type) << "i=" << i;
682     EXPECT_FLOAT_EQ(expected, out->details.move.dx) << "i=" << i;
683     EXPECT_FLOAT_EQ(0, out->details.move.dy) << "i=" << i;
684 
685     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
686     ASSERT_NE(nullptr, out) << "i=" << i;
687     EXPECT_EQ(kGestureTypeMove, out->type) << "i=" << i;
688     EXPECT_FLOAT_EQ(0, out->details.move.dx) << "i=" << i;
689     EXPECT_FLOAT_EQ(expected, out->details.move.dy) << "i=" << i;
690 
691     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
692     ASSERT_NE(nullptr, out) << "i=" << i;
693     EXPECT_EQ(kGestureTypeMove, out->type) << "i=" << i;
694     EXPECT_FLOAT_EQ(expected / 2.0, out->details.move.dx) << "i=" << i;
695     EXPECT_FLOAT_EQ(0, out->details.move.dy) << "i=" << i;
696 
697     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
698     ASSERT_NE(nullptr, out) << "i=" << i;
699     EXPECT_EQ(kGestureTypeMove, out->type) << "i=" << i;
700     EXPECT_FLOAT_EQ(0, out->details.move.dx) << "i=" << i;
701     EXPECT_FLOAT_EQ(expected / 2.0, out->details.move.dy) << "i=" << i;
702   }
703 
704   float swipe_in[]  = { 1.0, 2.5, 3.5, 5.0 };
705   float swipe_out[] = { 0.5, 2.0, 3.0, 3.0 };
706 
707   for (size_t i = 0; i < arraysize(swipe_in); ++i) {
708     float dist = swipe_in[i];
709     float expected = swipe_out[i];
710     base_interpreter->return_values_.push_back(Gesture(kGestureSwipe,
711                                                        1,  // start time
712                                                        2,  // end time
713                                                        dist,  // dx
714                                                        0));  // dy
715     base_interpreter->return_values_.push_back(Gesture(kGestureSwipe,
716                                                        1,  // start time
717                                                        2,  // end time
718                                                        0,  // dx
719                                                        dist));  // dy
720     // half time, half distance = same speed
721     base_interpreter->return_values_.push_back(Gesture(kGestureSwipe,
722                                                        1,  // start time
723                                                        1.5,  // end time
724                                                        dist / 2.0,  // dx
725                                                        0));  // dy
726     base_interpreter->return_values_.push_back(Gesture(kGestureSwipe,
727                                                        1,  // start time
728                                                        1.5,  // end time
729                                                        0,  // dx
730                                                        dist / 2.0));  // dy
731 
732     Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
733     ASSERT_NE(nullptr, out) << "i=" << i;
734     EXPECT_EQ(kGestureTypeSwipe, out->type) << "i=" << i;
735     EXPECT_FLOAT_EQ(expected, out->details.move.dx) << "i=" << i;
736     EXPECT_FLOAT_EQ(0, out->details.move.dy) << "i=" << i;
737 
738     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
739     ASSERT_NE(nullptr, out) << "i=" << i;
740     EXPECT_EQ(kGestureTypeSwipe, out->type) << "i=" << i;
741     EXPECT_FLOAT_EQ(0, out->details.move.dx) << "i=" << i;
742     EXPECT_FLOAT_EQ(expected, out->details.move.dy) << "i=" << i;
743 
744     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
745     ASSERT_NE(nullptr, out) << "i=" << i;
746     EXPECT_EQ(kGestureTypeSwipe, out->type) << "i=" << i;
747     EXPECT_FLOAT_EQ(expected / 2.0, out->details.move.dx) << "i=" << i;
748     EXPECT_FLOAT_EQ(0, out->details.move.dy) << "i=" << i;
749 
750     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
751     ASSERT_NE(nullptr, out) << "i=" << i;
752     EXPECT_EQ(kGestureTypeSwipe, out->type) << "i=" << i;
753     EXPECT_FLOAT_EQ(0, out->details.move.dx) << "i=" << i;
754     EXPECT_FLOAT_EQ(expected / 2.0, out->details.move.dy) << "i=" << i;
755   }
756 
757   float swipe4_in[]  = { 1.0, 2.5, 3.5, 5.0 };
758   float swipe4_out[] = { 0.5, 2.0, 3.0, 3.0 };
759 
760   for (size_t i = 0; i < arraysize(swipe4_in); ++i) {
761     float dist = swipe4_in[i];
762     float expected = swipe4_out[i];
763     base_interpreter->return_values_.push_back(Gesture(kGestureFourFingerSwipe,
764                                                        1,  // start time
765                                                        2,  // end time
766                                                        dist,  // dx
767                                                        0));  // dy
768     base_interpreter->return_values_.push_back(Gesture(kGestureFourFingerSwipe,
769                                                        1,  // start time
770                                                        2,  // end time
771                                                        0,  // dx
772                                                        dist));  // dy
773     // half time, half distance = same speed
774     base_interpreter->return_values_.push_back(Gesture(kGestureFourFingerSwipe,
775                                                        1,  // start time
776                                                        1.5,  // end time
777                                                        dist / 2.0,  // dx
778                                                        0));  // dy
779     base_interpreter->return_values_.push_back(Gesture(kGestureFourFingerSwipe,
780                                                        1,  // start time
781                                                        1.5,  // end time
782                                                        0,  // dx
783                                                        dist / 2.0));  // dy
784 
785     Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
786     ASSERT_NE(nullptr, out) << "i=" << i;
787     EXPECT_EQ(kGestureTypeFourFingerSwipe, out->type) << "i=" << i;
788     EXPECT_FLOAT_EQ(expected, out->details.move.dx) << "i=" << i;
789     EXPECT_FLOAT_EQ(0, out->details.move.dy) << "i=" << i;
790 
791     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
792     ASSERT_NE(nullptr, out) << "i=" << i;
793     EXPECT_EQ(kGestureTypeFourFingerSwipe, out->type) << "i=" << i;
794     EXPECT_FLOAT_EQ(0, out->details.move.dx) << "i=" << i;
795     EXPECT_FLOAT_EQ(expected, out->details.move.dy) << "i=" << i;
796 
797     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
798     ASSERT_NE(nullptr, out) << "i=" << i;
799     EXPECT_EQ(kGestureTypeFourFingerSwipe, out->type) << "i=" << i;
800     EXPECT_FLOAT_EQ(expected / 2.0, out->details.move.dx) << "i=" << i;
801     EXPECT_FLOAT_EQ(0, out->details.move.dy) << "i=" << i;
802 
803     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
804     ASSERT_NE(nullptr, out) << "i=" << i;
805     EXPECT_EQ(kGestureTypeFourFingerSwipe, out->type) << "i=" << i;
806     EXPECT_FLOAT_EQ(0, out->details.move.dx) << "i=" << i;
807     EXPECT_FLOAT_EQ(expected / 2.0, out->details.move.dy) << "i=" << i;
808   }
809 
810   float scroll_in[]  = { 0.25, 0.5, 0.75, 1.5, 2.5, 3.0, 3.5 };
811   float scroll_out[] = { 0.5,  1.0, 1.5,  2.0, 3.0, 4.0, 5.0 };
812 
813   for (size_t i = 0; i < arraysize(scroll_in); ++i) {
814     float dist = scroll_in[i];
815     float expected = scroll_out[i];
816     base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
817                                                        1,  // start time
818                                                        2,  // end time
819                                                        dist,  // dx
820                                                        0));  // dy
821     base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
822                                                        1,  // start time
823                                                        2,  // end time
824                                                        0,  // dx
825                                                        dist));  // dy
826     // half time, half distance = same speed
827     base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
828                                                        1,  // start time
829                                                        1.5,  // end time
830                                                        dist / 2.0,  // dx
831                                                        0));  // dy
832     base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
833                                                        1,  // start time
834                                                        1.5,  // end time
835                                                        0,  // dx
836                                                        dist / 2.0));  // dy
837 
838     Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
839     ASSERT_NE(nullptr, out) << "i=" << i;
840     EXPECT_EQ(kGestureTypeScroll, out->type) << "i=" << i;
841     EXPECT_FLOAT_EQ(expected, out->details.scroll.dx) << "i=" << i;
842     EXPECT_FLOAT_EQ(0, out->details.scroll.dy) << "i=" << i;
843 
844     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
845     ASSERT_NE(nullptr, out) << "i=" << i;
846     EXPECT_EQ(kGestureTypeScroll, out->type) << "i=" << i;
847     EXPECT_FLOAT_EQ(0, out->details.scroll.dx) << "i=" << i;
848     EXPECT_FLOAT_EQ(expected, out->details.scroll.dy) << "i=" << i;
849 
850     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
851     ASSERT_NE(nullptr, out) << "i=" << i;
852     EXPECT_EQ(kGestureTypeScroll, out->type) << "i=" << i;
853     EXPECT_FLOAT_EQ(expected / 2.0, out->details.scroll.dx) << "i=" << i;
854     EXPECT_FLOAT_EQ(0, out->details.scroll.dy) << "i=" << i;
855 
856     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
857     ASSERT_NE(nullptr, out) << "i=" << i;
858     EXPECT_EQ(kGestureTypeScroll, out->type) << "i=" << i;
859     EXPECT_FLOAT_EQ(0, out->details.scroll.dx) << "i=" << i;
860     EXPECT_FLOAT_EQ(expected / 2.0, out->details.scroll.dy) << "i=" << i;
861   }
862 }
863 
TEST_F(AccelFilterInterpreterTest,UnacceleratedMouseTest)864 TEST_F(AccelFilterInterpreterTest, UnacceleratedMouseTest) {
865   AccelFilterInterpreterTestInterpreter* base_interpreter =
866       new AccelFilterInterpreterTestInterpreter;
867   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
868   TestInterpreterWrapper interpreter(&accel_interpreter);
869 
870   accel_interpreter.use_mouse_point_curves_.val_ = true;
871   accel_interpreter.pointer_acceleration_.val_ = false;
872 
873   const float dx = 3;
874   const float dy = 5;
875   const float unaccel_slopes[] = { 2.0, 4.0, 8.0, 16.0, 24.0 };
876 
877   for (int i = 1; i <= 5; ++i) {
878     accel_interpreter.pointer_sensitivity_.val_ = i;
879 
880     base_interpreter->return_values_.push_back(Gesture());  // Null type
881     base_interpreter->return_values_.push_back(Gesture(kGestureMove,
882                                                        1,  // start time
883                                                        1.001,  // end time
884                                                        dx,  // dx
885                                                        dy));  // dy
886 
887     Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
888     ASSERT_EQ(nullptr, out);
889     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
890     ASSERT_NE(nullptr, out);
891     EXPECT_EQ(kGestureTypeMove, out->type);
892 
893     // Output should be scaled by a constant value.
894     EXPECT_FLOAT_EQ(dx * unaccel_slopes[i - 1], out->details.move.dx);
895     EXPECT_FLOAT_EQ(dy * unaccel_slopes[i - 1], out->details.move.dy);
896   }
897 }
898 
TEST_F(AccelFilterInterpreterTest,UnacceleratedTouchpadTest)899 TEST_F(AccelFilterInterpreterTest, UnacceleratedTouchpadTest) {
900   AccelFilterInterpreterTestInterpreter* base_interpreter =
901       new AccelFilterInterpreterTestInterpreter;
902   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
903   TestInterpreterWrapper interpreter(&accel_interpreter);
904 
905   accel_interpreter.use_mouse_point_curves_.val_ = false;
906   accel_interpreter.pointer_acceleration_.val_ = false;
907 
908   const float dx = 3;
909   const float dy = 5;
910   const float unaccel_slopes[] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
911 
912   for (int i = 1; i <= 5; ++i) {
913     accel_interpreter.pointer_sensitivity_.val_ = i;
914 
915     base_interpreter->return_values_.push_back(Gesture());  // Null type
916     base_interpreter->return_values_.push_back(Gesture(kGestureMove,
917                                                        1,  // start time
918                                                        1.001,  // end time
919                                                        dx,  // dx
920                                                        dy));  // dy
921 
922     Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
923     ASSERT_EQ(nullptr, out);
924     out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
925     ASSERT_NE(nullptr, out);
926     EXPECT_EQ(kGestureTypeMove, out->type);
927 
928     // Output should be scaled by a constant value.
929     EXPECT_FLOAT_EQ(dx * unaccel_slopes[i - 1], out->details.move.dx);
930     EXPECT_FLOAT_EQ(dy * unaccel_slopes[i - 1], out->details.move.dy);
931   }
932 }
933 
TEST_F(AccelFilterInterpreterTest,TouchpadPointAccelCurveTest)934 TEST_F(AccelFilterInterpreterTest, TouchpadPointAccelCurveTest) {
935   AccelFilterInterpreterTestInterpreter* base_interpreter =
936       new AccelFilterInterpreterTestInterpreter;
937   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
938   TestInterpreterWrapper interpreter(&accel_interpreter);
939 
940   size_t num_segs = AccelFilterInterpreter::kMaxCurveSegs;
941   AccelFilterInterpreter::CurveSegment* segs;
942 
943   // x = input speed of movement (mm/s, always >= 0), y = output speed (mm/s)
944   // Sensitivity: 1 No Acceleration
945   segs = accel_interpreter.point_curves_[0];
946 
947   float ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, 0);
948   ASSERT_EQ(ratio, 0.0);
949 
950   ASSERT_EQ(segs[0].x_, INFINITY);
951   ASSERT_EQ(segs[0].sqr_, 0.0);
952   ASSERT_EQ(segs[0].mul_, 1.0);
953   ASSERT_EQ(segs[0].int_, 0.0);
954   for (int x = 1; x < 1000; ++x) {
955     ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
956     float y = ratio * float(x);
957     ASSERT_EQ(x, y);
958   }
959 
960   // Sensitivity 2-5
961   const float point_divisors[] = {0.0, // unused
962                                   60.0, 37.5, 30.0, 25.0 };  // used
963 
964   for (int sensitivity = 2; sensitivity <= 5; ++sensitivity) {
965     segs = accel_interpreter.point_curves_[sensitivity - 1];
966     const float divisor = point_divisors[sensitivity - 1];
967 
968     ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, 0.0);
969     ASSERT_EQ(ratio, 0.0);
970 
971     ratio = accel_interpreter.RatioFromAccelCurve(segs, 1, INFINITY);
972     ASSERT_EQ(ratio, 0.0);
973 
974     //    y = 32x/divisor   (x < 32)
975     const float linear_until_x = 32.0;
976     ASSERT_EQ(segs[0].x_, linear_until_x);
977     ASSERT_EQ(segs[0].sqr_, 0.0);
978     ASSERT_EQ(segs[0].mul_, linear_until_x / divisor);
979     ASSERT_EQ(segs[0].int_, 0.0);
980     for (int i = 1; i < 32; ++i) {
981       float x = float(i);
982       ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
983       float y = x * ratio;
984       float expected = (linear_until_x * x) / divisor;
985       ASSERT_LE(expected - 0.001, y);
986       ASSERT_GE(expected + 0.001, y);
987     }
988 
989     //    y = x^2/divisor   (x < 150)
990     const float x_border = 150.0;
991     ASSERT_EQ(segs[1].x_, x_border);
992     ASSERT_EQ(segs[1].sqr_, 1 / divisor);
993     ASSERT_EQ(segs[1].mul_, 0.0);
994     ASSERT_EQ(segs[1].int_, 0.0);
995     for (int i = 33; i < 150; ++i) {
996       float x = float(i);
997       ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
998       float y = x * ratio;
999       float expected = (x * x) / divisor;
1000       ASSERT_LE(expected - 0.001, y);
1001       ASSERT_GE(expected + 0.001, y);
1002     }
1003 
1004     // linear with same slope after
1005     const float slope = (x_border * 2) / divisor;
1006     const float y_at_border = (x_border * x_border) / divisor;
1007     const float intercept = y_at_border - (slope * x_border);
1008     ASSERT_EQ(segs[2].x_, INFINITY);
1009     ASSERT_EQ(segs[2].sqr_, 0.0);
1010     ASSERT_EQ(segs[2].mul_, slope);
1011     ASSERT_EQ(segs[2].int_, intercept);
1012     for (int i = 150; i < 1000; ++i) {
1013       float x = float(i);
1014           // return seg.mul_ + seg.int_ / speed;;
1015       ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
1016       float y = x * ratio;
1017       float expected = x * (slope + (intercept / x));
1018       ASSERT_LE(expected - 0.001, y);
1019       ASSERT_GE(expected + 0.001, y);
1020     }
1021   }
1022 }
1023 
TEST_F(AccelFilterInterpreterTest,TouchpadScrollAccelCurveTest)1024 TEST_F(AccelFilterInterpreterTest, TouchpadScrollAccelCurveTest) {
1025   AccelFilterInterpreterTestInterpreter* base_interpreter =
1026       new AccelFilterInterpreterTestInterpreter;
1027   AccelFilterInterpreter accel_interpreter(nullptr, base_interpreter, nullptr);
1028   TestInterpreterWrapper interpreter(&accel_interpreter);
1029 
1030   size_t num_segs = AccelFilterInterpreter::kMaxCurveSegs;
1031   AccelFilterInterpreter::CurveSegment* segs;
1032 
1033   // x = input speed of movement (mm/s, always >= 0), y = output speed (mm/s)
1034   // Sensitivity: 1 No Acceleration
1035   segs = accel_interpreter.scroll_curves_[0];
1036 
1037   float ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, 0);
1038   ASSERT_EQ(ratio, 0.0);
1039 
1040   ASSERT_EQ(segs[0].x_, INFINITY);
1041   ASSERT_EQ(segs[0].sqr_, 0.0);
1042   ASSERT_EQ(segs[0].mul_, 1.0);
1043   ASSERT_EQ(segs[0].int_, 0.0);
1044   for (int x = 1; x < 1000; ++x) {
1045     ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
1046     float y = ratio * float(x);
1047     ASSERT_EQ(x, y);
1048   }
1049 
1050   // Sensitivity 2-5
1051   const float scroll_divisors[] = {0.0, // unused
1052                                    150, 75.0, 70.0, 65.0 };  // used
1053 
1054   for (int sensitivity = 2; sensitivity <= 5; ++sensitivity) {
1055     segs = accel_interpreter.scroll_curves_[sensitivity - 1];
1056     const float divisor = scroll_divisors[sensitivity - 1];
1057 
1058     ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, 0.0);
1059     ASSERT_EQ(ratio, 0.0);
1060 
1061     ratio = accel_interpreter.RatioFromAccelCurve(segs, 1, INFINITY);
1062     ASSERT_EQ(ratio, 0.0);
1063 
1064     //    y = 75x/divisor   (x < 75)
1065     const float linear_until_x = 75.0;
1066     ASSERT_EQ(segs[0].x_, linear_until_x);
1067     ASSERT_EQ(segs[0].sqr_, 0.0);
1068     ASSERT_EQ(segs[0].mul_, linear_until_x / divisor);
1069     ASSERT_EQ(segs[0].int_, 0.0);
1070     for (int i = 1; i < 75; ++i) {
1071       float x = float(i);
1072       ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
1073       float y = x * ratio;
1074       float expected = (linear_until_x * x) / divisor;
1075       ASSERT_LE(expected - 0.001, y);
1076       ASSERT_GE(expected + 0.001, y);
1077     }
1078 
1079     //    y = x^2/divisor   (x < 600)
1080     const float x_border = 600.0;
1081     ASSERT_EQ(segs[1].x_, x_border);
1082     ASSERT_EQ(segs[1].sqr_, 1 / divisor);
1083     ASSERT_EQ(segs[1].mul_, 0.0);
1084     ASSERT_EQ(segs[1].int_, 0.0);
1085     for (int i = 75; i < 600; ++i) {
1086       float x = float(i);
1087       ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
1088       float y = x * ratio;
1089       float expected = (x * x) / divisor;
1090       ASSERT_LE(expected - 0.001, y);
1091       ASSERT_GE(expected + 0.001, y);
1092     }
1093 
1094     // linear with same slope after
1095     const float slope = linear_until_x / divisor;
1096     const float y_at_border = (x_border * x_border) / divisor;
1097     const float intercept = y_at_border - (slope * x_border);
1098     ASSERT_EQ(segs[2].x_, INFINITY);
1099     ASSERT_EQ(segs[2].sqr_, 0.0);
1100     ASSERT_EQ(segs[2].mul_, slope);
1101     ASSERT_EQ(segs[2].int_, intercept);
1102     for (int i = 600; i < 1000; ++i) {
1103       float x = float(i);
1104       ratio = accel_interpreter.RatioFromAccelCurve(segs, num_segs, x);
1105       float y = x * ratio;
1106       float expected = x * (slope + (intercept / x));
1107       ASSERT_LE(expected - 0.001, y);
1108       ASSERT_GE(expected + 0.001, y);
1109     }
1110   }
1111 }
1112 
TEST_F(AccelFilterInterpreterTest,AccelDebugDataTest)1113 TEST_F(AccelFilterInterpreterTest, AccelDebugDataTest) {
1114   PropRegistry prop_reg;
1115   AccelFilterInterpreterTestInterpreter* base_interpreter =
1116       new AccelFilterInterpreterTestInterpreter;
1117   AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
1118                                            nullptr);
1119   TestInterpreterWrapper interpreter(&accel_interpreter);
1120 
1121   accel_interpreter.SetEventLoggingEnabled(true);
1122   accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
1123   accel_interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
1124   accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
1125   accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
1126 
1127   accel_interpreter.scroll_x_out_scale_.val_ =
1128       accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
1129 
1130   base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
1131                                                      2,  // start time
1132                                                      2.1,  // end time
1133                                                      4.1,  // dx
1134                                                      -10.3));  // dy
1135 
1136   Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
1137   ASSERT_NE(nullptr, out);
1138   EXPECT_EQ(kGestureTypeScroll, out->type);
1139 
1140   // Encode the log into Json
1141   Json::Value node;
1142   Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
1143 
1144   // Verify the Json information
1145   EXPECT_EQ(accel_interpreter.log_->size(), 5);
1146   node = tree[ActivityLog::kKeyRoot][0];
1147   EXPECT_EQ(node[ActivityLog::kKeyType],
1148             Json::Value(ActivityLog::kKeyHardwareState));
1149   node = tree[ActivityLog::kKeyRoot][1];
1150   EXPECT_EQ(node[ActivityLog::kKeyType],
1151             Json::Value(ActivityLog::kKeyGestureConsume));
1152   node = tree[ActivityLog::kKeyRoot][2];
1153   EXPECT_EQ(node[ActivityLog::kKeyType],
1154             Json::Value(ActivityLog::kKeyAccelGestureDebug));
1155   node = tree[ActivityLog::kKeyRoot][3];
1156   EXPECT_EQ(node[ActivityLog::kKeyType],
1157             Json::Value(ActivityLog::kKeyGestureProduce));
1158   node = tree[ActivityLog::kKeyRoot][4];
1159   EXPECT_EQ(node[ActivityLog::kKeyType],
1160             Json::Value(ActivityLog::kKeyGesture));
1161   accel_interpreter.log_->Clear();
1162 }
1163 
1164 }  // namespace gestures
1165