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