1 // Copyright 2017 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/string_util.h"
9 #include "include/timestamp_filter_interpreter.h"
10 #include "include/unittest_util.h"
11 #include "include/util.h"
12
13 namespace gestures {
14
15 using EventDebug = ActivityLog::EventDebug;
16
17 class TimestampFilterInterpreterTest : public ::testing::Test {};
18 class TimestampFilterInterpreterParmTest :
19 public TimestampFilterInterpreterTest,
20 public testing::WithParamInterface<stime_t> {};
21
22 class TimestampFilterInterpreterTestInterpreter : public Interpreter {
23 public:
TimestampFilterInterpreterTestInterpreter()24 TimestampFilterInterpreterTestInterpreter()
25 : Interpreter(nullptr, nullptr, false) {}
HandleTimer(stime_t now,stime_t * timeout)26 virtual void HandleTimer(stime_t now, stime_t* timeout) {
27 // For tests, use timeout to return the adjusted timestamp.
28 *timeout = now;
29 }
30
31 };
32
make_hwstate_times(stime_t timestamp,stime_t msc_timestamp)33 static HardwareState make_hwstate_times(stime_t timestamp,
34 stime_t msc_timestamp) {
35 return { timestamp, 0, 1, 1, nullptr, 0, 0, 0, 0, 0, msc_timestamp };
36 }
37
TEST(TimestampFilterInterpreterTest,SimpleTest)38 TEST(TimestampFilterInterpreterTest, SimpleTest) {
39 TimestampFilterInterpreterTestInterpreter* base_interpreter =
40 new TimestampFilterInterpreterTestInterpreter;
41 TimestampFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
42 TestInterpreterWrapper wrapper(&interpreter);
43
44 HardwareState hs[] = {
45 make_hwstate_times(1.000, 0.000),
46 make_hwstate_times(1.010, 0.012),
47 make_hwstate_times(1.020, 0.018),
48 make_hwstate_times(1.030, 0.031),
49 };
50
51 stime_t expected_timestamps[] = { 1.000, 1.012, 1.018, 1.031 };
52
53 for (size_t i = 0; i < arraysize(hs); i++) {
54 wrapper.SyncInterpret(hs[i], nullptr);
55 EXPECT_EQ(hs[i].timestamp, expected_timestamps[i]);
56 }
57
58 stime_t adjusted_timestamp = 0.0;
59 wrapper.HandleTimer(2.0, &adjusted_timestamp);
60
61 // Should be adjusted by the maximum skew between timestamps.
62 EXPECT_FLOAT_EQ(adjusted_timestamp, 2.002);
63 }
64
TEST(TimestampFilterInterpreterTest,NoMscTimestampTest)65 TEST(TimestampFilterInterpreterTest, NoMscTimestampTest) {
66 TimestampFilterInterpreterTestInterpreter* base_interpreter =
67 new TimestampFilterInterpreterTestInterpreter;
68 TimestampFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
69 TestInterpreterWrapper wrapper(&interpreter);
70
71 HardwareState hs[] = {
72 make_hwstate_times(1.000, 0.000),
73 make_hwstate_times(1.010, 0.000),
74 make_hwstate_times(1.020, 0.000),
75 make_hwstate_times(1.030, 0.000),
76 };
77
78 for (size_t i = 0; i < arraysize(hs); i++) {
79 stime_t expected_timestamp = hs[i].timestamp;
80 wrapper.SyncInterpret(hs[i], nullptr);
81 EXPECT_EQ(hs[i].timestamp, expected_timestamp);
82 }
83
84 stime_t adjusted_timestamp = 0.0;
85 wrapper.HandleTimer(2.0, &adjusted_timestamp);
86
87 EXPECT_FLOAT_EQ(adjusted_timestamp, 2.0);
88 }
89
TEST(TimestampFilterInterpreterTest,MscTimestampResetTest)90 TEST(TimestampFilterInterpreterTest, MscTimestampResetTest) {
91 TimestampFilterInterpreterTestInterpreter* base_interpreter =
92 new TimestampFilterInterpreterTestInterpreter;
93 TimestampFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
94 TestInterpreterWrapper wrapper(&interpreter);
95
96 HardwareState hs[] = {
97 make_hwstate_times(1.000, 0.000),
98 make_hwstate_times(1.010, 0.012),
99 make_hwstate_times(1.020, 0.018),
100 make_hwstate_times(1.030, 0.035),
101 make_hwstate_times(3.000, 0.000), // msc_timestamp reset to 0
102 make_hwstate_times(3.010, 0.008),
103 make_hwstate_times(3.020, 0.020),
104 make_hwstate_times(3.030, 0.031),
105 };
106
107 stime_t expected_timestamps[] = {
108 1.000, 1.012, 1.018, 1.035,
109 3.000, 3.008, 3.020, 3.031
110 };
111
112 for (size_t i = 0; i < arraysize(hs); i++) {
113 wrapper.SyncInterpret(hs[i], nullptr);
114 EXPECT_EQ(hs[i].timestamp, expected_timestamps[i]);
115 }
116
117 stime_t adjusted_timestamp = 0.0;
118 wrapper.HandleTimer(4.0, &adjusted_timestamp);
119
120 // Should be adjusted by the maximum skew between timestamps, but only since
121 // the last reset.
122 EXPECT_FLOAT_EQ(adjusted_timestamp, 4.001);
123 }
124
TEST(TimestampFilterInterpreterTest,FakeTimestampTest)125 TEST(TimestampFilterInterpreterTest, FakeTimestampTest) {
126 TimestampFilterInterpreterTestInterpreter* base_interpreter =
127 new TimestampFilterInterpreterTestInterpreter;
128 TimestampFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
129 TestInterpreterWrapper wrapper(&interpreter);
130
131 interpreter.fake_timestamp_delta_.val_ = 0.010;
132
133 HardwareState hs[] = {
134 make_hwstate_times(1.000, 0.002),
135 make_hwstate_times(1.002, 6.553),
136 make_hwstate_times(1.008, 0.001),
137 make_hwstate_times(1.031, 0.001),
138 };
139
140 stime_t expected_timestamps[] = { 1.000, 1.010, 1.020, 1.030 };
141
142 for (size_t i = 0; i < arraysize(hs); i++) {
143 wrapper.SyncInterpret(hs[i], nullptr);
144 EXPECT_TRUE(DoubleEq(hs[i].timestamp, expected_timestamps[i]));
145 }
146
147 stime_t adjusted_timestamp = 0.0;
148 wrapper.HandleTimer(2.0, &adjusted_timestamp);
149
150 // Should be adjusted by the maximum skew between timestamps.
151 EXPECT_FLOAT_EQ(adjusted_timestamp, 2.012);
152 }
153
TEST(TimestampFilterInterpreterTest,FakeTimestampJumpForwardTest)154 TEST(TimestampFilterInterpreterTest, FakeTimestampJumpForwardTest) {
155 TimestampFilterInterpreterTestInterpreter* base_interpreter =
156 new TimestampFilterInterpreterTestInterpreter;
157 TimestampFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
158 TestInterpreterWrapper wrapper(&interpreter);
159
160 interpreter.fake_timestamp_delta_.val_ = 0.010;
161
162 HardwareState hs[] = {
163 make_hwstate_times(1.000, 0.002),
164 make_hwstate_times(1.002, 6.553),
165 make_hwstate_times(1.008, 0.001),
166 make_hwstate_times(1.031, 0.001),
167 make_hwstate_times(2.000, 6.552),
168 make_hwstate_times(2.002, 6.553),
169 make_hwstate_times(2.011, 0.002),
170 make_hwstate_times(2.031, 0.001),
171 };
172
173 stime_t expected_timestamps[] = {
174 1.000, 1.010, 1.020, 1.030,
175 2.000, 2.010, 2.020, 2.030
176 };
177
178 for (size_t i = 0; i < arraysize(hs); i++) {
179 wrapper.SyncInterpret(hs[i], nullptr);
180 EXPECT_TRUE(DoubleEq(hs[i].timestamp, expected_timestamps[i]));
181 }
182
183 stime_t adjusted_timestamp = 0.0;
184 wrapper.HandleTimer(3.0, &adjusted_timestamp);
185
186 // Should be adjusted by the maximum skew between timestamps, but only since
187 // the last reset.
188 EXPECT_FLOAT_EQ(adjusted_timestamp, 3.009);
189 }
190
TEST(TimestampFilterInterpreterTest,FakeTimestampFallBackwardTest)191 TEST(TimestampFilterInterpreterTest, FakeTimestampFallBackwardTest) {
192 TimestampFilterInterpreterTestInterpreter* base_interpreter =
193 new TimestampFilterInterpreterTestInterpreter;
194 TimestampFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
195 TestInterpreterWrapper wrapper(&interpreter);
196
197 interpreter.fake_timestamp_delta_.val_ = 0.010;
198 interpreter.fake_timestamp_max_divergence_ = 0.030;
199
200 HardwareState hs[] = {
201 make_hwstate_times(1.000, 0.002),
202 make_hwstate_times(1.001, 6.553),
203 make_hwstate_times(1.002, 0.001),
204 make_hwstate_times(1.003, 0.001),
205 make_hwstate_times(1.004, 6.552),
206 make_hwstate_times(1.005, 6.553),
207 make_hwstate_times(1.006, 0.002),
208 make_hwstate_times(1.009, 6.552),
209 };
210
211 stime_t expected_timestamps[] = {
212 1.000, 1.010, 1.020, 1.030,
213 1.004, 1.014, 1.024, 1.034,
214 };
215
216 for (size_t i = 0; i < arraysize(hs); i++) {
217 wrapper.SyncInterpret(hs[i], nullptr);
218 EXPECT_TRUE(DoubleEq(hs[i].timestamp, expected_timestamps[i]));
219 }
220
221 stime_t adjusted_timestamp = 0.0;
222 wrapper.HandleTimer(2.0, &adjusted_timestamp);
223
224 // Should be adjusted by the maximum skew between timestamps, but only since
225 // the last reset.
226 EXPECT_FLOAT_EQ(adjusted_timestamp, 2.025);
227 }
228
TEST(TimestampFilterInterpreterTest,GestureDebugTest)229 TEST(TimestampFilterInterpreterTest, GestureDebugTest) {
230 PropRegistry prop_reg;
231 TimestampFilterInterpreter interpreter(&prop_reg, nullptr, nullptr);
232
233 using EventDebug = ActivityLog::EventDebug;
234 interpreter.SetEventLoggingEnabled(true);
235 interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
236 interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
237 interpreter.EventDebugLoggingEnable(EventDebug::HandleTimer);
238 interpreter.EventDebugLoggingEnable(EventDebug::Timestamp);
239 interpreter.log_.reset(new ActivityLog(&prop_reg));
240
241 EXPECT_EQ(interpreter.log_->size(), 0);
242 interpreter.ConsumeGesture(Gesture(kGestureButtonsChange,
243 1, // start time
244 2, // end time
245 0, // down
246 0, // up
247 false)); // is_tap
248
249 // Encode the log into Json
250 Json::Value node;
251 Json::Value tree = interpreter.log_->EncodeCommonInfo();
252
253 // Verify the Json information
254 EXPECT_EQ(interpreter.log_->size(), 3);
255 node = tree[ActivityLog::kKeyRoot][0];
256 EXPECT_EQ(node[ActivityLog::kKeyType],
257 Json::Value(ActivityLog::kKeyGestureConsume));
258 node = tree[ActivityLog::kKeyRoot][1];
259 EXPECT_EQ(node[ActivityLog::kKeyType],
260 Json::Value(ActivityLog::kKeyTimestampGestureDebug));
261 EXPECT_EQ(node[ActivityLog::kKeyTimestampDebugSkew],
262 Json::Value(interpreter.skew_));
263 node = tree[ActivityLog::kKeyRoot][2];
264 EXPECT_EQ(node[ActivityLog::kKeyType],
265 Json::Value(ActivityLog::kKeyGestureProduce));
266 interpreter.log_->Clear();
267 }
268
TEST_P(TimestampFilterInterpreterParmTest,TimestampDebugLoggingTest)269 TEST_P(TimestampFilterInterpreterParmTest, TimestampDebugLoggingTest) {
270 PropRegistry prop_reg;
271 TimestampFilterInterpreterTestInterpreter* base_interpreter =
272 new TimestampFilterInterpreterTestInterpreter;
273 TimestampFilterInterpreter interpreter(&prop_reg, base_interpreter, nullptr);
274 TestInterpreterWrapper wrapper(&interpreter);
275
276 interpreter.SetEventLoggingEnabled(true);
277 interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
278 interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
279 interpreter.EventDebugLoggingEnable(EventDebug::HandleTimer);
280 interpreter.EventDebugLoggingEnable(EventDebug::Timestamp);
281 interpreter.log_.reset(new ActivityLog(&prop_reg));
282 interpreter.fake_timestamp_delta_.val_ = GetParam();
283
284 HardwareState hs = make_hwstate_times(1.000, 0.000);
285 wrapper.SyncInterpret(hs, nullptr);
286
287 // Encode the log into Json
288 Json::Value node;
289 Json::Value tree = interpreter.log_->EncodeCommonInfo();
290
291 // Verify the Json information
292 EXPECT_EQ(interpreter.log_->size(), 4);
293 node = tree[ActivityLog::kKeyRoot][0];
294 EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
295 ActivityLog::kKeyHardwareState);
296 node = tree[ActivityLog::kKeyRoot][1];
297 EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
298 ActivityLog::kKeyHardwareStatePre);
299
300 node = tree[ActivityLog::kKeyRoot][2];
301 EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
302 ActivityLog::kKeyTimestampHardwareStateDebug);
303 if (interpreter.fake_timestamp_delta_.val_ == 0.0) {
304 EXPECT_FALSE(node[ActivityLog::kKeyTimestampDebugIsUsingFake].asBool());
305 } else {
306 EXPECT_TRUE(node[ActivityLog::kKeyTimestampDebugIsUsingFake].asBool());
307 }
308
309 node = tree[ActivityLog::kKeyRoot][3];
310 EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
311 ActivityLog::kKeyHardwareStatePost);
312 interpreter.log_->Clear();
313 }
314
315 INSTANTIATE_TEST_SUITE_P(TimestampFilterInterpreter,
316 TimestampFilterInterpreterParmTest,
317 testing::Values(0.000, 0.010));
318
319 } // namespace gestures
320