• 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 <gtest/gtest.h>
6 
7 #include "include/gestures.h"
8 #include "include/mouse_interpreter.h"
9 #include "include/unittest_util.h"
10 #include "include/util.h"
11 
12 namespace gestures {
13 
make_hwprops_for_mouse(unsigned has_wheel,unsigned wheel_is_hi_res)14 HardwareProperties make_hwprops_for_mouse(
15     unsigned has_wheel, unsigned wheel_is_hi_res) {
16   return {
17     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // touch-specific properties
18     has_wheel,
19     wheel_is_hi_res,
20     0,  // is_haptic_pad
21   };
22 }
23 
24 class MouseInterpreterTest : public ::testing::Test {};
25 
TEST(MouseInterpreterTest,SimpleTest)26 TEST(MouseInterpreterTest, SimpleTest) {
27   HardwareProperties hwprops = make_hwprops_for_mouse(1, 0);
28   MouseInterpreter mi(NULL, NULL);
29   TestInterpreterWrapper wrapper(&mi, &hwprops);
30   Gesture* gs;
31 
32   HardwareState hwstates[] = {
33     { 200000, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0.0 },
34     { 210000, 0, 0, 0, NULL, 9, -7, 0, 0, 0, 0.0 },
35     { 220000, 1, 0, 0, NULL, 0, 0, 0, 0, 0, 0.0 },
36     { 230000, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0.0 },
37     { 240000, 0, 0, 0, NULL, 0, 0, -3, -360, 4, 0.0 },
38   };
39 
40   mi.output_mouse_wheel_gestures_.val_ = true;
41 
42   gs = wrapper.SyncInterpret(&hwstates[0], NULL);
43   EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), gs);
44 
45   gs = wrapper.SyncInterpret(&hwstates[1], NULL);
46   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
47   EXPECT_EQ(kGestureTypeMove, gs->type);
48   EXPECT_EQ(9, gs->details.move.dx);
49   EXPECT_EQ(-7, gs->details.move.dy);
50   EXPECT_EQ(200000, gs->start_time);
51   EXPECT_EQ(210000, gs->end_time);
52 
53   gs = wrapper.SyncInterpret(&hwstates[2], NULL);
54   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
55   EXPECT_EQ(kGestureTypeButtonsChange, gs->type);
56   EXPECT_EQ(1, gs->details.buttons.down);
57   EXPECT_EQ(0, gs->details.buttons.up);
58   EXPECT_EQ(210000, gs->start_time);
59   EXPECT_EQ(220000, gs->end_time);
60 
61   gs = wrapper.SyncInterpret(&hwstates[3], NULL);
62   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
63   EXPECT_EQ(kGestureTypeButtonsChange, gs->type);
64   EXPECT_EQ(0, gs->details.buttons.down);
65   EXPECT_EQ(1, gs->details.buttons.up);
66   EXPECT_EQ(220000, gs->start_time);
67   EXPECT_EQ(230000, gs->end_time);
68 
69   gs = wrapper.SyncInterpret(&hwstates[4], NULL);
70   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
71   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
72   EXPECT_LT(-1, gs->details.wheel.dx);
73   EXPECT_GT(1, gs->details.wheel.dy);
74   EXPECT_EQ(240000, gs->start_time);
75   EXPECT_EQ(240000, gs->end_time);
76 }
77 
TEST(MouseInterpreterTest,HighResolutionVerticalScrollTest)78 TEST(MouseInterpreterTest, HighResolutionVerticalScrollTest) {
79   HardwareProperties hwprops = make_hwprops_for_mouse(1, 1);
80   MouseInterpreter mi(NULL, NULL);
81   TestInterpreterWrapper wrapper(&mi, &hwprops);
82   Gesture* gs;
83 
84   HardwareState hwstates[] = {
85     { 200000, 0, 0, 0, NULL, 0, 0,  0,   0, 0, 0.0 },
86     { 210000, 0, 0, 0, NULL, 0, 0,  0, -15, 0, 0.0 },
87     { 220000, 0, 0, 0, NULL, 0, 0, -1, -15, 0, 0.0 },
88     { 230000, 0, 0, 0, NULL, 0, 0,  0,-120, 0, 0.0 },
89     { 240000, 0, 0, 0, NULL, 0, 0, -1,   0, 0, 0.0 },
90   };
91 
92   mi.output_mouse_wheel_gestures_.val_ = true;
93   mi.hi_res_scrolling_.val_ = 1;
94 
95   gs = wrapper.SyncInterpret(&hwstates[0], NULL);
96   EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), gs);
97 
98   gs = wrapper.SyncInterpret(&hwstates[1], NULL);
99   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
100   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
101   EXPECT_EQ(0, gs->details.wheel.dx);
102   float offset_of_8th_notch_scroll = gs->details.wheel.dy;
103   EXPECT_LT(1, offset_of_8th_notch_scroll);
104 
105   gs = wrapper.SyncInterpret(&hwstates[2], NULL);
106   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
107   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
108   EXPECT_EQ(0, gs->details.wheel.dx);
109   // Having a low-res scroll event as well as the high-resolution one shouldn't
110   // change the output value.
111   EXPECT_NEAR(offset_of_8th_notch_scroll, gs->details.wheel.dy, 0.1);
112 
113   gs = wrapper.SyncInterpret(&hwstates[3], NULL);
114   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
115   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
116   EXPECT_EQ(0, gs->details.wheel.dx);
117   float offset_of_high_res_scroll = gs->details.wheel.dy;
118 
119   mi.hi_res_scrolling_.val_ = 0;
120 
121   gs = wrapper.SyncInterpret(&hwstates[4], NULL);
122   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
123   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
124   EXPECT_EQ(0, gs->details.wheel.dx);
125   // A high-res scroll should yield the same offset as a low-res one with
126   // proper unit conversion.
127   EXPECT_NEAR(offset_of_high_res_scroll, gs->details.wheel.dy, 0.1);
128 }
129 
TEST(MouseInterpreterTest,JankyScrollTest)130 TEST(MouseInterpreterTest, JankyScrollTest) {
131   HardwareProperties hwprops = make_hwprops_for_mouse(1, 0);
132   MouseInterpreter mi(NULL, NULL);
133   TestInterpreterWrapper wrapper(&mi, &hwprops);
134   Gesture* gs;
135 
136   // Because we do not allow time deltas less than 8ms when calculating scroll
137   // acceleration, the last two scroll events should give the same dy
138   // (timestamp is in units of seconds)
139   HardwareState hwstates[] = {
140     { 200000,      0, 0, 0, NULL, 0, 0, -1, 0, 0, 0.0 },
141     { 200000.008,  0, 0, 0, NULL, 0, 0, -1, 0, 0, 0.0 },
142     { 200000.0085, 0, 0, 0, NULL, 0, 0, -1, 0, 0, 0.0 },
143   };
144 
145   mi.output_mouse_wheel_gestures_.val_ = true;
146 
147   gs = wrapper.SyncInterpret(&hwstates[0], NULL);
148   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
149   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
150   EXPECT_EQ(0, gs->details.wheel.dx);
151   // Ignore the dy from the first scroll event, as the gesture interpreter
152   // hardcodes that time delta to 1 second, making it invalid for this test.
153 
154   gs = wrapper.SyncInterpret(&hwstates[1], NULL);
155   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
156   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
157   EXPECT_EQ(0, gs->details.wheel.dx);
158   float scroll_offset = gs->details.wheel.dy;
159 
160   gs = wrapper.SyncInterpret(&hwstates[2], NULL);
161   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
162   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
163   EXPECT_EQ(0, gs->details.wheel.dx);
164 
165   EXPECT_NEAR(scroll_offset, gs->details.wheel.dy, 0.1);
166 }
167 
TEST(MouseInterpreterTest,WheelTickReportingHighResTest)168 TEST(MouseInterpreterTest, WheelTickReportingHighResTest) {
169   HardwareProperties hwprops = make_hwprops_for_mouse(1, 1);
170   MouseInterpreter mi(NULL, NULL);
171   TestInterpreterWrapper wrapper(&mi, &hwprops);
172   Gesture* gs;
173 
174   HardwareState hwstates[] = {
175     { 200000, 0, 0, 0, NULL, 0, 0, 0,   0, 0, 0.0 },
176     { 210000, 0, 0, 0, NULL, 0, 0, 0, -30, 0, 0.0 },
177   };
178 
179   mi.output_mouse_wheel_gestures_.val_ = true;
180   mi.hi_res_scrolling_.val_ = true;
181 
182   gs = wrapper.SyncInterpret(&hwstates[0], NULL);
183   EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), gs);
184 
185   gs = wrapper.SyncInterpret(&hwstates[1], NULL);
186   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
187   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
188   EXPECT_EQ( 0, gs->details.wheel.tick_120ths_dx);
189   EXPECT_EQ(30, gs->details.wheel.tick_120ths_dy);
190 }
191 
TEST(MouseInterpreterTest,WheelTickReportingLowResTest)192 TEST(MouseInterpreterTest, WheelTickReportingLowResTest) {
193   HardwareProperties hwprops = make_hwprops_for_mouse(1, 0);
194   MouseInterpreter mi(NULL, NULL);
195   TestInterpreterWrapper wrapper(&mi, &hwprops);
196   Gesture* gs;
197 
198   HardwareState hwstates[] = {
199     { 200000, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0.0 },
200     { 210000, 0, 0, 0, NULL, 0, 0, 1, 0, 0, 0.0 },
201     { 210000, 0, 0, 0, NULL, 0, 0, 0, 0, 1, 0.0 },
202   };
203 
204   mi.output_mouse_wheel_gestures_.val_ = true;
205   mi.hi_res_scrolling_.val_ = false;
206 
207   gs = wrapper.SyncInterpret(&hwstates[0], NULL);
208   EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), gs);
209 
210   gs = wrapper.SyncInterpret(&hwstates[1], NULL);
211   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
212   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
213   EXPECT_EQ(   0, gs->details.wheel.tick_120ths_dx);
214   EXPECT_EQ(-120, gs->details.wheel.tick_120ths_dy);
215 
216   gs = wrapper.SyncInterpret(&hwstates[2], NULL);
217   ASSERT_NE(reinterpret_cast<Gesture*>(NULL), gs);
218   EXPECT_EQ(kGestureTypeMouseWheel, gs->type);
219   EXPECT_EQ(120, gs->details.wheel.tick_120ths_dx);
220   EXPECT_EQ(  0, gs->details.wheel.tick_120ths_dy);
221 }
222 
223 }  // namespace gestures
224