• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <deque>
6 #include <math.h>
7 #include <vector>
8 #include <utility>
9 
10 #include <gtest/gtest.h>
11 
12 #include "include/gestures.h"
13 #include "include/sensor_jump_filter_interpreter.h"
14 #include "include/unittest_util.h"
15 
16 using std::deque;
17 using std::make_pair;
18 using std::pair;
19 using std::vector;
20 
21 namespace gestures {
22 
23 class SensorJumpFilterInterpreterTest : public ::testing::Test {};
24 
25 class SensorJumpFilterInterpreterTestInterpreter : public Interpreter {
26  public:
SensorJumpFilterInterpreterTestInterpreter()27   SensorJumpFilterInterpreterTestInterpreter()
28       : Interpreter(NULL, NULL, false),
29         handle_timer_called_(false),
30         expected_finger_cnt_(-1) {}
31 
SyncInterpret(HardwareState * hwstate,stime_t * timeout)32   virtual void SyncInterpret(HardwareState* hwstate, stime_t* timeout) {
33     if (expected_finger_cnt_ >= 0) {
34       EXPECT_NE(static_cast<HardwareState*>(NULL), hwstate);
35       EXPECT_EQ(1, hwstate->finger_cnt);
36       prev_ = hwstate->fingers[0];
37     }
38   }
39 
HandleTimer(stime_t now,stime_t * timeout)40   virtual void HandleTimer(stime_t now, stime_t* timeout) {
41     handle_timer_called_ = true;
42   }
43 
44   FingerState prev_;
45   bool handle_timer_called_;
46   short expected_finger_cnt_;
47 };
48 
49 struct InputAndExpectedWarp {
50   float val;
51   bool warp;
52 };
53 
TEST(SensorJumpFilterInterpreterTest,SimpleTest)54 TEST(SensorJumpFilterInterpreterTest, SimpleTest) {
55   SensorJumpFilterInterpreterTestInterpreter* base_interpreter =
56       new SensorJumpFilterInterpreterTestInterpreter;
57   SensorJumpFilterInterpreter interpreter(NULL, base_interpreter, NULL);
58 
59   base_interpreter->expected_finger_cnt_ = 1;
60   interpreter.enabled_.val_ = 1;
61 
62   HardwareProperties hwprops = {
63     0, 0, 100, 100,  // left, top, right, bottom
64     1, 1,  // x res (pixels/mm), y res (pixels/mm)
65     1, 1,  // scrn DPI X, Y
66     -1,  // orientation minimum
67     2,   // orientation maximum
68     5, 5,  // max fingers, max_touch
69     0, 0, 1,  // t5r2, semi, button pad
70     0, 0,  // has wheel, vertical wheel is high resolution
71     0,  // haptic pad
72   };
73   TestInterpreterWrapper wrapper(&interpreter, &hwprops);
74 
75   EXPECT_FALSE(base_interpreter->handle_timer_called_);
76   wrapper.HandleTimer(0.0, NULL);
77   EXPECT_TRUE(base_interpreter->handle_timer_called_);
78 
79   FingerState fs = { 0, 0, 0, 0, 1, 0, 3.0, 0.0, 1, 0 };
80   HardwareState hs = make_hwstate(0.0, 0, 1, 1, &fs);
81 
82   InputAndExpectedWarp data[] = {
83     { 3.0, false },
84     { 4.0, false },
85     { 3.0, true },  // switch direction
86     { 4.0, true },  // switch direction
87     { 5.0, true },  // prev was flagged
88     { 6.0, false },
89     { 6.1, false },
90     { 7.1, true },  // suspicious
91     { 17.1, false },  // very large--okay
92   };
93 
94   stime_t now = 0.0;
95   const stime_t kTimeDelta = 0.01;
96   for (size_t i = 0; i < arraysize(data); i++) {
97     now += kTimeDelta;
98     hs.timestamp = now;
99     fs.flags = 0;
100     fs.position_y = data[i].val;
101     wrapper.SyncInterpret(&hs, NULL);
102     const unsigned kFlags = GESTURES_FINGER_WARP_Y |
103         GESTURES_FINGER_WARP_Y_TAP_MOVE |
104         GESTURES_FINGER_WARP_TELEPORTATION;
105     EXPECT_EQ(data[i].warp ? kFlags : 0, fs.flags) << "i=" << i;
106   }
107 }
108 
109 struct ActualLogInputs {
110   stime_t timestamp;
111   float x0, y0, p0;
112   short id0;
113   float x1, y1, p1;
114   short id1;
115 };
116 
117 // Real log with jumping fingers. Should only scroll in one direction
TEST(SensorJumpFilterInterpreterTest,ActualLogTest)118 TEST(SensorJumpFilterInterpreterTest, ActualLogTest) {
119   SensorJumpFilterInterpreterTestInterpreter* base_interpreter =
120       new SensorJumpFilterInterpreterTestInterpreter;
121   SensorJumpFilterInterpreter interpreter(NULL, base_interpreter, NULL);
122 
123   interpreter.enabled_.val_ = 1;
124 
125   HardwareProperties hwprops = {
126     0, 0, 106.666672, 68,  // left, top, right, bottom
127     1, 1,  // x res (pixels/mm), y res (pixels/mm)
128     25.4, 25.4,  // scrn DPI X, Y
129     -1,  // orientation minimum
130     2,   // orientation maximum
131     15, 5,  // max fingers, max_touch,
132     0, 0, 1,  // t5r2, semi, button pad
133     0, 0,  // has wheel, vertical wheel is high resolution
134     0,  // haptic pad
135   };
136   TestInterpreterWrapper wrapper(&interpreter, &hwprops);
137 
138   ActualLogInputs inputs[] = {
139     { 19.554, 56.666, 59.400, 118.201, 6, 35.083, 58.200, 118.201, 7 },
140     { 19.566, 56.583, 59.299, 118.201, 6, 35.083, 58.100, 118.201, 7 },
141     { 19.578, 56.583, 59.100, 118.201, 6, 35.000, 58.100, 118.201, 7 },
142     { 19.590, 56.500, 58.900, 118.201, 6, 34.750, 55.100, 116.261, 7 },
143     { 19.601, 56.416, 58.799, 118.201, 6, 34.666, 54.900, 118.201, 7 },
144     { 19.613, 56.333, 58.700, 118.201, 6, 34.666, 54.600, 118.201, 7 },
145     { 19.625, 56.250, 58.500, 118.201, 6, 34.583, 54.500, 118.201, 7 },
146     { 19.637, 56.166, 58.400, 118.201, 6, 34.583, 54.200, 118.201, 7 },
147     { 19.648, 56.166, 58.299, 118.201, 6, 34.416, 53.900, 118.201, 7 },
148     { 19.660, 56.083, 58.100, 118.201, 6, 34.416, 53.700, 118.201, 7 },
149     { 19.672, 56.083, 58.100, 118.201, 6, 34.333, 53.500, 118.201, 7 },
150     { 19.684, 56.083, 58.000, 118.201, 6, 34.250, 53.400, 118.201, 7 },
151     { 19.696, 56.000, 57.900, 118.201, 6, 34.166, 53.200, 118.201, 7 },
152     { 19.708, 55.916, 57.799, 118.201, 6, 34.166, 53.100, 118.201, 7 },
153     { 19.720, 55.916, 57.799, 118.201, 6, 34.166, 53.000, 118.201, 7 },
154     { 19.732, 55.916, 57.799, 118.201, 6, 34.083, 52.799, 118.201, 7 },
155     { 19.744, 55.916, 57.799, 118.201, 6, 34.083, 52.700, 118.201, 7 },
156     { 19.756, 55.833, 57.700, 118.201, 6, 34.000, 52.600, 118.201, 7 },
157     { 19.768, 55.833, 57.500, 118.201, 6, 34.000, 52.500, 118.201, 7 },
158     { 19.779, 55.333, 56.000, 118.201, 6, 34.000, 52.700, 118.201, 7 },
159     { 19.791, 55.333, 55.900, 118.201, 6, 34.000, 52.700, 118.201, 7 },
160     { 19.801, 55.333, 55.799, 118.201, 6, 34.000, 52.600, 118.201, 7 },
161     { 19.813, 55.333, 55.400, 118.201, 6, 33.833, 52.200, 118.201, 7 },
162     { 19.824, 55.333, 55.299, 118.201, 6, 33.833, 52.000, 118.201, 7 },
163     { 19.835, 55.333, 55.200, 118.201, 6, 33.833, 51.799, 118.201, 7 },
164     { 19.846, 55.333, 55.000, 118.201, 6, 33.750, 51.500, 118.201, 7 },
165     { 19.857, 55.333, 54.700, 118.201, 6, 33.750, 51.200, 118.201, 7 },
166     { 19.868, 55.333, 54.500, 118.201, 6, 33.750, 50.600, 118.201, 7 },
167     { 19.880, 55.250, 54.299, 118.201, 6, 33.666, 50.500, 118.201, 7 },
168     { 19.891, 55.250, 54.299, 118.201, 6, 33.666, 50.299, 118.201, 7 },
169     { 19.902, 55.166, 54.100, 118.201, 6, 33.666, 50.100, 118.201, 7 },
170     { 19.913, 55.166, 53.900, 116.261, 6, 33.666, 49.900, 118.201, 7 },
171     { 19.924, 55.083, 53.900, 116.261, 6, 33.666, 49.799, 118.201, 7 },
172     { 19.935, 55.083, 53.700, 116.261, 6, 33.583, 49.500, 118.201, 7 },
173     { 19.947, 55.083, 53.500, 112.380, 6, 33.583, 49.299, 118.201, 7 },
174     { 19.958, 55.083, 53.299, 110.439, 6, 33.583, 49.100, 118.201, 7 },
175     { 19.969, 55.083, 53.100, 106.559, 6, 33.500, 48.900, 118.201, 7 },
176     { 19.980, 55.000, 52.900, 104.618, 6, 33.416, 48.799, 118.201, 7 },
177     { 19.991, 55.000, 52.799, 102.678, 6, 33.416, 48.600, 118.201, 7 },
178     { 20.002, 55.000, 52.600, 98.7977, 6, 33.416, 48.299, 118.201, 7 },
179     { 20.013, 54.916, 52.500, 96.8573, 6, 33.416, 48.000, 118.201, 7 },
180     { 20.025, 54.833, 52.299, 92.9766, 6, 33.416, 47.700, 118.201, 7 },
181     { 20.036, 54.666, 50.299, 118.201, 6, 33.333, 47.400, 118.201, 7 },
182     { 20.047, 54.666, 50.100, 118.201, 6, 33.250, 47.000, 118.201, 7 },
183     { 20.058, 54.666, 49.700, 118.201, 6, 33.250, 46.799, 118.201, 7 },
184     { 20.069, 54.500, 49.299, 118.201, 6, 33.166, 46.299, 118.201, 7 },
185     { 20.080, 54.416, 49.000, 118.201, 6, 33.166, 46.100, 118.201, 7 },
186     { 20.091, 54.416, 48.700, 118.201, 6, 33.083, 45.600, 118.201, 7 },
187     { 20.102, 54.416, 48.600, 118.201, 6, 33.083, 45.299, 118.201, 7 },
188     { 20.113, 54.416, 48.299, 118.201, 6, 33.000, 45.000, 118.201, 7 },
189     { 20.124, 54.416, 48.100, 118.201, 6, 33.000, 44.700, 118.201, 7 },
190     { 20.135, 54.333, 47.700, 118.201, 6, 32.916, 44.000, 118.201, 7 },
191     { 20.147, 54.250, 47.500, 118.201, 6, 32.833, 43.600, 118.201, 7 },
192     { 20.158, 54.250, 47.400, 114.320, 6, 32.833, 43.400, 118.201, 7 },
193     { 20.169, 54.250, 47.200, 112.380, 6, 32.750, 43.100, 118.201, 7 },
194     { 20.180, 54.250, 47.000, 108.499, 6, 32.750, 42.799, 118.201, 7 },
195     { 20.191, 54.250, 46.799, 106.559, 6, 32.666, 42.600, 118.201, 7 },
196     { 20.202, 54.250, 46.600, 102.678, 6, 32.583, 42.299, 118.201, 7 },
197     { 20.213, 54.166, 46.400, 98.7977, 6, 32.583, 42.000, 118.201, 7 },
198     { 20.224, 54.000, 44.400, 118.201, 6, 32.583, 41.700, 118.201, 7 },
199     { 20.235, 53.916, 44.000, 118.201, 6, 32.416, 41.200, 118.201, 7 },
200     { 20.246, 53.833, 43.600, 118.201, 6, 32.416, 40.900, 118.201, 7 },
201     { 20.257, 53.833, 43.299, 118.201, 6, 32.416, 40.500, 118.201, 7 },
202     { 20.268, 53.750, 43.000, 118.201, 6, 32.416, 40.200, 118.201, 7 },
203     { 20.280, 53.750, 42.799, 118.201, 6, 32.333, 40.000, 118.201, 7 },
204     { 20.291, 53.750, 42.500, 118.201, 6, 32.333, 39.600, 118.201, 7 },
205     { 20.302, 53.750, 42.400, 118.201, 6, 32.250, 39.200, 118.201, 7 },
206     { 20.313, 53.666, 42.200, 118.201, 6, 32.166, 38.299, 118.201, 7 },
207     { 20.324, 53.666, 41.900, 118.201, 6, 32.166, 38.000, 118.201, 7 },
208     { 20.335, 53.666, 41.900, 118.201, 6, 32.166, 37.900, 118.201, 7 },
209     { 20.347, 53.583, 41.500, 118.201, 6, 32.166, 37.700, 118.201, 7 },
210     { 20.360, 53.500, 40.700, 182.233, 6, 31.666, 35.100, 118.201, 7 },
211     { 20.374, 53.416, 40.200, 182.233, 6, 31.666, 35.000, 118.201, 7 },
212     { 20.388, 53.416, 40.000, 182.233, 6, 31.666, 39.100, 118.201, 7 },
213     { 20.401, 53.416, 39.700, 184.173, 6, 31.666, 38.900, 118.201, 7 },
214     { 20.415, 53.333, 39.299, 184.173, 6, 31.666, 38.900, 118.201, 7 },
215     { 20.429, 53.333, 38.900, 182.233, 6, 31.583, 38.700, 118.201, 7 },
216     { 20.441, 52.666, 35.200, 118.201, 6, 31.666, 38.600, 118.201, 7 },
217     { 20.453, 52.750, 35.100, 118.201, 6, 31.583, 38.500, 118.201, 7 },
218     { 20.466, 52.666, 34.900, 118.201, 6, 31.666, 35.299, 189.995, 7 },
219     { 20.480, 52.666, 34.799, 118.201, 6, 31.666, 35.000, 193.875, 7 },
220     { 20.494, 52.666, 34.600, 118.201, 6, 31.666, 34.500, 191.935, 7 },
221     { 20.507, 52.583, 34.500, 118.201, 6, 31.666, 34.299, 193.875, 7 },
222     { 20.519, 52.583, 34.400, 118.201, 6, 31.333, 37.799, 118.201, 7 },
223     { 20.533, 52.583, 34.299, 118.201, 6, 31.583, 33.700, 195.816, 7 },
224     { 20.545, 52.666, 34.100, 118.201, 6, 31.000, 29.700, 118.201, 7 },
225     { 20.557, 52.583, 34.000, 118.201, 6, 31.000, 29.400, 118.201, 7 },
226     { 20.569, 52.583, 34.000, 118.201, 6, 31.000, 29.200, 118.201, 7 },
227     { 20.581, 52.583, 34.000, 118.201, 6, 31.000, 29.100, 118.201, 7 },
228     { 20.593, 52.583, 33.799, 118.201, 6, 30.916, 28.900, 118.201, 7 },
229     { 20.605, 52.583, 33.799, 118.201, 6, 30.916, 28.800, 118.201, 7 },
230   };
231 
232   FingerState fs[] = {
233     { 0, 0, 0, 0, 1, 0, 3.0, 0.0, 1, 0 },
234     { 0, 0, 0, 0, 1, 0, 3.0, 0.0, 1, 0 },
235   };
236   HardwareState hs = make_hwstate(0.0, 0, 2, 2, &fs[0]);
237 
238   float prev_y_out[] = { 0.0, 0.0 };
239 
240   for (size_t i = 0; i < arraysize(inputs); i++) {
241     const ActualLogInputs& input = inputs[i];
242     hs.timestamp = input.timestamp;
243     fs[0].position_x = input.x0;
244     fs[0].position_y = input.y0;
245     fs[0].pressure = input.p0;
246     fs[0].tracking_id = input.id0;
247     fs[1].position_x = input.x1;
248     fs[1].position_y = input.y1;
249     fs[1].pressure = input.p1;
250     fs[1].tracking_id = input.id1;
251     wrapper.SyncInterpret(&hs, NULL);
252     if (i != 0) {  // can't do deltas with the first input
253       float dy[] = { fs[0].position_y - prev_y_out[0],
254                      fs[1].position_y - prev_y_out[1] };
255       for (size_t j = 0; j < arraysize(dy); j++) {
256         if (fs[j].flags & GESTURES_FINGER_WARP_Y)
257           dy[j] = 0.0;
258         EXPECT_LE(dy[j], 0.0) << "i=" << i << " j=" << j;
259       }
260     }
261     prev_y_out[0] = fs[0].position_y;
262     prev_y_out[1] = fs[1].position_y;
263   }
264 }
265 
266 }  // namespace gestures
267