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