• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "gestures/TimerProvider.h"
18 
19 #include <vector>
20 
21 #include <gtest/gtest.h>
22 
23 #include "InterfaceMocks.h"
24 #include "TestConstants.h"
25 #include "include/gestures.h"
26 
27 namespace android {
28 
29 namespace {
30 
31 class TestTimerProvider : public TimerProvider {
32 public:
TestTimerProvider(InputReaderContext & context)33     TestTimerProvider(InputReaderContext& context) : TimerProvider(context) {}
34 
setCurrentTime(nsecs_t time)35     void setCurrentTime(nsecs_t time) { mCurrentTime = time; }
36 
37 protected:
getCurrentTime()38     nsecs_t getCurrentTime() override { return mCurrentTime; }
39 
40 private:
41     nsecs_t mCurrentTime = 0;
42 };
43 
pushTimeOntoVector(stime_t triggerTime,void * data)44 stime_t pushTimeOntoVector(stime_t triggerTime, void* data) {
45     std::vector<stime_t>* times = static_cast<std::vector<stime_t>*>(data);
46     times->push_back(triggerTime);
47     return NO_DEADLINE;
48 }
49 
copyTimeToVariable(stime_t triggerTime,void * data)50 stime_t copyTimeToVariable(stime_t triggerTime, void* data) {
51     stime_t* time = static_cast<stime_t*>(data);
52     *time = triggerTime;
53     return NO_DEADLINE;
54 }
55 
incrementInt(stime_t triggerTime,void * data)56 stime_t incrementInt(stime_t triggerTime, void* data) {
57     int* count = static_cast<int*>(data);
58     *count += 1;
59     return NO_DEADLINE;
60 }
61 
62 } // namespace
63 
64 using testing::AtLeast;
65 
66 class TimerProviderTest : public testing::Test {
67 public:
TimerProviderTest()68     TimerProviderTest() : mProvider(mMockContext) {}
69 
70 protected:
triggerCallbacksWithFakeTime(nsecs_t time)71     void triggerCallbacksWithFakeTime(nsecs_t time) {
72         mProvider.setCurrentTime(time);
73         mProvider.triggerCallbacks(time);
74     }
75 
76     MockInputReaderContext mMockContext;
77     TestTimerProvider mProvider;
78 };
79 
TEST_F(TimerProviderTest,SingleDeadlineTriggersWhenTimeoutIsExactlyOnTime)80 TEST_F(TimerProviderTest, SingleDeadlineTriggersWhenTimeoutIsExactlyOnTime) {
81     GesturesTimer* timer = mProvider.createTimer();
82     std::vector<stime_t> callTimes;
83     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(3);
84 
85     // Call through kGestureTimerProvider in this test case, so that we cover the stime_t to nsecs_t
86     // conversion code. This is why the delay is 1.0 rather than 1'000'000'000 here.
87     kGestureTimerProvider.set_fn(&mProvider, timer, 1.0, &pushTimeOntoVector, &callTimes);
88 
89     triggerCallbacksWithFakeTime(900'000'000);
90     triggerCallbacksWithFakeTime(999'999'999);
91     EXPECT_EQ(0u, callTimes.size());
92     triggerCallbacksWithFakeTime(1'000'000'000);
93     ASSERT_EQ(1u, callTimes.size());
94     EXPECT_NEAR(1.0, callTimes[0], EPSILON);
95 
96     // Now that the timer has triggered, it shouldn't trigger again if we get another timeout from
97     // InputReader.
98     triggerCallbacksWithFakeTime(1'300'000'000);
99     EXPECT_EQ(1u, callTimes.size());
100 }
101 
TEST_F(TimerProviderTest,SingleDeadlineTriggersWhenTimeoutIsLate)102 TEST_F(TimerProviderTest, SingleDeadlineTriggersWhenTimeoutIsLate) {
103     GesturesTimer* timer = mProvider.createTimer();
104     stime_t callTime = -1.0;
105     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(1);
106     mProvider.setDeadline(timer, 1'000'000'000, &copyTimeToVariable, &callTime);
107 
108     triggerCallbacksWithFakeTime(1'010'000'000);
109     EXPECT_NEAR(1.01, callTime, EPSILON);
110 }
111 
TEST_F(TimerProviderTest,SingleRescheduledDeadlineTriggers)112 TEST_F(TimerProviderTest, SingleRescheduledDeadlineTriggers) {
113     GesturesTimer* timer = mProvider.createTimer();
114     std::vector<stime_t> callTimes;
115     auto callback = [](stime_t triggerTime, void* callbackData) {
116         std::vector<stime_t>* times = static_cast<std::vector<stime_t>*>(callbackData);
117         times->push_back(triggerTime);
118         if (times->size() < 2) {
119             return 1.0;
120         } else {
121             return NO_DEADLINE;
122         }
123     };
124     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(1);
125     // The deadline should be rescheduled for 2.01s, since the first triggerCallbacks call is 0.01s
126     // late.
127     EXPECT_CALL(mMockContext, requestTimeoutAtTime(2'010'000'000)).Times(1);
128 
129     mProvider.setDeadline(timer, 1'000'000'000, callback, &callTimes);
130 
131     triggerCallbacksWithFakeTime(1'010'000'000);
132     ASSERT_EQ(1u, callTimes.size());
133     EXPECT_NEAR(1.01, callTimes[0], EPSILON);
134 
135     triggerCallbacksWithFakeTime(2'020'000'000);
136     ASSERT_EQ(2u, callTimes.size());
137     EXPECT_NEAR(1.01, callTimes[0], EPSILON);
138     EXPECT_NEAR(2.02, callTimes[1], EPSILON);
139 
140     triggerCallbacksWithFakeTime(3'000'000'000);
141     EXPECT_EQ(2u, callTimes.size());
142 }
143 
TEST_F(TimerProviderTest,MultipleDeadlinesTriggerWithMultipleTimeouts)144 TEST_F(TimerProviderTest, MultipleDeadlinesTriggerWithMultipleTimeouts) {
145     GesturesTimer* timer = mProvider.createTimer();
146     std::vector<stime_t> callTimes1;
147     std::vector<stime_t> callTimes2;
148 
149     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(AtLeast(1));
150     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'500'000'000)).Times(1);
151 
152     mProvider.setDeadline(timer, 1'000'000'000, &pushTimeOntoVector, &callTimes1);
153     mProvider.setDeadline(timer, 1'500'000'000, &pushTimeOntoVector, &callTimes2);
154 
155     EXPECT_EQ(0u, callTimes1.size());
156     EXPECT_EQ(0u, callTimes2.size());
157 
158     triggerCallbacksWithFakeTime(1'010'000'000);
159     ASSERT_EQ(1u, callTimes1.size());
160     EXPECT_NEAR(1.01, callTimes1[0], EPSILON);
161     EXPECT_EQ(0u, callTimes2.size());
162 
163     triggerCallbacksWithFakeTime(1'500'000'000);
164     EXPECT_EQ(1u, callTimes1.size());
165     ASSERT_EQ(1u, callTimes2.size());
166     EXPECT_NEAR(1.5, callTimes2[0], EPSILON);
167 }
168 
TEST_F(TimerProviderTest,MultipleDeadlinesTriggerWithOneLateTimeout)169 TEST_F(TimerProviderTest, MultipleDeadlinesTriggerWithOneLateTimeout) {
170     GesturesTimer* timer = mProvider.createTimer();
171     stime_t callTime1 = -1.0;
172     stime_t callTime2 = -1.0;
173 
174     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(AtLeast(1));
175 
176     mProvider.setDeadline(timer, 1'000'000'000, &copyTimeToVariable, &callTime1);
177     mProvider.setDeadline(timer, 1'500'000'000, &copyTimeToVariable, &callTime2);
178 
179     triggerCallbacksWithFakeTime(1'510'000'000);
180     EXPECT_NEAR(1.51, callTime1, EPSILON);
181     EXPECT_NEAR(1.51, callTime2, EPSILON);
182 }
183 
TEST_F(TimerProviderTest,MultipleDeadlinesAtSameTimeTriggerTogether)184 TEST_F(TimerProviderTest, MultipleDeadlinesAtSameTimeTriggerTogether) {
185     GesturesTimer* timer = mProvider.createTimer();
186     stime_t callTime1 = -1.0;
187     stime_t callTime2 = -1.0;
188 
189     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(AtLeast(1));
190 
191     mProvider.setDeadline(timer, 1'000'000'000, &copyTimeToVariable, &callTime1);
192     mProvider.setDeadline(timer, 1'000'000'000, &copyTimeToVariable, &callTime2);
193 
194     triggerCallbacksWithFakeTime(1'000'000'000);
195     EXPECT_NEAR(1.0, callTime1, EPSILON);
196     EXPECT_NEAR(1.0, callTime2, EPSILON);
197 }
198 
TEST_F(TimerProviderTest,MultipleTimersTriggerCorrectly)199 TEST_F(TimerProviderTest, MultipleTimersTriggerCorrectly) {
200     GesturesTimer* timer1 = mProvider.createTimer();
201     GesturesTimer* timer2 = mProvider.createTimer();
202     std::vector<stime_t> callTimes1;
203     std::vector<stime_t> callTimes2;
204 
205     EXPECT_CALL(mMockContext, requestTimeoutAtTime(500'000'000)).Times(AtLeast(1));
206     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'250'000'000)).Times(1);
207     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'500'000'000)).Times(1);
208 
209     mProvider.setDeadline(timer1, 500'000'000, &pushTimeOntoVector, &callTimes1);
210     mProvider.setDeadline(timer1, 1'250'000'000, &pushTimeOntoVector, &callTimes1);
211     mProvider.setDeadline(timer1, 1'500'000'000, &pushTimeOntoVector, &callTimes1);
212     mProvider.setDeadline(timer2, 750'000'000, &pushTimeOntoVector, &callTimes2);
213     mProvider.setDeadline(timer2, 1'250'000'000, &pushTimeOntoVector, &callTimes2);
214 
215     triggerCallbacksWithFakeTime(800'000'000);
216     ASSERT_EQ(1u, callTimes1.size());
217     EXPECT_NEAR(0.8, callTimes1[0], EPSILON);
218     ASSERT_EQ(1u, callTimes2.size());
219     EXPECT_NEAR(0.8, callTimes2[0], EPSILON);
220 
221     triggerCallbacksWithFakeTime(1'250'000'000);
222     ASSERT_EQ(2u, callTimes1.size());
223     EXPECT_NEAR(1.25, callTimes1[1], EPSILON);
224     ASSERT_EQ(2u, callTimes2.size());
225     EXPECT_NEAR(1.25, callTimes2[1], EPSILON);
226 
227     triggerCallbacksWithFakeTime(1'501'000'000);
228     ASSERT_EQ(3u, callTimes1.size());
229     EXPECT_NEAR(1.501, callTimes1[2], EPSILON);
230     EXPECT_EQ(2u, callTimes2.size());
231 }
232 
TEST_F(TimerProviderTest,CancelledTimerDoesntTrigger)233 TEST_F(TimerProviderTest, CancelledTimerDoesntTrigger) {
234     GesturesTimer* timer = mProvider.createTimer();
235     int numCalls = 0;
236 
237     EXPECT_CALL(mMockContext, requestTimeoutAtTime(500'000'000)).Times(AtLeast(1));
238     mProvider.setDeadline(timer, 500'000'000, &incrementInt, &numCalls);
239     mProvider.setDeadline(timer, 1'000'000'000, &incrementInt, &numCalls);
240     mProvider.cancelTimer(timer);
241 
242     triggerCallbacksWithFakeTime(1'100'000'000);
243     EXPECT_EQ(0, numCalls);
244 }
245 
TEST_F(TimerProviderTest,CancellingOneTimerDoesntAffectOthers)246 TEST_F(TimerProviderTest, CancellingOneTimerDoesntAffectOthers) {
247     GesturesTimer* timer1 = mProvider.createTimer();
248     GesturesTimer* timer2 = mProvider.createTimer();
249     int numCalls1 = 0;
250     int numCalls2 = 0;
251 
252     EXPECT_CALL(mMockContext, requestTimeoutAtTime(500'000'000)).Times(AtLeast(1));
253     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(1);
254 
255     mProvider.setDeadline(timer1, 500'000'000, &incrementInt, &numCalls1);
256     mProvider.setDeadline(timer2, 500'000'000, &incrementInt, &numCalls2);
257     mProvider.setDeadline(timer2, 1'000'000'000, &incrementInt, &numCalls2);
258     mProvider.cancelTimer(timer1);
259 
260     triggerCallbacksWithFakeTime(501'000'000);
261     EXPECT_EQ(0, numCalls1);
262     EXPECT_EQ(1, numCalls2);
263 
264     triggerCallbacksWithFakeTime(1'000'000'000);
265     EXPECT_EQ(0, numCalls1);
266     EXPECT_EQ(2, numCalls2);
267 }
268 
TEST_F(TimerProviderTest,CancellingOneTimerCausesNewTimeoutRequestForAnother)269 TEST_F(TimerProviderTest, CancellingOneTimerCausesNewTimeoutRequestForAnother) {
270     GesturesTimer* timer1 = mProvider.createTimer();
271     GesturesTimer* timer2 = mProvider.createTimer();
272     auto callback = [](stime_t, void*) { return NO_DEADLINE; };
273 
274     EXPECT_CALL(mMockContext, requestTimeoutAtTime(500'000'000)).Times(AtLeast(1));
275 
276     mProvider.setDeadline(timer1, 500'000'000, callback, nullptr);
277     mProvider.setDeadline(timer2, 1'000'000'000, callback, nullptr);
278 
279     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(1);
280     mProvider.cancelTimer(timer1);
281 }
282 
TEST_F(TimerProviderTest,CancelledTimerCanBeReused)283 TEST_F(TimerProviderTest, CancelledTimerCanBeReused) {
284     GesturesTimer* timer = mProvider.createTimer();
285     int numCallsBeforeCancellation = 0;
286     int numCallsAfterCancellation = 0;
287 
288     EXPECT_CALL(mMockContext, requestTimeoutAtTime(500'000'000)).Times(1);
289     EXPECT_CALL(mMockContext, requestTimeoutAtTime(1'000'000'000)).Times(1);
290 
291     mProvider.setDeadline(timer, 500'000'000, &incrementInt, &numCallsBeforeCancellation);
292     mProvider.cancelTimer(timer);
293     mProvider.setDeadline(timer, 1'000'000'000, &incrementInt, &numCallsAfterCancellation);
294 
295     triggerCallbacksWithFakeTime(1'000'000'000);
296     EXPECT_EQ(0, numCallsBeforeCancellation);
297     EXPECT_EQ(1, numCallsAfterCancellation);
298 }
299 
TEST_F(TimerProviderTest,FreeingTimerCancelsFirst)300 TEST_F(TimerProviderTest, FreeingTimerCancelsFirst) {
301     GesturesTimer* timer = mProvider.createTimer();
302     int numCalls = 0;
303 
304     mProvider.setDeadline(timer, 1'000'000'000, &incrementInt, &numCalls);
305     mProvider.freeTimer(timer);
306 
307     triggerCallbacksWithFakeTime(1'000'000'000);
308     EXPECT_EQ(0, numCalls);
309 }
310 
311 } // namespace android