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