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 <memory>
8 #include <vector>
9 #include <utility>
10
11 #include <gtest/gtest.h>
12
13 #include "include/gestures.h"
14 #include "include/scaling_filter_interpreter.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
22 namespace gestures {
23
24 class ScalingFilterInterpreterTest : public ::testing::Test {};
25
26 class ScalingFilterInterpreterTestInterpreter : public Interpreter {
27 public:
ScalingFilterInterpreterTestInterpreter()28 ScalingFilterInterpreterTestInterpreter()
29 : Interpreter(nullptr, nullptr, false), initialize_called_(false) {}
30
SyncInterpret(HardwareState & hwstate,stime_t * timeout)31 virtual void SyncInterpret(HardwareState& hwstate, stime_t* timeout) {
32 if (!expected_coordinates_.empty()) {
33 std::vector<pair<float, float> >& expected =
34 expected_coordinates_.front();
35 for (unsigned short i = 0; i < hwstate.finger_cnt; i++) {
36 EXPECT_FLOAT_EQ(expected[i].first, hwstate.fingers[i].position_x)
37 << "i = " << i;
38 EXPECT_FLOAT_EQ(expected[i].second, hwstate.fingers[i].position_y)
39 << "i = " << i;
40 }
41 expected_coordinates_.pop_front();
42 }
43 if (!expected_orientation_.empty()) {
44 const std::vector<float>& expected = expected_orientation_.front();
45 EXPECT_EQ(expected.size(), hwstate.finger_cnt);
46 for (size_t i = 0; i < hwstate.finger_cnt; i++)
47 EXPECT_FLOAT_EQ(expected[i], hwstate.fingers[i].orientation)
48 << "i=" << i;
49 expected_orientation_.pop_front();
50 }
51 if (!expected_touch_major_.empty()) {
52 const std::vector<float>& expected = expected_touch_major_.front();
53 EXPECT_EQ(expected.size(), hwstate.finger_cnt);
54 for (size_t i = 0; i < hwstate.finger_cnt; i++)
55 EXPECT_FLOAT_EQ(expected[i], hwstate.fingers[i].touch_major)
56 << "i=" << i;
57 expected_touch_major_.pop_front();
58 }
59 if (!expected_touch_minor_.empty()) {
60 const std::vector<float>& expected = expected_touch_minor_.front();
61 EXPECT_EQ(expected.size(), hwstate.finger_cnt);
62 for (size_t i = 0; i < hwstate.finger_cnt; i++)
63 EXPECT_FLOAT_EQ(expected[i], hwstate.fingers[i].touch_minor)
64 << "i=" << i;
65 expected_touch_minor_.pop_front();
66 }
67 if (!expected_pressures_.empty() && hwstate.finger_cnt > 0) {
68 EXPECT_FLOAT_EQ(expected_pressures_.front(),
69 hwstate.fingers[0].pressure);
70 expected_pressures_.pop_front();
71 } else if (!expected_finger_cnt_.empty() && !expected_touch_cnt_.empty()) {
72 // Test if the low pressure event is dropped
73 EXPECT_EQ(expected_finger_cnt_.front(), hwstate.finger_cnt);
74 expected_finger_cnt_.pop_front();
75 EXPECT_EQ(expected_touch_cnt_.front(), hwstate.touch_cnt);
76 expected_touch_cnt_.pop_front();
77 }
78 if (return_values_.empty())
79 return;
80 return_value_ = return_values_.front();
81 return_values_.pop_front();
82 if (return_value_.type == kGestureTypeNull)
83 return;
84 ProduceGesture(return_value_);
85 }
86
HandleTimer(stime_t now,stime_t * timeout)87 virtual void HandleTimer(stime_t now, stime_t* timeout) {
88 EXPECT_TRUE(false);
89 }
90
Initialize(const HardwareProperties * hw_props,Metrics * metrics,MetricsProperties * mprops,GestureConsumer * consumer)91 virtual void Initialize(const HardwareProperties* hw_props,
92 Metrics* metrics,
93 MetricsProperties* mprops,
94 GestureConsumer* consumer) {
95 EXPECT_FLOAT_EQ(expected_hwprops_.left, hw_props->left);
96 EXPECT_FLOAT_EQ(expected_hwprops_.top, hw_props->top);
97 EXPECT_FLOAT_EQ(expected_hwprops_.right, hw_props->right);
98 EXPECT_FLOAT_EQ(expected_hwprops_.bottom, hw_props->bottom);
99 EXPECT_FLOAT_EQ(expected_hwprops_.res_x, hw_props->res_x);
100 EXPECT_FLOAT_EQ(expected_hwprops_.res_y, hw_props->res_y);
101 EXPECT_FLOAT_EQ(expected_hwprops_.orientation_minimum,
102 hw_props->orientation_minimum);
103 EXPECT_FLOAT_EQ(expected_hwprops_.orientation_maximum,
104 hw_props->orientation_maximum);
105 EXPECT_EQ(expected_hwprops_.max_finger_cnt, hw_props->max_finger_cnt);
106 EXPECT_EQ(expected_hwprops_.max_touch_cnt, hw_props->max_touch_cnt);
107 EXPECT_EQ(expected_hwprops_.supports_t5r2, hw_props->supports_t5r2);
108 EXPECT_EQ(expected_hwprops_.support_semi_mt, hw_props->support_semi_mt);
109 EXPECT_EQ(expected_hwprops_.is_button_pad, hw_props->is_button_pad);
110 initialize_called_ = true;
111 Interpreter::Initialize(hw_props, metrics, mprops, consumer);
112 };
113
114 Gesture return_value_;
115 deque<Gesture> return_values_;
116 deque<std::vector<pair<float, float> > > expected_coordinates_;
117 deque<std::vector<float> > expected_orientation_;
118 deque<std::vector<float> > expected_touch_major_;
119 deque<std::vector<float> > expected_touch_minor_;
120 deque<float> expected_pressures_;
121 deque<int> expected_finger_cnt_;
122 deque<int> expected_touch_cnt_;
123 HardwareProperties expected_hwprops_;
124 bool initialize_called_;
125 };
126
TEST(ScalingFilterInterpreterTest,SimpleTest)127 TEST(ScalingFilterInterpreterTest, SimpleTest) {
128 ScalingFilterInterpreterTestInterpreter* base_interpreter =
129 new ScalingFilterInterpreterTestInterpreter;
130 ScalingFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
131 GESTURES_DEVCLASS_TOUCHPAD);
132 HardwareProperties initial_hwprops = {
133 .left = 133, .top = 728, .right = 10279, .bottom = 5822,
134 .res_x = (10279.0 - 133.0) / 100.0,
135 .res_y = (5822.0 - 728.0) / 60,
136 .orientation_minimum = -1,
137 .orientation_maximum = 2,
138 .max_finger_cnt = 2, .max_touch_cnt = 5,
139 .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
140 .has_wheel = 0, .wheel_is_hi_res = 0,
141 .is_haptic_pad = 0,
142 };
143 HardwareProperties expected_hwprops = {
144 .right = 100, .bottom = 60,
145 .res_x = 1.0,
146 .res_y = 1.0,
147 .orientation_minimum = -M_PI_4, // (1 tick above X-axis)
148 .orientation_maximum = M_PI_2,
149 .max_finger_cnt = 2, .max_touch_cnt = 5,
150 .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
151 .has_wheel = 0, .wheel_is_hi_res = 0,
152 .is_haptic_pad = 0,
153 };
154 base_interpreter->expected_hwprops_ = expected_hwprops;
155
156 TestInterpreterWrapper wrapper(&interpreter, &initial_hwprops);
157 EXPECT_TRUE(base_interpreter->initialize_called_);
158 const float kPressureScale = 2.0;
159 const float kPressureTranslate = 3.0;
160 const float kPressureThreshold = 10.0;
161 interpreter.pressure_scale_.val_ = kPressureScale;
162 interpreter.pressure_translate_.val_ = kPressureTranslate;
163 const float kTpYBias = -2.8;
164 interpreter.tp_y_bias_.val_ = kTpYBias;
165
166 FingerState fs[] = {
167 { 1, 0, 0, 0, 1, 0, 150, 4000, 1, 0 },
168 { 0, 0, 0, 0, 2, 0, 550, 2000, 1, 0 },
169 { 0, 0, 0, 0, 3, 0, 250, 3000, 1, 0 },
170 { 0, 0, 0, 0, 3, 0, 250, 3000, 1, 0 }
171 };
172 HardwareState hs[] = {
173 make_hwstate(10000, 0, 1, 1, &fs[0]),
174 make_hwstate(54000, 0, 1, 1, &fs[1]),
175 make_hwstate(98000, 0, 1, 1, &fs[2]),
176 make_hwstate(99000, 0, 1, 1, &fs[3]),
177 };
178
179 // Set up expected translated coordinates
180 base_interpreter->expected_coordinates_.push_back(
181 std::vector<pair<float, float> >(1, make_pair(
182 static_cast<float>(100.0 * (150.0 - 133.0) / (10279.0 - 133.0)),
183 static_cast<float>(60.0 * (4000.0 - 728.0) / (5822.0 - 728.0)))));
184 base_interpreter->expected_coordinates_.push_back(
185 std::vector<pair<float, float> >(1, make_pair(
186 static_cast<float>(100.0 * (550.0 - 133.0) / (10279.0 - 133.0)),
187 static_cast<float>(60.0 * (2000.0 - 728.0) / (5822.0 - 728.0)))));
188 base_interpreter->expected_coordinates_.push_back(
189 std::vector<pair<float, float> >(1, make_pair(
190 static_cast<float>(100.0 * (250.0 - 133.0) / (10279.0 - 133.0)),
191 static_cast<float>(60.0 * (3000.0 - 728.0) / (5822.0 - 728.0)))));
192 base_interpreter->expected_coordinates_.push_back(
193 std::vector<pair<float, float> >(1, make_pair(
194 static_cast<float>(100.0 * (250.0 - 133.0) / (10279.0 - 133.0)),
195 static_cast<float>(60.0 * (3000.0 - 728.0) / (5822.0 - 728.0)))));
196
197 base_interpreter->expected_pressures_.push_back(
198 fs[0].pressure * kPressureScale + kPressureTranslate);
199 base_interpreter->expected_pressures_.push_back(
200 fs[1].pressure * kPressureScale + kPressureTranslate);
201 base_interpreter->expected_pressures_.push_back(
202 fs[2].pressure * kPressureScale + kPressureTranslate);
203 base_interpreter->expected_pressures_.push_back(
204 fs[3].pressure * kPressureScale + kPressureTranslate);
205
206 base_interpreter->expected_touch_major_.push_back(
207 std::vector<float>(1, interpreter.tp_y_scale_ *
208 (fs[0].touch_major - kTpYBias)));
209
210 // Set up gestures to return
211 base_interpreter->return_values_.push_back(Gesture()); // Null type
212 base_interpreter->return_values_.push_back(Gesture(kGestureMove,
213 0, // start time
214 0, // end time
215 -4, // dx
216 2.8)); // dy
217 base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
218 0, // start time
219 0, // end time
220 4.1, // dx
221 -10.3)); // dy
222 base_interpreter->return_values_.push_back(Gesture(kGestureFling,
223 0, // start time
224 0, // end time
225 201.8, // dx
226 -112.4, // dy
227 GESTURES_FLING_START));
228 base_interpreter->return_values_.push_back(Gesture()); // Null type
229
230 Gesture* out = wrapper.SyncInterpret(hs[0], nullptr);
231 ASSERT_EQ(nullptr, out);
232 out = wrapper.SyncInterpret(hs[1], nullptr);
233 ASSERT_NE(nullptr, out);
234 EXPECT_EQ(kGestureTypeMove, out->type);
235 EXPECT_FLOAT_EQ(-4.0 * 133.0 / 25.4, out->details.move.dx);
236 EXPECT_FLOAT_EQ(2.8 * 133.0 / 25.4, out->details.move.dy);
237 out = wrapper.SyncInterpret(hs[2], nullptr);
238 ASSERT_NE(nullptr, out);
239 EXPECT_EQ(kGestureTypeScroll, out->type);
240 EXPECT_FLOAT_EQ(-4.1 * 133.0 / 25.4, out->details.scroll.dx);
241 EXPECT_FLOAT_EQ(10.3 * 133.0 / 25.4, out->details.scroll.dy);
242 out = wrapper.SyncInterpret(hs[3], nullptr);
243 ASSERT_NE(nullptr, out);
244 EXPECT_EQ(kGestureTypeFling, out->type);
245 EXPECT_FLOAT_EQ(-201.8 * 133.0 / 25.4, out->details.fling.vx);
246 EXPECT_FLOAT_EQ(112.4 * 133.0 / 25.4, out->details.fling.vy);
247 EXPECT_EQ(GESTURES_FLING_START, out->details.fling.fling_state);
248
249 // Test if we will drop the low pressure event.
250 FingerState fs2[] = {
251 { 0, 0, 0, 0, 1, 0, 150, 4000, 2, 0 },
252 { 0, 0, 0, 0, 4, 0, 550, 2000, 2, 0 },
253 { 0, 0, 0, 0, 1, 0, 560, 2000, 2, 0 },
254 };
255 HardwareState hs2[] = {
256 make_hwstate(110000, 0, 1, 2, &fs2[0]),
257 make_hwstate(154000, 0, 1, 1, &fs2[1]),
258 make_hwstate(184000, 0, 1, 0, &fs2[2]),
259 };
260 interpreter.pressure_threshold_.val_ = kPressureThreshold;
261 base_interpreter->expected_finger_cnt_.push_back(0);
262 base_interpreter->expected_touch_cnt_.push_back(1);
263 out = wrapper.SyncInterpret(hs2[0], nullptr);
264
265 base_interpreter->expected_pressures_.push_back(
266 fs2[1].pressure * kPressureScale + kPressureTranslate);
267 out = wrapper.SyncInterpret(hs2[1], nullptr);
268
269 base_interpreter->expected_finger_cnt_.push_back(0);
270 base_interpreter->expected_touch_cnt_.push_back(0);
271 out = wrapper.SyncInterpret(hs2[2], nullptr);
272 }
273
TEST(ScalingFilterInterpreterTest,ResolutionFallback)274 TEST(ScalingFilterInterpreterTest, ResolutionFallback) {
275 ScalingFilterInterpreterTestInterpreter* base_interpreter =
276 new ScalingFilterInterpreterTestInterpreter;
277 ScalingFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
278 GESTURES_DEVCLASS_TOUCHPAD);
279 HardwareProperties initial_hwprops = {
280 .right = 2000, .bottom = 1000,
281 .res_x = 0, .res_y = 0,
282 .orientation_minimum = -1,
283 .orientation_maximum = 2,
284 .max_finger_cnt = 2, .max_touch_cnt = 5,
285 .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
286 .has_wheel = 0, .wheel_is_hi_res = 0,
287 .is_haptic_pad = 0,
288 };
289 HardwareProperties expected_hwprops = {
290 .right = 2000 / 32.0, .bottom = 1000 / 32.0,
291 .res_x = 1, .res_y = 1,
292 .orientation_minimum = -M_PI_4, // (1 tick above X-axis)
293 .orientation_maximum = M_PI_2,
294 .max_finger_cnt = 2, .max_touch_cnt = 5,
295 .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
296 .has_wheel = 0, .wheel_is_hi_res = 0,
297 .is_haptic_pad = 0,
298 };
299 base_interpreter->expected_hwprops_ = expected_hwprops;
300
301 TestInterpreterWrapper wrapper(&interpreter, &initial_hwprops);
302 EXPECT_TRUE(base_interpreter->initialize_called_);
303
304 FingerState fs = { 1, 0, 0, 0, 1, 0, 1000, 500, 1, 0 };
305 HardwareState hs = make_hwstate(10000, 0, 1, 1, &fs);
306
307 base_interpreter->expected_coordinates_.push_back(
308 std::vector<pair<float, float>>(1, make_pair(
309 static_cast<float>(1000 / 32.0), static_cast<float>(500 / 32.0))));
310
311 wrapper.SyncInterpret(hs, nullptr);
312 }
313
RunTouchMajorAndMinorTest(ScalingFilterInterpreterTestInterpreter * base_interpreter,ScalingFilterInterpreter * interpreter,HardwareProperties * hwprops,HardwareProperties * expected_hwprops,FingerState * fs,size_t n_fs,float e_x,float e_y)314 static void RunTouchMajorAndMinorTest(
315 ScalingFilterInterpreterTestInterpreter* base_interpreter,
316 ScalingFilterInterpreter* interpreter,
317 HardwareProperties *hwprops,
318 HardwareProperties *expected_hwprops,
319 FingerState *fs,
320 size_t n_fs,
321 float e_x,
322 float e_y) {
323
324 const float r_x_2 = 1.0 / hwprops->res_x / hwprops->res_x;
325 const float r_y_2 = 1.0 / hwprops->res_y / hwprops->res_y;
326
327 float orientation, touch_major, touch_minor, pressure;
328
329 std::unique_ptr<bool[]> has_zero_area(new bool[n_fs]);
330
331 for (size_t i = 0; i < n_fs; i++) {
332 bool no_orientation = hwprops->orientation_maximum == 0;
333 float cos_2, sin_2, touch_major_bias, touch_minor_bias;
334 if (no_orientation)
335 orientation = 0;
336 else
337 orientation = M_PI * fs[i].orientation /
338 (hwprops->orientation_maximum - hwprops->orientation_minimum + 1);
339 cos_2 = cosf(orientation) * cosf(orientation);
340 sin_2 = sinf(orientation) * sinf(orientation);
341 touch_major_bias = e_x * sin_2 + e_y * cos_2;
342 touch_minor_bias = e_x * cos_2 + e_y * sin_2;
343 if (fs[i].touch_major)
344 touch_major = fabsf(fs[i].touch_major - touch_major_bias) *
345 sqrtf(r_x_2 * sin_2 + r_y_2 * cos_2);
346 else
347 touch_major = 0.0;
348 if (fs[i].touch_minor)
349 touch_minor = fabsf(fs[i].touch_minor - touch_minor_bias) *
350 sqrtf(r_x_2 * cos_2 + r_y_2 * sin_2);
351 else
352 touch_minor = 0.0;
353 if (!no_orientation && touch_major < touch_minor) {
354 std::swap(touch_major, touch_minor);
355 if (orientation > 0.0)
356 orientation -= M_PI_2;
357 else
358 orientation += M_PI_2;
359 }
360 if (touch_major && touch_minor)
361 pressure = M_PI_4 * touch_major * touch_minor;
362 else if (touch_major)
363 pressure = M_PI_4 * touch_major * touch_major;
364 else
365 pressure = 0;
366
367 has_zero_area[i] = pressure == 0.0;
368
369 pressure = std::max(pressure , 1.0f);
370
371 if (has_zero_area[i]) {
372 base_interpreter->expected_orientation_.push_back(
373 std::vector<float>(0));
374 base_interpreter->expected_touch_major_.push_back(
375 std::vector<float>(0));
376 base_interpreter->expected_touch_minor_.push_back(
377 std::vector<float>(0));
378 base_interpreter->expected_finger_cnt_.push_back(0);
379 base_interpreter->expected_touch_cnt_.push_back(0);
380 } else {
381 base_interpreter->expected_orientation_.push_back(
382 std::vector<float>(1, orientation));
383 base_interpreter->expected_touch_major_.push_back(
384 std::vector<float>(1, touch_major));
385 base_interpreter->expected_touch_minor_.push_back(
386 std::vector<float>(1, touch_minor));
387 base_interpreter->expected_pressures_.push_back(pressure);
388 }
389 }
390
391 base_interpreter->expected_hwprops_ = *expected_hwprops;
392 interpreter->Initialize(hwprops, nullptr, nullptr, nullptr);
393 EXPECT_TRUE(base_interpreter->initialize_called_);
394
395 for (size_t i = 0; i < n_fs; i++) {
396 HardwareState hs;
397 memset(&hs, 0x0, sizeof(hs));
398 hs.timestamp = (i + 1) * 1000;
399 if (has_zero_area[i]) {
400 hs.finger_cnt = 0;
401 hs.touch_cnt = 0;
402 } else {
403 hs.finger_cnt = 1;
404 hs.touch_cnt = 1;
405 }
406 hs.fingers = fs + i;
407 interpreter->SyncInterpret(hs, nullptr);
408 }
409
410 // Tear down state
411 base_interpreter->initialize_called_ = false;
412 }
413
TEST(ScalingFilterInterpreterTest,TouchMajorAndMinorTest)414 TEST(ScalingFilterInterpreterTest, TouchMajorAndMinorTest) {
415 ScalingFilterInterpreterTestInterpreter* base_interpreter =
416 new ScalingFilterInterpreterTestInterpreter;
417 ScalingFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
418 GESTURES_DEVCLASS_TOUCHPAD);
419
420 const float e_x = 17;
421 const float e_y = 71;
422 const bool kFilterLowPressure = 1;
423
424 interpreter.surface_area_from_pressure_.val_ = false;
425 interpreter.filter_low_pressure_.val_ = kFilterLowPressure;
426 interpreter.tp_x_bias_.val_ = e_x;
427 interpreter.tp_y_bias_.val_ = e_y;
428
429 HardwareProperties hwprops = {
430 .right = 500, .bottom = 1000,
431 .res_x = 5,
432 .res_y = 10,
433 .orientation_minimum = -31,
434 .orientation_maximum = 32,
435 .max_finger_cnt = 2, .max_touch_cnt = 5,
436 .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
437 .has_wheel = 1, .wheel_is_hi_res = 0,
438 .is_haptic_pad = 0,
439 };
440 HardwareProperties expected_hwprops = {
441 .right = 100, .bottom = 100,
442 .res_x = 1.0, .res_y = 1.0,
443 .orientation_minimum = -M_PI * 31 / 64, // (1 tick above X-axis)
444 .orientation_maximum = M_PI_2,
445 .max_finger_cnt = 2, .max_touch_cnt = 5,
446 .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
447 .has_wheel = 1, .wheel_is_hi_res = 0,
448 .is_haptic_pad = 0,
449 };
450
451 // Test 1: Touch major and touch minor scaling with orientation
452 // range [-31, 32].
453
454 hwprops.orientation_minimum = -31;
455 hwprops.orientation_maximum = 32;
456 expected_hwprops.orientation_minimum =
457 M_PI * hwprops.orientation_minimum /
458 (hwprops.orientation_maximum - hwprops.orientation_minimum + 1);
459 expected_hwprops.orientation_maximum =
460 M_PI * hwprops.orientation_maximum /
461 (hwprops.orientation_maximum - hwprops.orientation_minimum + 1);
462
463 FingerState test_1_fs[] = {
464 { 0.0, 0.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
465
466 { 79.0, 99.0, 0, 0, 0, 16.0, 0, 0, 1, 0 },
467
468 { 79.0, 31.0, 0, 0, 0, -16.0, 0, 0, 1, 0 },
469 { 79.0, 31.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
470 { 79.0, 31.0, 0, 0, 0, 16.0, 0, 0, 1, 0 },
471 { 79.0, 31.0, 0, 0, 0, 32.0, 0, 0, 1, 0 },
472
473 { 79.0, 0.0, 0, 0, 0, -16.0, 0, 0, 1, 0 },
474 { 79.0, 0.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
475 { 79.0, 0.0, 0, 0, 0, 16.0, 0, 0, 1, 0 },
476 { 79.0, 0.0, 0, 0, 0, 32.0, 0, 0, 1, 0 },
477 };
478
479 RunTouchMajorAndMinorTest(base_interpreter,
480 &interpreter,
481 &hwprops,
482 &expected_hwprops,
483 test_1_fs,
484 arraysize(test_1_fs),
485 e_x,
486 e_y);
487
488 // Test 2: Touch major and touch minor scaling with orientation
489 // range [0, 1].
490
491 hwprops.orientation_minimum = 0;
492 hwprops.orientation_maximum = 1;
493 expected_hwprops.orientation_minimum = 0;
494 expected_hwprops.orientation_maximum = M_PI_2;
495
496 FingerState test_2_fs[] = {
497 { 0.0, 0.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
498
499 { 79.0, 31.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
500 { 79.0, 31.0, 0, 0, 0, 1.0, 0, 0, 1, 0 },
501
502 { 79.0, 0.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
503 { 79.0, 0.0, 0, 0, 0, 1.0, 0, 0, 1, 0 },
504 };
505
506 RunTouchMajorAndMinorTest(base_interpreter,
507 &interpreter,
508 &hwprops,
509 &expected_hwprops,
510 test_2_fs,
511 arraysize(test_2_fs),
512 e_x,
513 e_y);
514
515 // Test 3: Touch major and touch minor scaling with no orientation
516 // provided.
517
518 hwprops.orientation_minimum = 0;
519 hwprops.orientation_maximum = 0;
520 expected_hwprops.orientation_minimum = 0;
521 expected_hwprops.orientation_maximum = 0;
522
523 FingerState test_3_fs[] = {
524 { 0.0, 0.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
525
526 { 79.0, 31.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
527
528 { 79.0, 0.0, 0, 0, 0, 0.0, 0, 0, 1, 0 },
529 };
530
531 RunTouchMajorAndMinorTest(base_interpreter,
532 &interpreter,
533 &hwprops,
534 &expected_hwprops,
535 test_3_fs,
536 arraysize(test_3_fs),
537 e_x,
538 e_y);
539 }
540
541 } // namespace gestures
542