xref: /aosp_15_r20/external/libchrome-gestures/src/timestamp_filter_interpreter_unittest.cc (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
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