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 <gtest/gtest.h>
6
7 #include "include/fling_stop_filter_interpreter.h"
8 #include "include/gestures.h"
9 #include "include/unittest_util.h"
10 #include "include/util.h"
11
12 namespace gestures {
13
14 class FlingStopFilterInterpreterTest : public ::testing::Test {};
15
16 namespace {
17
18 class FlingStopFilterInterpreterTestInterpreter : public Interpreter {
19 public:
FlingStopFilterInterpreterTestInterpreter()20 FlingStopFilterInterpreterTestInterpreter()
21 : Interpreter(nullptr, nullptr, false),
22 sync_interpret_called_(false), handle_timer_called_(true),
23 next_timeout_(NO_DEADLINE) {}
24
SyncInterpret(HardwareState & hwstate,stime_t * timeout)25 virtual void SyncInterpret(HardwareState& hwstate, stime_t* timeout) {
26 sync_interpret_called_ = true;
27 *timeout = next_timeout_;
28 }
29
HandleTimer(stime_t now,stime_t * timeout)30 virtual void HandleTimer(stime_t now, stime_t* timeout) {
31 handle_timer_called_ = true;
32 *timeout = next_timeout_;
33 }
34
35 bool sync_interpret_called_;
36 bool handle_timer_called_;
37 stime_t next_timeout_;
38 };
39
40
41 struct SimpleTestInputs {
42 stime_t now;
43 short touch_cnt; // -1 for timer callback
44
45 bool expected_call_next;
46 stime_t next_timeout; // NO_DEADLINE for none (similarly for below)
47 stime_t expected_local_deadline;
48 stime_t expected_next_deadline;
49 stime_t expected_timeout;
50 bool expected_fling_stop_out;
51 };
52
53 } // namespace {}
54
TEST(FlingStopFilterInterpreterTest,SimpleTest)55 TEST(FlingStopFilterInterpreterTest, SimpleTest) {
56 FlingStopFilterInterpreterTestInterpreter* base_interpreter =
57 new FlingStopFilterInterpreterTestInterpreter;
58 FlingStopFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
59 GESTURES_DEVCLASS_TOUCHPAD);
60 TestInterpreterWrapper wrapper(&interpreter);
61
62 const stime_t kTO = interpreter.fling_stop_timeout_.val_ = 0.03;
63 const stime_t kED= interpreter.fling_stop_extra_delay_.val_ = 0.055;
64 const stime_t kND = NO_DEADLINE;
65
66 SimpleTestInputs inputs[] = {
67 // timeout case
68 { 0.01, 1, true, kND, 0.01 + kTO, kND, kTO, false },
69 { 0.02, 1, true, kND, 0.01 + kTO, kND, kTO - 0.01, false },
70 { 0.03, 0, true, kND, 0.01 + kTO, kND, kTO - 0.02, false },
71 { 0.01 + kTO, -1, false, kND, kND, kND, kND, true },
72
73 // multiple fingers come down, timeout
74 { 3.01, 1, true, kND, 3.01 + kTO, kND, kTO, false },
75 { 3.02, 2, true, kND, 3.01 + kTO + kED, kND, kTO + kED - 0.01, false },
76 { 3.03, 0, true, kND, 3.01 + kTO + kED, kND, kTO + kED - 0.02, false },
77 { 3.01 + kTO + kED, -1, false, kND, kND, kND, kND, true },
78
79 // Dual timeouts, local is shorter
80 { 6.01, 1, true, kND, 6.01 + kTO, kND, kTO, false },
81 { 6.02, 0, true, 0.1, 6.01 + kTO, 6.02 + 0.1, kTO - 0.01, false },
82 { 6.01 + kTO, -1, false, kND, kND, 6.02 + 0.1, 0.08, true },
83 { 6.02 + 0.1, -1, true, kND, kND, kND, kND, false },
84
85 // Dual timeouts, local is longer
86 { 9.01, 1, true, kND, 9.01 + kTO, kND, kTO, false },
87 { 9.02, 0, true, .01, 9.01 + kTO, 9.02 + .01, .01, false },
88 { 9.02 + .01, -1, true, kND, 9.01 + kTO, kND, kTO - .01 - 0.01, false },
89 { 9.01 + kTO, -1, false, kND, kND, kND, kND, true },
90
91 // Dual timeouts, new timeout on handling timeout
92 { 12.01, 1, true, kND, 12.01 + kTO, kND, kTO, false },
93 { 12.02, 0, true, 0.1, 12.01 + kTO, 12.02 + 0.1, kTO - 0.01, false },
94 { 12.01 + kTO, -1, false, kND, kND, 12.02 + 0.1, 0.08, true },
95 { 12.02 + 0.1, -1, true, 0.1, kND, 12.22, 0.1, false },
96 { 12.22, -1, true, kND, kND, kND, kND, false },
97
98 // Overrun deadline
99 { 15.01, 1, true, kND, 15.01 + kTO, kND, kTO, false },
100 { 15.02, 1, true, kND, 15.01 + kTO, kND, kTO - 0.01, false },
101 { 15.03, 0, true, kND, 15.01 + kTO, kND, kTO - 0.02, false },
102 { 15.02 + kTO, 0, true, kND, kND, kND, kND, true },
103 };
104
105 for (size_t i = 0; i < arraysize(inputs); i++) {
106 SimpleTestInputs& input = inputs[i];
107
108 base_interpreter->sync_interpret_called_ = false;
109 base_interpreter->handle_timer_called_ = false;
110 base_interpreter->next_timeout_ = input.next_timeout;
111
112 stime_t timeout = kND;
113
114 Gesture* ret = nullptr;
115 if (input.touch_cnt >= 0) {
116 FingerState fs[5];
117 memset(fs, 0, sizeof(fs));
118 unsigned short touch_cnt = static_cast<unsigned short>(input.touch_cnt);
119 HardwareState hs = make_hwstate(input.now, 0, touch_cnt, touch_cnt, fs);
120
121 ret = wrapper.SyncInterpret(hs, &timeout);
122
123 EXPECT_EQ(input.expected_call_next,
124 base_interpreter->sync_interpret_called_) << "i=" << i;
125 EXPECT_FALSE(base_interpreter->handle_timer_called_) << "i=" << i;
126 } else {
127 ret = wrapper.HandleTimer(input.now, &timeout);
128
129 EXPECT_EQ(input.expected_call_next,
130 base_interpreter->handle_timer_called_) << "i=" << i;
131 EXPECT_FALSE(base_interpreter->sync_interpret_called_) << "i=" << i;
132 }
133 EXPECT_FLOAT_EQ(input.expected_local_deadline,
134 interpreter.fling_stop_deadline_) << "i=" << i;
135 EXPECT_FLOAT_EQ(input.expected_next_deadline,
136 interpreter.next_timer_deadline_) << "i=" << i;
137 EXPECT_FLOAT_EQ(input.expected_timeout, timeout) << "i=" << i;
138 EXPECT_EQ(input.expected_fling_stop_out,
139 ret && ret->type == kGestureTypeFling &&
140 ret->details.fling.fling_state == GESTURES_FLING_TAP_DOWN)
141 << "i=" << i;
142 }
143 }
144
TEST(FlingStopFilterInterpreterTest,FlingGestureTest)145 TEST(FlingStopFilterInterpreterTest, FlingGestureTest) {
146 FlingStopFilterInterpreterTestInterpreter* base_interpreter =
147 new FlingStopFilterInterpreterTestInterpreter;
148 FlingStopFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
149 GESTURES_DEVCLASS_TOUCHPAD);
150
151 Gesture fling(kGestureFling, 0.0, 1.0, 0.0, 0.0, GESTURES_FLING_TAP_DOWN);
152 Gesture swipelift(kGestureSwipeLift, 1.0, 2.0);
153 Gesture swipe4flift(kGestureFourFingerSwipeLift, 1.0, 2.0);
154 Gesture move(kGestureMove, 1.0, 2.0, 3.0, 4.0);
155
156 interpreter.fling_stop_already_sent_ = true;
157 interpreter.ConsumeGesture(fling);
158 interpreter.ConsumeGesture(fling);
159 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFling);
160 interpreter.ConsumeGesture(swipelift);
161 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeSwipeLift);
162 interpreter.ConsumeGesture(swipe4flift);
163 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFourFingerSwipeLift);
164
165 interpreter.fling_stop_already_sent_ = false;
166 interpreter.ConsumeGesture(fling);
167 interpreter.ConsumeGesture(fling);
168 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFling);
169 interpreter.ConsumeGesture(swipelift);
170 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeSwipeLift);
171 interpreter.ConsumeGesture(swipe4flift);
172 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFourFingerSwipeLift);
173
174 interpreter.ConsumeGesture(move);
175 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeMove);
176 }
177
TEST(FlingStopFilterInterpreterTest,FlingStopMultimouseMoveTest)178 TEST(FlingStopFilterInterpreterTest, FlingStopMultimouseMoveTest) {
179 FlingStopFilterInterpreterTestInterpreter* base_interpreter =
180 new FlingStopFilterInterpreterTestInterpreter;
181 FlingStopFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
182 GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
183
184 Gesture move(kGestureMove, 1.0, 2.0, 3.0, 4.0);
185 interpreter.ConsumeGesture(move);
186 EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeMove);
187 }
188
189 } // namespace gestures
190