• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdio.h>
8 #include <vector>
9 #include <utility>
10 
11 #include <gtest/gtest.h>
12 
13 #include "include/gestures.h"
14 #include "include/palm_classifying_filter_interpreter.h"
15 #include "include/string_util.h"
16 #include "include/unittest_util.h"
17 #include "include/util.h"
18 
19 using std::deque;
20 using std::make_pair;
21 using std::pair;
22 using std::vector;
23 
24 namespace gestures {
25 
26 class PalmClassifyingFilterInterpreterTest : public ::testing::Test {};
27 
28 class PalmClassifyingFilterInterpreterTestInterpreter : public Interpreter {
29  public:
PalmClassifyingFilterInterpreterTestInterpreter()30   PalmClassifyingFilterInterpreterTestInterpreter()
31       : Interpreter(nullptr, nullptr, false),
32         expected_flags_(0) {}
33 
SyncInterpret(HardwareState & hwstate,stime_t * timeout)34   virtual void SyncInterpret(HardwareState& hwstate, stime_t* timeout) {
35     if (hwstate.finger_cnt > 0) {
36       EXPECT_EQ(expected_flags_, hwstate.fingers[0].flags);
37     }
38   }
39 
HandleTimer(stime_t now,stime_t * timeout)40   virtual void HandleTimer(stime_t now, stime_t* timeout) {
41     EXPECT_TRUE(false);
42   }
43 
44   unsigned expected_flags_;
45 };
46 
TEST(PalmClassifyingFilterInterpreterTest,PalmTest)47 TEST(PalmClassifyingFilterInterpreterTest, PalmTest) {
48   PalmClassifyingFilterInterpreter pci(nullptr, nullptr, nullptr);
49   HardwareProperties hwprops = {
50     .right = 1000,
51     .bottom = 1000,
52     .res_x = 500,
53     .res_y = 500,
54     .screen_x_dpi = 0,
55     .screen_y_dpi = 0,
56     .orientation_minimum = -1,
57     .orientation_maximum = 2,
58     .max_finger_cnt = 2,
59     .max_touch_cnt = 5,
60     .supports_t5r2 = 0,
61     .support_semi_mt = 0,
62     .is_button_pad = 1,
63     .has_wheel = 0,
64     .wheel_is_hi_res = 0,
65     .is_haptic_pad = 0,
66   };
67   TestInterpreterWrapper wrapper(&pci, &hwprops);
68 
69   const float kBig = pci.palm_pressure_.val_ + 1;  // big (palm) pressure
70   const float kSml = pci.palm_pressure_.val_ - 1;  // low pressure
71 
72   FingerState finger_states[] = {
73     // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID
74     {0, 0, 0, 0, kSml, 0, 600, 500, 1, 0},
75     {0, 0, 0, 0, kSml, 0, 500, 500, 2, 0},
76 
77     {0, 0, 0, 0, kSml, 0, 600, 500, 1, 0},
78     {0, 0, 0, 0, kBig, 0, 500, 500, 2, 0},
79 
80     {0, 0, 0, 0, kSml, 0, 600, 500, 1, 0},
81     {0, 0, 0, 0, kSml, 0, 500, 500, 2, 0},
82 
83     {0, 0, 0, 0, kSml, 0, 600, 500, 3, 0},
84     {0, 0, 0, 0, kBig, 0, 500, 500, 4, 0},
85 
86     {0, 0, 0, 0, kSml, 0, 600, 500, 3, 0},
87     {0, 0, 0, 0, kSml, 0, 500, 500, 4, 0}
88   };
89   HardwareState hardware_state[] = {
90     // time, buttons, finger count, touch count, finger states pointer
91     make_hwstate(200000, 0, 2, 2, &finger_states[0]),
92     make_hwstate(200001, 0, 2, 2, &finger_states[2]),
93     make_hwstate(200002, 0, 2, 2, &finger_states[4]),
94     make_hwstate(200003, 0, 2, 2, &finger_states[6]),
95     make_hwstate(200004, 0, 2, 2, &finger_states[8]),
96   };
97 
98   for (size_t i = 0; i < 5; ++i) {
99     wrapper.SyncInterpret(hardware_state[i], nullptr);
100     switch (i) {
101       case 0:
102         EXPECT_TRUE(SetContainsValue(pci.pointing_, 1));
103         EXPECT_FALSE(SetContainsValue(pci.palm_, 1));
104         EXPECT_TRUE(SetContainsValue(pci.pointing_, 2));
105         EXPECT_FALSE(SetContainsValue(pci.palm_, 2));
106         break;
107       case 1:  // fallthrough
108       case 2:
109         EXPECT_TRUE(SetContainsValue(pci.pointing_, 1));
110         EXPECT_FALSE(SetContainsValue(pci.palm_, 1));
111         EXPECT_FALSE(SetContainsValue(pci.pointing_, 2));
112         EXPECT_TRUE(SetContainsValue(pci.palm_, 2));
113         break;
114       case 3:  // fallthrough
115       case 4:
116         EXPECT_TRUE(SetContainsValue(pci.pointing_, 3)) << "i=" << i;
117         EXPECT_FALSE(SetContainsValue(pci.palm_, 3));
118         EXPECT_FALSE(SetContainsValue(pci.pointing_, 4));
119         EXPECT_TRUE(SetContainsValue(pci.palm_, 4));
120         break;
121     }
122   }
123 }
124 
TEST(PalmClassifyingFilterInterpreterTest,ExternallyMarkedPalmTest)125 TEST(PalmClassifyingFilterInterpreterTest, ExternallyMarkedPalmTest) {
126   PalmClassifyingFilterInterpreterTestInterpreter* base_interpreter =
127     new PalmClassifyingFilterInterpreterTestInterpreter;
128   PalmClassifyingFilterInterpreter pci(nullptr, base_interpreter, nullptr);
129   HardwareProperties hwprops = {
130     .right = 1000,
131     .bottom = 1000,
132     .res_x = 500,
133     .res_y = 500,
134     .screen_x_dpi = 0,
135     .screen_y_dpi = 0,
136     .orientation_minimum = -1,
137     .orientation_maximum = 2,
138     .max_finger_cnt = 2,
139     .max_touch_cnt = 5,
140     .supports_t5r2 = 0,
141     .support_semi_mt = 0,
142     .is_button_pad = 1,
143     .has_wheel = 0,
144     .wheel_is_hi_res = 0,
145     .is_haptic_pad = 0,
146   };
147 
148   TestInterpreterWrapper wrapper(&pci, &hwprops);
149 
150   const float kPr = pci.palm_pressure_.val_ / 2;
151 
152   FingerState finger_states[] = {
153     // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID, flags, ToolType
154     {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0},
155     {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0},
156     // mark the touch as palm
157     {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0, FingerState::ToolType::kPalm},
158     {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0, FingerState::ToolType::kPalm},
159   };
160   HardwareState hardware_state[] = {
161     // time, buttons, finger count, touch count, finger states pointer
162     make_hwstate(0.00, 0, 1, 1, &finger_states[0]),
163     make_hwstate(4.00, 0, 1, 1, &finger_states[1]),
164     make_hwstate(5.00, 0, 1, 1, &finger_states[2]),
165     make_hwstate(5.01, 0, 1, 1, &finger_states[3]),
166   };
167 
168   for (size_t i = 0; i < arraysize(hardware_state); ++i) {
169     SCOPED_TRACE(StringPrintf("i = %zu", i));
170     if(i > 1) {
171       base_interpreter->expected_flags_ = GESTURES_FINGER_PALM;
172     }
173     else {
174       base_interpreter->expected_flags_ = 0;
175     }
176     wrapper.SyncInterpret(hardware_state[i], nullptr);
177     if (i > 1) {
178       // After the second frame finger is marked as palm
179       EXPECT_FALSE(SetContainsValue(pci.pointing_, 1));
180       EXPECT_TRUE(SetContainsValue(pci.palm_, 1));
181     }
182     else {
183       EXPECT_TRUE(SetContainsValue(pci.pointing_, 1));
184       EXPECT_FALSE(SetContainsValue(pci.palm_, 1));
185     }
186   }
187 }
188 
TEST(PalmClassifyingFilterInterpreterTest,StationaryPalmTest)189 TEST(PalmClassifyingFilterInterpreterTest, StationaryPalmTest) {
190   PalmClassifyingFilterInterpreter pci(nullptr, nullptr, nullptr);
191   HardwareProperties hwprops = {
192     .right = 100,
193     .bottom = 100,
194     .res_x = 1,
195     .res_y = 1,
196     .screen_x_dpi = 0,
197     .screen_y_dpi = 0,
198     .orientation_minimum = -1,
199     .orientation_maximum = 2,
200     .max_finger_cnt = 5,
201     .max_touch_cnt = 5,
202     .supports_t5r2 = 0,
203     .support_semi_mt = 0,
204     .is_button_pad = 1,
205     .has_wheel = 0,
206     .wheel_is_hi_res = 0,
207     .is_haptic_pad = 0,
208   };
209   TestInterpreterWrapper wrapper(&pci, &hwprops);
210 
211   const float kPr = pci.palm_pressure_.val_ / 2;
212 
213   FingerState finger_states[] = {
214     // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID, flags
215     // Palm is id 1, finger id 2
216     {0, 0, 0, 0, kPr, 0,  0, 40, 1, 0},
217     {0, 0, 0, 0, kPr, 0, 60, 37, 2, 0},
218 
219     {0, 0, 0, 0, kPr, 0,  0, 40, 1, 0},
220     {0, 0, 0, 0, kPr, 0, 60, 40, 2, 0},
221 
222     {0, 0, 0, 0, kPr, 0,  0, 40, 1, 0},
223     {0, 0, 0, 0, kPr, 0, 60, 43, 2, 0},
224   };
225   HardwareState hardware_state[] = {
226     // time, buttons, finger count, touch count, finger states pointer
227     make_hwstate(0.00, 0, 1, 1, &finger_states[0]),
228     make_hwstate(4.00, 0, 2, 2, &finger_states[0]),
229     make_hwstate(5.00, 0, 2, 2, &finger_states[2]),
230     make_hwstate(5.01, 0, 2, 2, &finger_states[4]),
231   };
232 
233   for (size_t i = 0; i < arraysize(hardware_state); ++i) {
234     wrapper.SyncInterpret(hardware_state[i], nullptr);
235     if (i > 0) {
236       // We expect after the second input frame is processed that the palm
237       // is classified
238       EXPECT_FALSE(SetContainsValue(pci.pointing_, 1));
239       EXPECT_TRUE(SetContainsValue(pci.palm_, 1));
240     }
241     if (hardware_state[i].finger_cnt > 1)
242       EXPECT_TRUE(SetContainsValue(pci.pointing_, 2)) << "i=" << i;
243   }
244 }
245 
TEST(PalmClassifyingFilterInterpreterTest,PalmAtEdgeTest)246 TEST(PalmClassifyingFilterInterpreterTest, PalmAtEdgeTest) {
247   PalmClassifyingFilterInterpreterTestInterpreter* base_interpreter = nullptr;
248   std::unique_ptr<PalmClassifyingFilterInterpreter> pci(
249       new PalmClassifyingFilterInterpreter(nullptr, nullptr, nullptr));
250   HardwareProperties hwprops = {
251     .right = 100,
252     .bottom = 100,
253     .res_x = 1,
254     .res_y = 1,
255     .screen_x_dpi = 0,
256     .screen_y_dpi = 0,
257     .orientation_minimum = -1,
258     .orientation_maximum = 2,
259     .max_finger_cnt = 5,
260     .max_touch_cnt = 5,
261     .supports_t5r2 = 0,
262     .support_semi_mt = 0,
263     .is_button_pad = 1,
264     .has_wheel = 0,
265     .wheel_is_hi_res = 0,
266     .is_haptic_pad = 0,
267   };
268   TestInterpreterWrapper wrapper(pci.get(), &hwprops);
269 
270   const float kBig = pci->palm_pressure_.val_ + 1.0;  // palm pressure
271   const float kSml = pci->palm_pressure_.val_ - 1.0;  // small, low pressure
272   const float kMid = pci->palm_pressure_.val_ / 2.0;
273   const float kMidWidth =
274       (pci->palm_edge_min_width_.val_ + pci->palm_edge_width_.val_) / 2.0;
275 
276   const float kBigMove = pci->palm_pointing_min_dist_.val_ + 1.0;
277   const float kSmallMove = pci->palm_pointing_min_dist_.val_ - 1.0;
278 
279   FingerState finger_states[] = {
280     // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID
281     // small contact with small movement in edge
282     {0, 0, 0, 0, kSml, 0, 1, 40, 1, 0},
283     {0, 0, 0, 0, kSml, 0, 1, 40 + kSmallMove, 1, 0},
284     // small contact movement in middle
285     {0, 0, 0, 0, kSml, 0, 50, 40, 1, 0},
286     {0, 0, 0, 0, kSml, 0, 50, 50, 1, 0},
287     // large contact movment in middle
288     {0, 0, 0, 0, kBig, 0, 50, 40, 1, 0},
289     {0, 0, 0, 0, kBig, 0, 50, 50, 1, 0},
290     // under mid-pressure contact move at mid-width
291     {0, 0, 0, 0, kMid - 1.0f, 0, kMidWidth, 40, 1, 0},
292     {0, 0, 0, 0, kMid - 1.0f, 0, kMidWidth, 50, 1, 0},
293     // over mid-pressure contact move at mid-width with small movement
294     {0, 0, 0, 0, kMid + 1.0f, 0, kMidWidth, 40, 1, 0},
295     {0, 0, 0, 0, kMid + 1.0f, 0, kMidWidth, 40 + kSmallMove, 1, 0},
296     // small contact with large movement in edge
297     {0, 0, 0, 0, kSml, 0, 1, 40, 1, 0},
298     {0, 0, 0, 0, kSml, 0, 1, 40 + kBigMove, 1, 0},
299     // over mid-pressure contact move at mid-width with large movement
300     {0, 0, 0, 0, kMid + 1.0f, 0, kMidWidth, 40, 1, 0},
301     {0, 0, 0, 0, kMid + 1.0f, 0, kMidWidth, 40 + kBigMove, 1, 0},
302   };
303   HardwareState hardware_state[] = {
304     // time, buttons, finger count, touch count, finger states pointer
305     // slow movement at edge with small movement
306     make_hwstate(0.0, 0, 1, 1, &finger_states[0]),
307     make_hwstate(1.0, 0, 1, 1, &finger_states[1]),
308     // slow small contact movement in middle
309     make_hwstate(0.0, 0, 1, 1, &finger_states[2]),
310     make_hwstate(1.0, 0, 1, 1, &finger_states[3]),
311     // slow large contact movement in middle
312     make_hwstate(0.0, 0, 1, 1, &finger_states[4]),
313     make_hwstate(1.0, 0, 1, 1, &finger_states[5]),
314     // under mid-pressure at mid-width
315     make_hwstate(0.0, 0, 1, 1, &finger_states[6]),
316     make_hwstate(1.0, 0, 1, 1, &finger_states[7]),
317     // over mid-pressure at mid-width
318     make_hwstate(0.0, 0, 1, 1, &finger_states[8]),
319     make_hwstate(1.0, 0, 1, 1, &finger_states[9]),
320     // large movement at edge
321     make_hwstate(0.0, 0, 1, 1, &finger_states[10]),
322     make_hwstate(1.0, 0, 1, 1, &finger_states[11]),
323     // over mid-pressure at mid-width with large movement
324     make_hwstate(0.0, 0, 1, 1, &finger_states[12]),
325     make_hwstate(1.0, 0, 1, 1, &finger_states[13]),
326   };
327 
328   for (size_t i = 0; i < arraysize(hardware_state); ++i) {
329     if ((i % 2) == 0) {
330       base_interpreter = new PalmClassifyingFilterInterpreterTestInterpreter;
331       pci.reset(new PalmClassifyingFilterInterpreter(nullptr, base_interpreter,
332                                                      nullptr));
333       wrapper.Reset(pci.get());
334     }
335     switch (i) {
336       case 2:  // fallthough
337       case 3:
338       case 6:
339       case 7:
340         base_interpreter->expected_flags_ = 0;
341         break;
342       case 11:
343       case 13:
344         base_interpreter->expected_flags_ = GESTURES_FINGER_POSSIBLE_PALM;
345         break;
346       case 0:  // fallthrough
347       case 1:
348       case 8:
349       case 9:
350       case 10:
351       case 12:
352         base_interpreter->expected_flags_ = GESTURES_FINGER_PALM;
353         break;
354       case 4:
355       case 5:
356         base_interpreter->expected_flags_ =
357             (GESTURES_FINGER_PALM | GESTURES_FINGER_LARGE_PALM);
358         break;
359       default:
360         ADD_FAILURE() << "Should be unreached.";
361         break;
362     }
363     fprintf(stderr, "iteration i = %zd\n", i);
364     wrapper.SyncInterpret(hardware_state[i], nullptr);
365   }
366 }
367 
368 struct PalmReevaluateTestInputs {
369   stime_t now_;
370   float x_, y_, pressure_;
371 };
372 
373 // This tests that a palm that doesn't start out as a palm, but actually is,
374 // and can be classified as one shortly after it starts, doesn't cause motion.
TEST(PalmClassifyingFilterInterpreterTest,PalmReevaluateTest)375 TEST(PalmClassifyingFilterInterpreterTest, PalmReevaluateTest) {
376   PalmClassifyingFilterInterpreter pci(nullptr, nullptr, nullptr);
377   HardwareProperties hwprops = {
378     .right = 106.666672,
379     .bottom = 68.000000,
380     .res_x = 1,
381     .res_y = 1,
382     .screen_x_dpi = 0,
383     .screen_y_dpi = 0,
384     .orientation_minimum = -1,
385     .orientation_maximum = 2,
386     .max_finger_cnt = 15,
387     .max_touch_cnt = 5,
388     .supports_t5r2 = 0,
389     .support_semi_mt = 0,
390     .is_button_pad = true,
391     .has_wheel = 0,
392     .wheel_is_hi_res = 0,
393     .is_haptic_pad = false,
394   };
395   TestInterpreterWrapper wrapper(&pci, &hwprops);
396 
397   PalmReevaluateTestInputs inputs[] = {
398     { 5.8174, 10.25, 46.10,  15.36 },
399     { 5.8277, 10.25, 46.10,  21.18 },
400     { 5.8377, 10.25, 46.10,  19.24 },
401     { 5.8479,  9.91, 45.90,  15.36 },
402     { 5.8578,  9.08, 44.90,  19.24 },
403     { 5.8677,  9.08, 44.90,  28.94 },
404     { 5.8777,  8.66, 44.70,  61.93 },
405     { 5.8879,  8.41, 44.60,  58.04 },
406     { 5.8973,  8.08, 44.20,  73.57 },
407     { 5.9073,  7.83, 44.20,  87.15 },
408     { 5.9171,  7.50, 44.40,  89.09 },
409     { 5.9271,  7.25, 44.20,  87.15 },
410     { 5.9369,  7.00, 44.40,  83.27 },
411     { 5.9466,  6.33, 44.60,  89.09 },
412     { 5.9568,  6.00, 44.70,  85.21 },
413     { 5.9666,  5.75, 44.70,  87.15 },
414     { 5.9763,  5.41, 44.79,  75.51 },
415     { 5.9862,  5.08, 45.20,  75.51 },
416     { 5.9962,  4.50, 45.50,  75.51 },
417     { 6.0062,  4.41, 45.79,  81.33 },
418     { 6.0160,  4.08, 46.40,  77.45 },
419     { 6.0263,  3.83, 46.90,  91.03 },
420     { 6.0363,  3.58, 47.50,  98.79 },
421     { 6.0459,  3.25, 47.90, 114.32 },
422     { 6.0560,  3.25, 47.90, 149.24 },
423     { 6.0663,  3.33, 48.10, 170.59 },
424     { 6.0765,  3.50, 48.29, 180.29 },
425     { 6.0866,  3.66, 48.40, 188.05 },
426     { 6.0967,  3.83, 48.50, 188.05 },
427     { 6.1067,  3.91, 48.79, 182.23 },
428     { 6.1168,  4.00, 48.79, 180.29 },
429     { 6.1269,  4.08, 48.79, 180.29 },
430     { 6.1370,  4.16, 48.90, 176.41 },
431     { 6.1473,  4.25, 49.20, 162.82 },
432     { 6.1572,  4.58, 51.00, 135.66 },
433     { 6.1669,  4.66, 51.00, 114.32 },
434     { 6.1767,  4.66, 51.40,  73.57 },
435     { 6.1868,  4.66, 52.00,  40.58 },
436     { 6.1970,  4.66, 52.40,  21.18 },
437     { 6.2068,  6.25, 51.90,  13.42 },
438   };
439   for (size_t i = 0; i < arraysize(inputs); i++) {
440     FingerState fs =
441         { 0, 0, 0, 0, inputs[i].pressure_, 0.0,
442           inputs[i].x_, inputs[i].y_, 1, 0 };
443     HardwareState hs = make_hwstate(inputs[i].now_, 0, 1, 1, &fs);
444 
445     stime_t timeout = NO_DEADLINE;
446     wrapper.SyncInterpret(hs, &timeout);
447     // Allow movement at first:
448     stime_t age = inputs[i].now_ - inputs[0].now_;
449     if (age < pci.palm_eval_timeout_.val_)
450       continue;
451     EXPECT_FALSE(SetContainsValue(pci.pointing_, 1));
452   }
453 }
454 
455 namespace {
456 struct LargeTouchMajorTestInputs {
457   stime_t now_;
458   float touch_major_, x_, y_, pressure_;
459 };
460 }  // namespace {}
461 
TEST(PalmClassifyingFilterInterpreterTest,LargeTouchMajorTest)462 TEST(PalmClassifyingFilterInterpreterTest, LargeTouchMajorTest) {
463   PalmClassifyingFilterInterpreterTestInterpreter* base_interpreter =
464       new PalmClassifyingFilterInterpreterTestInterpreter;
465   PalmClassifyingFilterInterpreter pci(nullptr, base_interpreter, nullptr);
466   HardwareProperties hwprops = {
467     .right = 100,
468     .bottom = 100,
469     .res_x = 1,
470     .res_y = 1,
471     .screen_x_dpi = 0,
472     .screen_y_dpi = 0,
473     .orientation_minimum = -1,
474     .orientation_maximum = 2,
475     .max_finger_cnt = 5,
476     .max_touch_cnt = 5,
477     .supports_t5r2 = 0,
478     .support_semi_mt = 0,
479     .is_button_pad = 1,
480     .has_wheel = 0,
481     .wheel_is_hi_res = 0,
482     .is_haptic_pad = 0,
483   };
484   TestInterpreterWrapper wrapper(&pci, &hwprops);
485 
486   LargeTouchMajorTestInputs inputs[] = {
487     { 658.0355, 22.73, 29.1, 29.1, 140.6 },
488     { 658.0475, 22.73, 29.1, 29.1, 140.6 },
489     { 658.0652, 23.51, 29.1, 29.1, 118.1 },
490     { 658.0827, 22.73, 29.1, 29.1, 161.7 },
491     { 658.1002, 20.20, 29.1, 29.1, 156.4 },
492     { 658.1171, 21.95, 29.2, 29.5, 144.5 },
493     { 658.1344, 25.06, 29.2, 29.9, 157.8 },
494     { 658.1513, 26.42, 28.9, 30.0, 144.5 },
495     { 658.1687, 22.73, 28.9, 29.8, 120.7 },
496     { 658.1856, 25.06, 28.9, 30.1, 159.1 },
497     { 658.2033, 23.51, 28.9, 30.3, 174.9 },
498     { 658.2204, 22.73, 28.9, 30.1, 161.7 },
499     { 658.2378, 17.28, 29.6, 30.1, 144.5 },
500     { 658.2561, 21.95, 29.9, 32.0, 144.5 },
501     { 658.2737, 20.20, 30.2, 30.7, 144.5 },
502     { 658.2907, 16.21, 31.4, 30.7, 145.9 },
503     { 658.3079, 22.73, 30.7, 32.6, 148.5 },
504     { 658.3259, 21.07, 30.8, 30.5, 124.7 },
505     { 658.3437, 22.73, 30.7, 30.4, 147.2 },
506     { 658.3613, 21.95, 30.6, 32.7, 141.9 },
507     { 658.3782, 25.74, 30.2, 32.6, 148.5 },
508     { 658.3954, 25.74, 29.3, 31.9, 151.2 },
509     { 658.4135, 25.06, 28.2, 34.9, 147.2 },
510     { 658.4307, 25.06, 28.9, 29.1, 141.9 },
511     { 658.4476, 25.74, 29.0, 31.7, 145.9 },
512     { 658.4642, 25.74, 29.0, 32.0, 151.2 },
513     { 658.4811, 29.15, 27.6, 32.7, 141.9 },
514     { 658.4984, 27.11, 27.5, 32.2, 148.5 },
515     { 658.5150, 25.06, 27.9, 32.3, 148.5 },
516     { 658.5322, 27.11, 27.8, 32.2, 147.2 },
517     { 658.5494, 27.79, 27.8, 32.1, 151.2 },
518     { 658.5667, 20.20, 28.5, 31.2, 123.4 },
519     { 658.5846, 25.06, 28.6, 31.4, 161.7 },
520     { 658.6022, 21.07, 29.3, 30.5, 126.0 },
521     { 658.6195, 25.74, 29.2, 30.9, 152.5 },
522     { 658.6372, 29.15, 27.8, 32.0, 151.2 },
523     { 658.6547, 29.73, 27.1, 32.6, 145.9 },
524     { 658.6724, 25.06, 27.5, 32.7, 176.3 },
525     { 658.6910, 27.79, 27.4, 32.4, 141.9 },
526     { 658.7081, 27.11, 27.5, 32.2, 141.9 },
527     { 658.7263, 27.79, 27.4, 32.2, 147.2 },
528     { 658.7428, 27.11, 27.3, 32.2, 145.9 },
529     { 658.7601, 25.74, 27.5, 32.2, 148.5 },
530     { 658.7780, 16.21, 29.0, 31.8, 147.2 },
531     { 658.7956, 25.74, 29.0, 31.9, 152.5 },
532     { 658.8132, 21.07, 29.4, 31.1, 145.9 },
533     { 658.8311, 27.79, 29.0, 31.1, 145.9 },
534     { 658.8493, 25.74, 28.9, 31.3, 147.2 },
535     { 658.8666, 24.28, 29.0, 31.3, 147.2 },
536     { 658.8840, 25.06, 29.0, 31.1, 147.2 },
537     { 658.9014, 29.15, 28.7, 31.0, 152.5 },
538     { 658.9138, 29.15, 28.7, 31.0, 152.5 },
539     { 658.9309, 27.79, 28.6, 31.0, 152.5 },
540     { 658.9491, 25.06, 28.6, 31.1, 148.5 },
541     { 658.9667, 27.79, 28.5, 31.1, 152.5 },
542     { 658.9847, 25.74, 28.5, 31.2, 143.2 },
543     { 659.0022, 25.74, 28.6, 31.3, 149.8 },
544     { 659.0193, 20.20, 28.8, 30.9, 122.1 },
545     { 659.0371, 29.73, 28.1, 31.6, 151.2 },
546     { 659.0550, 21.07, 29.2, 30.2, 145.9 },
547     { 659.0728, 16.21, 31.3, 30.5, 145.9 },
548     { 659.0911, 27.79, 27.2, 31.8, 127.4 },
549     { 659.1092, 26.42, 27.6, 31.4, 180.2 },
550     { 659.1275, 23.51, 29.8, 34.1, 148.5 },
551     { 659.1444, 25.74, 29.3, 33.4, 141.9 },
552     { 659.1631, 25.74, 29.2, 33.1, 152.5 },
553     { 659.1808, 25.74, 29.2, 33.0, 149.8 },
554     { 659.1986, 21.95, 28.1, 29.9, 165.7 },
555     { 659.2168, 27.11, 27.8, 30.4, 148.5 },
556     { 659.2346, 27.11, 27.8, 30.6, 149.8 },
557     { 659.2521, 29.73, 27.2, 31.5, 153.8 },
558     { 659.2699, 25.06, 27.6, 31.8, 152.5 },
559     { 659.2869, 25.74, 28.0, 32.0, 152.5 },
560     { 659.3041, 23.51, 28.4, 32.5, 143.2 },
561     { 659.3223, 25.74, 28.5, 32.5, 149.8 },
562     { 659.3402, 23.51, 28.5, 31.6, 147.2 },
563     { 659.3583, 24.28, 28.7, 31.6, 152.5 },
564     { 659.3756, 27.79, 28.6, 31.6, 149.8 },
565     { 659.3933, 29.15, 28.3, 31.7, 164.4 },
566     { 659.4100, 25.74, 28.4, 31.8, 152.5 },
567     { 659.4276, 29.73, 27.9, 32.2, 145.9 },
568     { 659.4449, 23.51, 28.8, 33.1, 148.5 },
569     { 659.4617, 25.74, 28.8, 33.0, 151.2 },
570     { 659.4785, 25.74, 28.9, 33.0, 152.5 },
571     { 659.4963, 29.15, 28.6, 33.0, 181.6 },
572     { 659.5135, 20.20, 29.7, 32.6, 149.8 },
573     { 659.5303, 29.15, 28.9, 32.6, 152.5 },
574     { 659.5482, 26.42, 28.5, 34.1, 126.0 },
575     { 659.5661, 25.74, 28.7, 33.7, 127.4 },
576     { 659.5839, 22.73, 29.1, 33.6, 151.2 },
577     { 659.6017, 25.74, 29.1, 33.5, 149.8 },
578     { 659.6198, 27.79, 28.8, 33.1, 143.2 },
579     { 659.6382, 26.42, 28.6, 32.6, 182.9 },
580     { 659.6548, 25.06, 28.7, 32.6, 163.0 },
581     { 659.6726, 25.74, 28.7, 32.6, 149.8 },
582     { 659.6898, 25.06, 28.7, 32.6, 143.2 },
583     { 659.7072, 25.74, 28.7, 32.6, 152.5 },
584     { 659.7248, 27.79, 28.7, 32.5, 156.4 },
585     { 659.7421, 25.74, 28.7, 32.5, 178.9 },
586     { 659.7586, 25.74, 28.7, 32.5, 153.8 },
587     { 659.7774, 27.79, 28.6, 32.5, 149.8 },
588     { 659.7950, 25.74, 28.7, 32.5, 143.2 },
589     { 659.8126, 25.74, 28.7, 32.5, 151.2 },
590     { 659.8304, 24.28, 28.8, 32.6, 153.8 },
591     { 659.8477, 29.15, 28.6, 32.6, 128.7 },
592     { 659.8655, 27.79, 28.5, 32.9, 130.0 },
593     { 659.8827, 25.74, 28.5, 32.9, 165.7 },
594     { 659.9001, 27.79, 28.4, 32.7, 149.8 },
595     { 659.9179, 27.79, 28.3, 32.5, 148.5 },
596     { 659.9351, 25.06, 28.5, 31.9, 149.8 },
597     { 659.9530, 25.74, 28.6, 31.9, 149.8 },
598     { 659.9701, 29.73, 28.1, 32.2, 151.2 },
599     { 659.9874, 27.79, 28.0, 32.1, 143.2 },
600     { 660.0051, 25.74, 28.1, 32.2, 141.9 },
601     { 660.0227, 25.74, 28.2, 32.2, 152.5 },
602     { 660.0403, 23.51, 28.7, 32.7, 151.2 },
603     { 660.0576, 27.79, 28.5, 32.5, 147.2 },
604     { 660.0755, 25.74, 28.5, 32.5, 178.9 },
605     { 660.0930, 22.73, 29.1, 31.9, 127.4 },
606     { 660.1101, 22.73, 29.5, 31.4, 149.8 },
607     { 660.1273, 27.79, 29.2, 31.3, 128.7 },
608     { 660.1449, 24.28, 29.2, 31.4, 151.2 },
609     { 660.1632, 28.47, 29.0, 31.5, 151.2 },
610     { 660.1803, 25.06, 29.0, 31.2, 149.8 },
611     { 660.1992, 23.51, 29.4, 32.2, 147.2 },
612     { 660.2168, 22.73, 29.6, 32.9, 149.8 },
613     { 660.2350, 22.73, 30.1, 31.8, 151.2 },
614     { 660.2524, 25.74, 29.9, 32.0, 145.9 },
615     { 660.2708, 29.73, 28.0, 32.7, 174.9 },
616     { 660.2883, 27.79, 27.9, 32.3, 151.2 },
617     { 660.3063, 25.74, 28.1, 32.3, 151.2 },
618     { 660.3232, 25.74, 28.2, 32.4, 153.8 },
619     { 660.3401, 25.74, 28.3, 32.4, 160.4 },
620     { 660.3576, 24.28, 28.5, 32.6, 153.8 },
621     { 660.3748, 27.79, 28.4, 32.5, 151.2 },
622     { 660.3920, 25.74, 28.5, 32.5, 155.1 },
623     { 660.4099, 23.51, 28.5, 31.8, 148.5 },
624     { 660.4280, 25.74, 28.6, 31.9, 151.2 },
625     { 660.4448, 25.74, 28.6, 32.0, 127.4 },
626     { 660.4612, 25.74, 28.7, 32.0, 151.2 },
627     { 660.4799, 25.06, 28.7, 32.1, 164.4 },
628     { 660.4971, 25.74, 28.7, 32.1, 148.5 },
629     { 660.5155, 29.15, 28.5, 32.1, 168.3 },
630     { 660.5334, 27.79, 28.5, 32.1, 151.2 },
631     { 660.5507, 25.74, 28.5, 32.1, 156.4 },
632     { 660.5690, 25.06, 28.5, 32.1, 145.9 },
633     { 660.5868, 23.51, 28.8, 32.5, 140.6 },
634     { 660.6049, 25.74, 28.8, 32.5, 155.1 },
635     { 660.6217, 25.74, 28.8, 32.6, 152.5 },
636     { 660.6394, 27.79, 28.8, 32.5, 141.9 },
637     { 660.6571, 23.51, 29.0, 32.8, 145.9 },
638     { 660.6749, 29.73, 28.4, 33.0, 145.9 },
639     { 660.6924, 25.06, 28.5, 32.9, 151.2 },
640     { 660.7088, 25.74, 28.6, 32.9, 153.8 },
641     { 660.7268, 24.28, 28.7, 32.7, 152.5 },
642     { 660.7443, 25.74, 28.7, 32.7, 152.5 },
643     { 660.7617, 25.74, 28.7, 32.7, 157.8 },
644     { 660.7790, 23.51, 28.9, 33.0, 152.5 },
645     { 660.7969, 25.74, 28.9, 33.0, 135.3 },
646     { 660.8136, 25.74, 29.0, 32.9, 128.7 },
647     { 660.8308, 25.74, 29.0, 32.9, 136.6 },
648     { 660.8489, 20.20, 29.4, 32.7, 151.2 },
649     { 660.8664, 25.06, 28.6, 31.3, 152.5 },
650     { 660.8837, 23.51, 29.2, 32.4, 153.8 },
651     { 660.9014, 25.74, 29.2, 32.5, 152.5 },
652     { 660.9190, 27.79, 28.9, 32.4, 148.5 },
653     { 660.9358, 24.28, 29.2, 32.7, 155.1 },
654     { 660.9523, 25.74, 29.2, 32.6, 149.8 },
655     { 660.9698, 25.74, 29.2, 32.6, 155.1 },
656     { 660.9872, 24.28, 29.3, 32.7, 152.5 },
657     { 661.0051, 25.74, 29.3, 32.7, 132.6 },
658     { 661.0233, 29.15, 28.9, 32.5, 147.2 },
659     { 661.0404, 22.73, 29.3, 32.0, 153.8 },
660     { 661.0584, 29.73, 28.3, 32.5, 152.5 },
661     { 661.0758, 25.74, 28.4, 32.5, 156.4 },
662     { 661.0940, 18.35, 30.9, 31.1, 155.1 },
663     { 661.1123, 18.35, 31.9, 30.5, 155.1 },
664     { 661.1302, 23.51, 29.9, 32.9, 193.5 },
665     { 661.1471, 24.28, 30.0, 33.4, 127.4 },
666     { 661.1657, 25.06, 29.6, 33.6, 151.2 },
667     { 661.1836, 26.42, 29.0, 32.4, 155.1 },
668     { 661.2009, 25.74, 29.1, 32.5, 156.4 },
669     { 661.2189, 25.74, 28.9, 32.1, 178.9 },
670     { 661.2368, 29.15, 28.4, 32.2, 151.2 },
671     { 661.2543, 23.51, 29.2, 33.1, 127.4 },
672     { 661.2720, 25.74, 29.1, 33.1, 151.2 },
673     { 661.2894, 27.79, 28.9, 32.7, 132.6 },
674     { 661.3069, 22.73, 29.4, 32.0, 152.5 },
675     { 661.3249, 23.51, 30.0, 33.2, 151.2 },
676     { 661.3432, 25.74, 29.3, 35.1, 153.8 },
677     { 661.3600, 25.74, 29.3, 34.2, 155.1 },
678     { 661.3775, 27.79, 28.6, 32.9, 156.4 },
679     { 661.3947, 25.74, 28.7, 32.9, 181.6 },
680     { 661.4111, 24.28, 29.0, 33.1, 130.0 },
681     { 661.4299, 27.79, 28.7, 32.7, 151.2 },
682     { 661.4471, 25.74, 28.7, 32.7, 153.8 },
683     { 661.4648, 25.74, 28.8, 32.6, 153.8 },
684     { 661.4820, 27.79, 28.7, 32.5, 147.2 },
685     { 661.4999, 27.79, 28.6, 32.4, 152.5 },
686     { 661.5167, 25.74, 28.6, 32.4, 167.0 },
687     { 661.5334, 25.74, 28.7, 32.4, 152.5 },
688     { 661.5498, 24.28, 28.8, 32.5, 151.2 },
689     { 661.5680, 25.06, 28.9, 32.1, 136.6 },
690     { 661.5863, 25.06, 29.0, 31.7, 151.2 },
691     { 661.6037, 25.74, 29.0, 31.8, 132.6 },
692     { 661.6218, 25.74, 29.0, 31.8, 155.1 },
693     { 661.6386, 25.74, 29.1, 31.9, 144.5 },
694     { 661.6562, 20.20, 29.5, 31.8, 151.2 },
695     { 661.6739, 25.74, 29.4, 31.9, 155.1 },
696     { 661.6907, 22.73, 29.5, 32.2, 155.1 },
697     { 661.7087, 20.20, 30.2, 32.1, 155.1 },
698     { 661.7256, 24.28, 30.2, 32.4, 152.5 },
699     { 661.7429, 24.28, 30.1, 32.3, 153.8 },
700     { 661.7605, 25.74, 30.1, 32.4, 156.4 },
701     { 661.7775, 25.74, 30.0, 32.4, 159.1 },
702     { 661.7956, 25.74, 30.0, 32.4, 151.2 },
703     { 661.8128, 24.28, 30.0, 32.5, 152.5 },
704     { 661.8301, 24.28, 29.3, 31.6, 151.2 },
705     { 661.8480, 22.73, 29.3, 31.6, 161.7 },
706     { 661.8634, 16.21, 29.3, 30.8, 151.2 },
707     { 661.8793, 18.35, 28.3, 29.6, 141.9 },
708     { 661.8893, 18.35, 28.3, 29.6, 141.9 },
709     { 661.8969, 18.35, 28.3, 29.6, 141.9 },
710     { 661.9044, 18.35, 28.3, 29.6, 141.9 },
711     { 661.9111, 18.35, 28.3, 29.6, 141.9 }
712   };
713 
714   for (size_t i = 0; i < arraysize(inputs); i++) {
715     const LargeTouchMajorTestInputs& input = inputs[i];
716     FingerState fs = {
717       input.touch_major_, 0, 0, 0, input.pressure_, 0, input.x_, input.y_, 1, 0
718     };
719     HardwareState hs = make_hwstate(input.now_, 0, 1, 1, &fs);
720     base_interpreter->expected_flags_ =
721         (GESTURES_FINGER_PALM | GESTURES_FINGER_LARGE_PALM);
722     wrapper.SyncInterpret(hs, nullptr);
723   }
724 }
725 
726 }  // namespace gestures
727