1 /*
2  * Copyright 2019 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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 #pragma clang diagnostic ignored "-Wextra"
21 
22 #undef LOG_TAG
23 #define LOG_TAG "LibSurfaceFlingerUnittests"
24 #define LOG_NDEBUG 0
25 
26 #include <thread>
27 
28 #include <gmock/gmock.h>
29 #include <gtest/gtest.h>
30 
31 #include <scheduler/TimeKeeper.h>
32 
33 #include <common/test/FlagUtils.h>
34 #include "Scheduler/VSyncDispatchTimerQueue.h"
35 #include "Scheduler/VSyncTracker.h"
36 #include "mock/MockVSyncTracker.h"
37 
38 #include <com_android_graphics_surfaceflinger_flags.h>
39 
40 using namespace testing;
41 using namespace std::literals;
42 
43 namespace android::scheduler {
44 using namespace com::android::graphics::surfaceflinger;
45 
46 class MockVSyncTracker : public mock::VSyncTracker {
47 public:
MockVSyncTracker(nsecs_t period)48     MockVSyncTracker(nsecs_t period) : mPeriod{period} {
49         ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_, _))
50                 .WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
51         ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
52         ON_CALL(*this, currentPeriod())
53                 .WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
54     }
55 
nextVSyncTime(nsecs_t timePoint,std::optional<nsecs_t>) const56     nsecs_t nextVSyncTime(nsecs_t timePoint, std::optional<nsecs_t>) const {
57         if (timePoint % mPeriod == 0) {
58             return timePoint;
59         }
60         return (timePoint - (timePoint % mPeriod) + mPeriod);
61     }
62 
getCurrentPeriod() const63     nsecs_t getCurrentPeriod() const { return mPeriod; }
64 
65 protected:
66     nsecs_t const mPeriod;
67 };
68 
69 class ControllableClock : public TimeKeeper {
70 public:
ControllableClock()71     ControllableClock() {
72         ON_CALL(*this, alarmAt(_, _))
73                 .WillByDefault(Invoke(this, &ControllableClock::alarmAtDefaultBehavior));
74         ON_CALL(*this, now()).WillByDefault(Invoke(this, &ControllableClock::fakeTime));
75     }
76 
77     MOCK_METHOD(nsecs_t, now, (), (const));
78     MOCK_METHOD(void, alarmAt, (std::function<void()>, nsecs_t), (override));
79     MOCK_METHOD(void, alarmCancel, (), (override));
80     MOCK_METHOD(void, dump, (std::string&), (const, override));
81 
alarmAtDefaultBehavior(std::function<void ()> const & callback,nsecs_t time)82     void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
83         mCallback = callback;
84         mNextCallbackTime = time;
85     }
86 
fakeTime() const87     nsecs_t fakeTime() const { return mCurrentTime; }
88 
advanceToNextCallback()89     void advanceToNextCallback() {
90         mCurrentTime = mNextCallbackTime;
91         if (mCallback) {
92             mCallback();
93         }
94     }
95 
advanceBy(nsecs_t advancement)96     void advanceBy(nsecs_t advancement) {
97         mCurrentTime += advancement;
98         if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
99             mCallback();
100         }
101     };
102 
setLag(nsecs_t lag)103     void setLag(nsecs_t lag) { mLag = lag; }
104 
105 private:
106     std::function<void()> mCallback;
107     nsecs_t mNextCallbackTime = 0;
108     nsecs_t mCurrentTime = 0;
109     nsecs_t mLag = 0;
110 };
111 
112 class CountingCallback {
113 public:
CountingCallback(std::shared_ptr<VSyncDispatch> dispatch)114     CountingCallback(std::shared_ptr<VSyncDispatch> dispatch)
115           : mDispatch(std::move(dispatch)),
116             mToken(mDispatch->registerCallback(std::bind(&CountingCallback::counter, this,
117                                                          std::placeholders::_1,
118                                                          std::placeholders::_2,
119                                                          std::placeholders::_3),
120                                                "test")) {}
~CountingCallback()121     ~CountingCallback() { mDispatch->unregisterCallback(mToken); }
122 
operator VSyncDispatch::CallbackToken() const123     operator VSyncDispatch::CallbackToken() const { return mToken; }
124 
counter(nsecs_t time,nsecs_t wakeup_time,nsecs_t readyTime)125     void counter(nsecs_t time, nsecs_t wakeup_time, nsecs_t readyTime) {
126         mCalls.push_back(time);
127         mWakeupTime.push_back(wakeup_time);
128         mReadyTime.push_back(readyTime);
129     }
130 
131     std::shared_ptr<VSyncDispatch> mDispatch;
132     VSyncDispatch::CallbackToken mToken;
133     std::vector<nsecs_t> mCalls;
134     std::vector<nsecs_t> mWakeupTime;
135     std::vector<nsecs_t> mReadyTime;
136 };
137 
138 class PausingCallback {
139 public:
PausingCallback(std::shared_ptr<VSyncDispatch> dispatch,std::chrono::milliseconds pauseAmount)140     PausingCallback(std::shared_ptr<VSyncDispatch> dispatch, std::chrono::milliseconds pauseAmount)
141           : mDispatch(std::move(dispatch)),
142             mToken(mDispatch->registerCallback(std::bind(&PausingCallback::pause, this,
143                                                          std::placeholders::_1,
144                                                          std::placeholders::_2),
145                                                "test")),
146             mRegistered(true),
147             mPauseAmount(pauseAmount) {}
~PausingCallback()148     ~PausingCallback() { unregister(); }
149 
operator VSyncDispatch::CallbackToken() const150     operator VSyncDispatch::CallbackToken() const { return mToken; }
151 
pause(nsecs_t,nsecs_t)152     void pause(nsecs_t, nsecs_t) {
153         std::unique_lock lock(mMutex);
154         mPause = true;
155         mCv.notify_all();
156 
157         mCv.wait_for(lock, mPauseAmount, [this] { return !mPause; });
158 
159         mResourcePresent = (mResource.lock() != nullptr);
160     }
161 
waitForPause()162     bool waitForPause() {
163         std::unique_lock lock(mMutex);
164         auto waiting = mCv.wait_for(lock, 10s, [this] { return mPause; });
165         return waiting;
166     }
167 
stashResource(std::weak_ptr<void> const & resource)168     void stashResource(std::weak_ptr<void> const& resource) { mResource = resource; }
169 
resourcePresent()170     bool resourcePresent() { return mResourcePresent; }
171 
unpause()172     void unpause() {
173         std::unique_lock lock(mMutex);
174         mPause = false;
175         mCv.notify_all();
176     }
177 
unregister()178     void unregister() {
179         if (mRegistered) {
180             mDispatch->unregisterCallback(mToken);
181             mRegistered = false;
182         }
183     }
184 
185     std::shared_ptr<VSyncDispatch> mDispatch;
186     VSyncDispatch::CallbackToken mToken;
187     bool mRegistered = true;
188 
189     std::mutex mMutex;
190     std::condition_variable mCv;
191     bool mPause = false;
192     std::weak_ptr<void> mResource;
193     bool mResourcePresent = false;
194     std::chrono::milliseconds const mPauseAmount;
195 };
196 
197 class VSyncDispatchTimerQueueTest : public testing::Test {
198 protected:
createTimeKeeper()199     std::unique_ptr<TimeKeeper> createTimeKeeper() {
200         class TimeKeeperWrapper : public TimeKeeper {
201         public:
202             TimeKeeperWrapper(TimeKeeper& control) : mControllableClock(control) {}
203 
204             nsecs_t now() const final { return mControllableClock.now(); }
205 
206             void alarmAt(std::function<void()> callback, nsecs_t time) final {
207                 mControllableClock.alarmAt(std::move(callback), time);
208             }
209 
210             void alarmCancel() final { mControllableClock.alarmCancel(); }
211             void dump(std::string&) const final {}
212 
213         private:
214             TimeKeeper& mControllableClock;
215         };
216         return std::make_unique<TimeKeeperWrapper>(mMockClock);
217     }
218 
~VSyncDispatchTimerQueueTest()219     ~VSyncDispatchTimerQueueTest() {
220         // destructor of  dispatch will cancelAlarm(). Ignore final cancel in common test.
221         Mock::VerifyAndClearExpectations(&mMockClock);
222     }
223 
advanceToNextCallback()224     void advanceToNextCallback() { mMockClock.advanceToNextCallback(); }
225 
226     NiceMock<ControllableClock> mMockClock;
227     static nsecs_t constexpr mDispatchGroupThreshold = 5;
228     nsecs_t const mPeriod = 1000;
229     nsecs_t const mVsyncMoveThreshold = 300;
230     std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
231             std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
232     std::shared_ptr<VSyncDispatch> mDispatch =
233             std::make_shared<VSyncDispatchTimerQueue>(createTimeKeeper(), mStubTracker,
234                                                       mDispatchGroupThreshold, mVsyncMoveThreshold);
235 };
236 
TEST_F(VSyncDispatchTimerQueueTest,unregistersSetAlarmOnDestruction)237 TEST_F(VSyncDispatchTimerQueueTest, unregistersSetAlarmOnDestruction) {
238     EXPECT_CALL(mMockClock, alarmAt(_, 900));
239     EXPECT_CALL(mMockClock, alarmCancel());
240     {
241         std::shared_ptr<VSyncDispatch> mDispatch =
242                 std::make_shared<VSyncDispatchTimerQueue>(createTimeKeeper(), mStubTracker,
243                                                           mDispatchGroupThreshold,
244                                                           mVsyncMoveThreshold);
245         CountingCallback cb(mDispatch);
246         const auto result =
247                 mDispatch->schedule(cb,
248                                     {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
249         EXPECT_TRUE(result.has_value());
250         EXPECT_EQ(900, result->callbackTime.ns());
251         EXPECT_EQ(1000, result->vsyncTime.ns());
252     }
253 }
254 
TEST_F(VSyncDispatchTimerQueueTest,basicAlarmSettingFuture)255 TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFuture) {
256     auto intended = mPeriod - 230;
257     EXPECT_CALL(mMockClock, alarmAt(_, 900));
258 
259     CountingCallback cb(mDispatch);
260     const auto result =
261             mDispatch->schedule(cb,
262                                 {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
263     EXPECT_TRUE(result.has_value());
264     EXPECT_EQ(900, result->callbackTime.ns());
265     EXPECT_EQ(1000, result->vsyncTime.ns());
266 
267     advanceToNextCallback();
268 
269     ASSERT_THAT(cb.mCalls.size(), Eq(1));
270     EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
271 }
272 
TEST_F(VSyncDispatchTimerQueueTest,updateAlarmSettingFuture)273 TEST_F(VSyncDispatchTimerQueueTest, updateAlarmSettingFuture) {
274     auto intended = mPeriod - 230;
275     Sequence seq;
276     EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
277     EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
278 
279     CountingCallback cb(mDispatch);
280     auto result =
281             mDispatch->schedule(cb,
282                                 {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
283     EXPECT_TRUE(result.has_value());
284     EXPECT_EQ(900, result->callbackTime.ns());
285     EXPECT_EQ(1000, result->vsyncTime.ns());
286 
287     result =
288             mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
289     EXPECT_TRUE(result.has_value());
290     EXPECT_EQ(700, result->callbackTime.ns());
291     EXPECT_EQ(1000, result->vsyncTime.ns());
292 
293     advanceToNextCallback();
294 
295     ASSERT_THAT(cb.mCalls.size(), Eq(1));
296     EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
297     EXPECT_THAT(cb.mWakeupTime[0], Eq(700));
298 }
299 
TEST_F(VSyncDispatchTimerQueueTest,updateDoesntSchedule)300 TEST_F(VSyncDispatchTimerQueueTest, updateDoesntSchedule) {
301     auto intended = mPeriod - 230;
302     EXPECT_CALL(mMockClock, alarmAt(_, _)).Times(0);
303 
304     CountingCallback cb(mDispatch);
305     const auto result =
306             mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
307     EXPECT_FALSE(result.has_value());
308 }
309 
TEST_F(VSyncDispatchTimerQueueTest,basicAlarmSettingFutureWithAdjustmentToTrueVsync)310 TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
311     EXPECT_CALL(*mStubTracker.get(),
312                 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(mPeriod)))
313             .WillOnce(Return(1150));
314     EXPECT_CALL(mMockClock, alarmAt(_, 1050));
315 
316     CountingCallback cb(mDispatch);
317     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
318     advanceToNextCallback();
319 
320     ASSERT_THAT(cb.mCalls.size(), Eq(1));
321     EXPECT_THAT(cb.mCalls[0], Eq(1150));
322 }
323 
TEST_F(VSyncDispatchTimerQueueTest,basicAlarmSettingAdjustmentPast)324 TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingAdjustmentPast) {
325     auto const now = 234;
326     mMockClock.advanceBy(234);
327     auto const workDuration = 10 * mPeriod;
328     EXPECT_CALL(*mStubTracker.get(),
329                 nextAnticipatedVSyncTimeFrom(now + workDuration, std::optional<nsecs_t>(mPeriod)))
330             .WillOnce(Return(mPeriod * 11));
331     EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
332 
333     CountingCallback cb(mDispatch);
334     const auto result = mDispatch->schedule(cb,
335                                             {.workDuration = workDuration,
336                                              .readyDuration = 0,
337                                              .lastVsync = mPeriod});
338     EXPECT_TRUE(result.has_value());
339     EXPECT_EQ(mPeriod, result->callbackTime.ns());
340     EXPECT_EQ(workDuration + mPeriod, result->vsyncTime.ns());
341 }
342 
TEST_F(VSyncDispatchTimerQueueTest,basicAlarmCancel)343 TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancel) {
344     EXPECT_CALL(mMockClock, alarmAt(_, 900));
345     EXPECT_CALL(mMockClock, alarmCancel());
346 
347     CountingCallback cb(mDispatch);
348     const auto result =
349             mDispatch->schedule(cb,
350                                 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
351     EXPECT_TRUE(result.has_value());
352     EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
353     EXPECT_EQ(mPeriod, result->vsyncTime.ns());
354     EXPECT_EQ(mDispatch->cancel(cb), CancelResult::Cancelled);
355 }
356 
TEST_F(VSyncDispatchTimerQueueTest,basicAlarmCancelTooLate)357 TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLate) {
358     EXPECT_CALL(mMockClock, alarmAt(_, 900));
359     EXPECT_CALL(mMockClock, alarmCancel());
360 
361     CountingCallback cb(mDispatch);
362     const auto result =
363             mDispatch->schedule(cb,
364                                 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
365     EXPECT_TRUE(result.has_value());
366     EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
367     EXPECT_EQ(mPeriod, result->vsyncTime.ns());
368     mMockClock.advanceBy(950);
369     EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
370 }
371 
TEST_F(VSyncDispatchTimerQueueTest,basicAlarmCancelTooLateWhenRunning)372 TEST_F(VSyncDispatchTimerQueueTest, basicAlarmCancelTooLateWhenRunning) {
373     EXPECT_CALL(mMockClock, alarmAt(_, 900));
374     EXPECT_CALL(mMockClock, alarmCancel());
375 
376     PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
377     const auto result =
378             mDispatch->schedule(cb,
379                                 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
380     EXPECT_TRUE(result.has_value());
381     EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
382     EXPECT_EQ(mPeriod, result->vsyncTime.ns());
383 
384     std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
385     EXPECT_TRUE(cb.waitForPause());
386     EXPECT_EQ(mDispatch->cancel(cb), CancelResult::TooLate);
387     cb.unpause();
388     pausingThread.join();
389 }
390 
TEST_F(VSyncDispatchTimerQueueTest,unregisterSynchronizes)391 TEST_F(VSyncDispatchTimerQueueTest, unregisterSynchronizes) {
392     EXPECT_CALL(mMockClock, alarmAt(_, 900));
393     EXPECT_CALL(mMockClock, alarmCancel());
394 
395     auto resource = std::make_shared<int>(110);
396 
397     PausingCallback cb(mDispatch, 50ms);
398     cb.stashResource(resource);
399     const auto result =
400             mDispatch->schedule(cb,
401                                 {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
402     EXPECT_TRUE(result.has_value());
403     EXPECT_EQ(mPeriod - 100, result->callbackTime.ns());
404     EXPECT_EQ(mPeriod, result->vsyncTime.ns());
405 
406     std::thread pausingThread([&] { mMockClock.advanceToNextCallback(); });
407     EXPECT_TRUE(cb.waitForPause());
408 
409     cb.unregister();
410     resource.reset();
411 
412     cb.unpause();
413     pausingThread.join();
414 
415     EXPECT_TRUE(cb.resourcePresent());
416 }
417 
TEST_F(VSyncDispatchTimerQueueTest,basicTwoAlarmSetting)418 TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
419     EXPECT_CALL(*mStubTracker.get(),
420                 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
421             .Times(4)
422             .WillOnce(Return(1055))
423             .WillOnce(Return(1063))
424             .WillOnce(Return(1063))
425             .WillOnce(Return(1075));
426 
427     Sequence seq;
428     EXPECT_CALL(mMockClock, alarmAt(_, 955)).InSequence(seq);
429     EXPECT_CALL(mMockClock, alarmAt(_, 813)).InSequence(seq);
430     EXPECT_CALL(mMockClock, alarmAt(_, 975)).InSequence(seq);
431 
432     CountingCallback cb0(mDispatch);
433     CountingCallback cb1(mDispatch);
434 
435     mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
436     mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
437 
438     advanceToNextCallback();
439     advanceToNextCallback();
440 
441     ASSERT_THAT(cb0.mCalls.size(), Eq(1));
442     EXPECT_THAT(cb0.mCalls[0], Eq(1075));
443     ASSERT_THAT(cb1.mCalls.size(), Eq(1));
444     EXPECT_THAT(cb1.mCalls[0], Eq(1063));
445 }
446 
TEST_F(VSyncDispatchTimerQueueTest,noCloseCallbacksAfterPeriodChange)447 TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
448     EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
449             .Times(4)
450             .WillOnce(Return(1000))
451             .WillOnce(Return(2000))
452             .WillOnce(Return(2500))
453             .WillOnce(Return(4000));
454 
455     Sequence seq;
456     EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
457     EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
458     EXPECT_CALL(mMockClock, alarmAt(_, 3900)).InSequence(seq);
459 
460     CountingCallback cb(mDispatch);
461 
462     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 0});
463 
464     advanceToNextCallback();
465 
466     ASSERT_THAT(cb.mCalls.size(), Eq(1));
467     EXPECT_THAT(cb.mCalls[0], Eq(1000));
468 
469     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
470 
471     advanceToNextCallback();
472 
473     ASSERT_THAT(cb.mCalls.size(), Eq(2));
474     EXPECT_THAT(cb.mCalls[1], Eq(2000));
475 
476     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
477 
478     advanceToNextCallback();
479 
480     ASSERT_THAT(cb.mCalls.size(), Eq(3));
481     EXPECT_THAT(cb.mCalls[2], Eq(4000));
482 }
483 
TEST_F(VSyncDispatchTimerQueueTest,rearmsFaroutTimeoutWhenCancellingCloseOne)484 TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
485     EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
486             .Times(4)
487             .WillOnce(Return(10000))
488             .WillOnce(Return(1000))
489             .WillOnce(Return(10000))
490             .WillOnce(Return(10000));
491 
492     Sequence seq;
493     EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
494     EXPECT_CALL(mMockClock, alarmAt(_, 750)).InSequence(seq);
495     EXPECT_CALL(mMockClock, alarmAt(_, 9900)).InSequence(seq);
496 
497     CountingCallback cb0(mDispatch);
498     CountingCallback cb1(mDispatch);
499 
500     mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod * 10});
501     mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
502     mDispatch->cancel(cb1);
503 }
504 
TEST_F(VSyncDispatchTimerQueueTest,noUnnecessaryRearmsWhenRescheduling)505 TEST_F(VSyncDispatchTimerQueueTest, noUnnecessaryRearmsWhenRescheduling) {
506     Sequence seq;
507     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
508     EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
509 
510     CountingCallback cb0(mDispatch);
511     CountingCallback cb1(mDispatch);
512 
513     mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
514     mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
515     mDispatch->schedule(cb1, {.workDuration = 300, .readyDuration = 0, .lastVsync = 1000});
516     advanceToNextCallback();
517 }
518 
TEST_F(VSyncDispatchTimerQueueTest,necessaryRearmsWhenModifying)519 TEST_F(VSyncDispatchTimerQueueTest, necessaryRearmsWhenModifying) {
520     Sequence seq;
521     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
522     EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
523     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
524 
525     CountingCallback cb0(mDispatch);
526     CountingCallback cb1(mDispatch);
527 
528     mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
529     mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
530     mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
531     advanceToNextCallback();
532 }
533 
TEST_F(VSyncDispatchTimerQueueTest,modifyIntoGroup)534 TEST_F(VSyncDispatchTimerQueueTest, modifyIntoGroup) {
535     Sequence seq;
536     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
537     EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
538     EXPECT_CALL(mMockClock, alarmAt(_, 1590)).InSequence(seq);
539     EXPECT_CALL(mMockClock, alarmAt(_, 1600)).InSequence(seq);
540 
541     auto offset = 400;
542     auto closeOffset = offset + mDispatchGroupThreshold - 1;
543     auto notCloseOffset = offset + 2 * mDispatchGroupThreshold;
544 
545     CountingCallback cb0(mDispatch);
546     CountingCallback cb1(mDispatch);
547 
548     mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
549     mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
550     mDispatch->schedule(cb1, {.workDuration = closeOffset, .readyDuration = 0, .lastVsync = 1000});
551 
552     advanceToNextCallback();
553     ASSERT_THAT(cb0.mCalls.size(), Eq(1));
554     EXPECT_THAT(cb0.mCalls[0], Eq(mPeriod));
555     ASSERT_THAT(cb1.mCalls.size(), Eq(1));
556     EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
557 
558     mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 2000});
559     mDispatch->schedule(cb1,
560                         {.workDuration = notCloseOffset, .readyDuration = 0, .lastVsync = 2000});
561     advanceToNextCallback();
562     ASSERT_THAT(cb1.mCalls.size(), Eq(2));
563     EXPECT_THAT(cb1.mCalls[1], Eq(2000));
564 
565     advanceToNextCallback();
566     ASSERT_THAT(cb0.mCalls.size(), Eq(2));
567     EXPECT_THAT(cb0.mCalls[1], Eq(2000));
568 }
569 
TEST_F(VSyncDispatchTimerQueueTest,rearmsWhenEndingAndDoesntCancel)570 TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenEndingAndDoesntCancel) {
571     Sequence seq;
572     EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
573     EXPECT_CALL(mMockClock, alarmAt(_, 800)).InSequence(seq);
574     EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
575     EXPECT_CALL(mMockClock, alarmCancel());
576 
577     CountingCallback cb0(mDispatch);
578     CountingCallback cb1(mDispatch);
579 
580     mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
581     mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
582     advanceToNextCallback();
583     EXPECT_EQ(mDispatch->cancel(cb0), CancelResult::Cancelled);
584 }
585 
TEST_F(VSyncDispatchTimerQueueTest,setAlarmCallsAtCorrectTimeWithChangingVsync)586 TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
587     EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
588             .Times(3)
589             .WillOnce(Return(950))
590             .WillOnce(Return(1975))
591             .WillOnce(Return(2950));
592 
593     CountingCallback cb(mDispatch);
594     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 920});
595 
596     mMockClock.advanceBy(850);
597     EXPECT_THAT(cb.mCalls.size(), Eq(1));
598 
599     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1900});
600     mMockClock.advanceBy(900);
601     EXPECT_THAT(cb.mCalls.size(), Eq(1));
602     mMockClock.advanceBy(125);
603     EXPECT_THAT(cb.mCalls.size(), Eq(2));
604 
605     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2900});
606     mMockClock.advanceBy(975);
607     EXPECT_THAT(cb.mCalls.size(), Eq(3));
608 }
609 
TEST_F(VSyncDispatchTimerQueueTest,callbackReentrancy)610 TEST_F(VSyncDispatchTimerQueueTest, callbackReentrancy) {
611     Sequence seq;
612     EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
613     EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
614 
615     VSyncDispatch::CallbackToken tmp;
616     tmp = mDispatch->registerCallback(
617             [&](auto, auto, auto) {
618                 mDispatch->schedule(tmp,
619                                     {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
620             },
621             "o.o");
622 
623     mDispatch->schedule(tmp, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
624     advanceToNextCallback();
625 }
626 
TEST_F(VSyncDispatchTimerQueueTest,callbackReentrantWithPastWakeup)627 TEST_F(VSyncDispatchTimerQueueTest, callbackReentrantWithPastWakeup) {
628     VSyncDispatch::CallbackToken tmp;
629     std::optional<nsecs_t> lastTarget;
630     tmp = mDispatch->registerCallback(
631             [&](auto timestamp, auto, auto) {
632                 auto result = mDispatch->schedule(tmp,
633                                                   {.workDuration = 400,
634                                                    .readyDuration = 0,
635                                                    .lastVsync = timestamp - mVsyncMoveThreshold});
636                 EXPECT_TRUE(result.has_value());
637                 EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
638                 EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
639                 result = mDispatch->schedule(tmp,
640                                              {.workDuration = 400,
641                                               .readyDuration = 0,
642                                               .lastVsync = timestamp});
643                 EXPECT_TRUE(result.has_value());
644                 EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
645                 EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
646                 result = mDispatch->schedule(tmp,
647                                              {.workDuration = 400,
648                                               .readyDuration = 0,
649                                               .lastVsync = timestamp + mVsyncMoveThreshold});
650                 EXPECT_TRUE(result.has_value());
651                 EXPECT_EQ(mPeriod + timestamp - 400, result->callbackTime.ns());
652                 EXPECT_EQ(mPeriod + timestamp, result->vsyncTime.ns());
653                 lastTarget = timestamp;
654             },
655             "oo");
656 
657     mDispatch->schedule(tmp, {.workDuration = 999, .readyDuration = 0, .lastVsync = 1000});
658     advanceToNextCallback();
659     EXPECT_THAT(lastTarget, Eq(1000));
660 
661     advanceToNextCallback();
662     EXPECT_THAT(lastTarget, Eq(2000));
663 }
664 
TEST_F(VSyncDispatchTimerQueueTest,modificationsAroundVsyncTime)665 TEST_F(VSyncDispatchTimerQueueTest, modificationsAroundVsyncTime) {
666     Sequence seq;
667     EXPECT_CALL(mMockClock, alarmAt(_, 1000)).InSequence(seq);
668     EXPECT_CALL(mMockClock, alarmAt(_, 950)).InSequence(seq);
669     EXPECT_CALL(mMockClock, alarmAt(_, 1950)).InSequence(seq);
670     EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
671 
672     CountingCallback cb(mDispatch);
673     mDispatch->schedule(cb, {.workDuration = 0, .readyDuration = 0, .lastVsync = 1000});
674 
675     mMockClock.advanceBy(750);
676     mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 1000});
677 
678     advanceToNextCallback();
679     mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 2000});
680 
681     mMockClock.advanceBy(800);
682     mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
683 }
684 
TEST_F(VSyncDispatchTimerQueueTest,lateModifications)685 TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
686     Sequence seq;
687     EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
688     EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
689     EXPECT_CALL(mMockClock, alarmAt(_, 850)).InSequence(seq);
690     EXPECT_CALL(mMockClock, alarmAt(_, 1800)).InSequence(seq);
691 
692     CountingCallback cb0(mDispatch);
693     CountingCallback cb1(mDispatch);
694 
695     mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
696     mDispatch->schedule(cb1, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
697 
698     advanceToNextCallback();
699     mDispatch->schedule(cb0, {.workDuration = 200, .readyDuration = 0, .lastVsync = 2000});
700     mDispatch->schedule(cb1, {.workDuration = 150, .readyDuration = 0, .lastVsync = 1000});
701 
702     advanceToNextCallback();
703     advanceToNextCallback();
704 }
705 
TEST_F(VSyncDispatchTimerQueueTest,doesntCancelPriorValidTimerForFutureMod)706 TEST_F(VSyncDispatchTimerQueueTest, doesntCancelPriorValidTimerForFutureMod) {
707     Sequence seq;
708     EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
709 
710     CountingCallback cb0(mDispatch);
711     CountingCallback cb1(mDispatch);
712     mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
713     mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 20000});
714 }
715 
TEST_F(VSyncDispatchTimerQueueTest,setsTimerAfterCancellation)716 TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
717     Sequence seq;
718     EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
719     EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
720     EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
721 
722     CountingCallback cb0(mDispatch);
723     mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
724     mDispatch->cancel(cb0);
725     mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
726 }
727 
TEST_F(VSyncDispatchTimerQueueTest,makingUpIdsError)728 TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
729     VSyncDispatch::CallbackToken token(100);
730     EXPECT_FALSE(
731             mDispatch->schedule(token, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000})
732                     .has_value());
733     EXPECT_THAT(mDispatch->cancel(token), Eq(CancelResult::Error));
734 }
735 
TEST_F(VSyncDispatchTimerQueueTest,canMoveCallbackBackwardsInTime)736 TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
737     CountingCallback cb0(mDispatch);
738     auto result =
739             mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
740     EXPECT_TRUE(result.has_value());
741     EXPECT_EQ(500, result->callbackTime.ns());
742     EXPECT_EQ(1000, result->vsyncTime.ns());
743     result = mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
744     EXPECT_TRUE(result.has_value());
745     EXPECT_EQ(900, result->callbackTime.ns());
746     EXPECT_EQ(1000, result->vsyncTime.ns());
747 }
748 
749 // b/1450138150
TEST_F(VSyncDispatchTimerQueueTest,doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync)750 TEST_F(VSyncDispatchTimerQueueTest, doesNotMoveCallbackBackwardsAndSkipAScheduledTargetVSync) {
751     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
752 
753     EXPECT_CALL(mMockClock, alarmAt(_, 500));
754     CountingCallback cb(mDispatch);
755     auto result =
756             mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
757     EXPECT_TRUE(result.has_value());
758     EXPECT_EQ(500, result->callbackTime.ns());
759     EXPECT_EQ(1000, result->vsyncTime.ns());
760     mMockClock.advanceBy(400);
761 
762     result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
763     EXPECT_TRUE(result.has_value());
764     EXPECT_EQ(1200, result->callbackTime.ns());
765     EXPECT_EQ(2000, result->vsyncTime.ns());
766 
767     advanceToNextCallback();
768     ASSERT_THAT(cb.mCalls.size(), Eq(1));
769 }
770 
771 // b/1450138150
TEST_F(VSyncDispatchTimerQueueTest,movesCallbackBackwardsAndSkipAScheduledTargetVSync)772 TEST_F(VSyncDispatchTimerQueueTest, movesCallbackBackwardsAndSkipAScheduledTargetVSync) {
773     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
774 
775     Sequence seq;
776     EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
777     EXPECT_CALL(mMockClock, alarmAt(_, 400)).InSequence(seq);
778     CountingCallback cb(mDispatch);
779     auto result =
780             mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
781     EXPECT_TRUE(result.has_value());
782     EXPECT_EQ(500, result->callbackTime.ns());
783     EXPECT_EQ(1000, result->vsyncTime.ns());
784     mMockClock.advanceBy(400);
785 
786     result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
787     EXPECT_TRUE(result.has_value());
788     EXPECT_EQ(400, result->callbackTime.ns());
789     EXPECT_EQ(1000, result->vsyncTime.ns());
790 
791     advanceToNextCallback();
792     ASSERT_THAT(cb.mCalls.size(), Eq(1));
793 }
794 
TEST_F(VSyncDispatchTimerQueueTest,targetOffsetMovingBackALittleCanStillSchedule)795 TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
796     EXPECT_CALL(*mStubTracker.get(),
797                 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
798             .Times(2)
799             .WillOnce(Return(1000))
800             .WillOnce(Return(1002));
801     CountingCallback cb(mDispatch);
802     auto result =
803             mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
804     EXPECT_TRUE(result.has_value());
805     EXPECT_EQ(500, result->callbackTime.ns());
806     EXPECT_EQ(1000, result->vsyncTime.ns());
807     mMockClock.advanceBy(400);
808     result = mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
809     EXPECT_TRUE(result.has_value());
810     EXPECT_EQ(602, result->callbackTime.ns());
811     EXPECT_EQ(1002, result->vsyncTime.ns());
812 }
813 
TEST_F(VSyncDispatchTimerQueueTest,canScheduleNegativeOffsetAgainstDifferentPeriods)814 TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
815     CountingCallback cb0(mDispatch);
816     auto result =
817             mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
818     EXPECT_TRUE(result.has_value());
819     EXPECT_EQ(500, result->callbackTime.ns());
820     EXPECT_EQ(1000, result->vsyncTime.ns());
821     advanceToNextCallback();
822     result =
823             mDispatch->schedule(cb0, {.workDuration = 1100, .readyDuration = 0, .lastVsync = 2000});
824     EXPECT_TRUE(result.has_value());
825     EXPECT_EQ(900, result->callbackTime.ns());
826     EXPECT_EQ(2000, result->vsyncTime.ns());
827 }
828 
TEST_F(VSyncDispatchTimerQueueTest,canScheduleLargeNegativeOffset)829 TEST_F(VSyncDispatchTimerQueueTest, canScheduleLargeNegativeOffset) {
830     Sequence seq;
831     EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
832     EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
833     CountingCallback cb0(mDispatch);
834     auto result =
835             mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
836     EXPECT_TRUE(result.has_value());
837     EXPECT_EQ(500, result->callbackTime.ns());
838     EXPECT_EQ(1000, result->vsyncTime.ns());
839     advanceToNextCallback();
840     result =
841             mDispatch->schedule(cb0, {.workDuration = 1900, .readyDuration = 0, .lastVsync = 2000});
842     EXPECT_TRUE(result.has_value());
843     EXPECT_EQ(1100, result->callbackTime.ns());
844     EXPECT_EQ(3000, result->vsyncTime.ns());
845 }
846 
TEST_F(VSyncDispatchTimerQueueTest,scheduleUpdatesDoesNotAffectSchedulingState)847 TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesNotAffectSchedulingState) {
848     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
849 
850     EXPECT_CALL(mMockClock, alarmAt(_, 600));
851 
852     CountingCallback cb(mDispatch);
853     auto result =
854             mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
855     EXPECT_TRUE(result.has_value());
856     EXPECT_EQ(600, result->callbackTime.ns());
857     EXPECT_EQ(1000, result->vsyncTime.ns());
858 
859     result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
860     EXPECT_TRUE(result.has_value());
861     EXPECT_EQ(600, result->callbackTime.ns());
862     EXPECT_EQ(2000, result->vsyncTime.ns());
863 
864     advanceToNextCallback();
865 }
866 
TEST_F(VSyncDispatchTimerQueueTest,scheduleUpdatesDoesAffectSchedulingState)867 TEST_F(VSyncDispatchTimerQueueTest, scheduleUpdatesDoesAffectSchedulingState) {
868     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
869 
870     Sequence seq;
871     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
872     EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
873 
874     CountingCallback cb(mDispatch);
875     auto result =
876             mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
877     EXPECT_TRUE(result.has_value());
878     EXPECT_EQ(600, result->callbackTime.ns());
879     EXPECT_EQ(1000, result->vsyncTime.ns());
880 
881     result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
882     EXPECT_TRUE(result.has_value());
883     EXPECT_EQ(0, result->callbackTime.ns());
884     EXPECT_EQ(1000, result->vsyncTime.ns());
885 
886     advanceToNextCallback();
887 }
888 
TEST_F(VSyncDispatchTimerQueueTest,helperMove)889 TEST_F(VSyncDispatchTimerQueueTest, helperMove) {
890     EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
891     EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
892 
893     VSyncCallbackRegistration cb(
894             mDispatch, [](auto, auto, auto) {}, "");
895     VSyncCallbackRegistration cb1(std::move(cb));
896     cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
897     cb.cancel();
898 
899     cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
900     cb1.cancel();
901 }
902 
TEST_F(VSyncDispatchTimerQueueTest,helperMoveAssign)903 TEST_F(VSyncDispatchTimerQueueTest, helperMoveAssign) {
904     EXPECT_CALL(mMockClock, alarmAt(_, 500)).Times(1);
905     EXPECT_CALL(mMockClock, alarmCancel()).Times(1);
906 
907     VSyncCallbackRegistration cb(
908             mDispatch, [](auto, auto, auto) {}, "");
909     VSyncCallbackRegistration cb1(
910             mDispatch, [](auto, auto, auto) {}, "");
911     cb1 = std::move(cb);
912     cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
913     cb.cancel();
914 
915     cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
916     cb1.cancel();
917 }
918 
919 // b/154303580
TEST_F(VSyncDispatchTimerQueueTest,skipsSchedulingIfTimerReschedulingIsImminent)920 TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminent) {
921     Sequence seq;
922     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
923     EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
924     CountingCallback cb1(mDispatch);
925     CountingCallback cb2(mDispatch);
926 
927     auto result =
928             mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
929     EXPECT_TRUE(result.has_value());
930     EXPECT_EQ(600, result->callbackTime.ns());
931     EXPECT_EQ(1000, result->vsyncTime.ns());
932 
933     mMockClock.setLag(100);
934     mMockClock.advanceBy(620);
935 
936     result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
937     EXPECT_TRUE(result.has_value());
938     EXPECT_EQ(1900, result->callbackTime.ns());
939     EXPECT_EQ(2000, result->vsyncTime.ns());
940     mMockClock.advanceBy(80);
941 
942     EXPECT_THAT(cb1.mCalls.size(), Eq(1));
943     EXPECT_THAT(cb2.mCalls.size(), Eq(0));
944 }
945 
946 // b/154303580.
947 // If the same callback tries to reschedule itself after it's too late, timer opts to apply the
948 // update later, as opposed to blocking the calling thread.
TEST_F(VSyncDispatchTimerQueueTest,skipsSchedulingIfTimerReschedulingIsImminentSameCallback)949 TEST_F(VSyncDispatchTimerQueueTest, skipsSchedulingIfTimerReschedulingIsImminentSameCallback) {
950     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
951 
952     Sequence seq;
953     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
954     EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
955     CountingCallback cb(mDispatch);
956 
957     auto result =
958             mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
959     EXPECT_TRUE(result.has_value());
960     EXPECT_EQ(600, result->callbackTime.ns());
961     EXPECT_EQ(1000, result->vsyncTime.ns());
962 
963     mMockClock.setLag(100);
964     mMockClock.advanceBy(620);
965 
966     result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
967     EXPECT_TRUE(result.has_value());
968     EXPECT_EQ(1630, result->callbackTime.ns());
969     EXPECT_EQ(2000, result->vsyncTime.ns());
970     mMockClock.advanceBy(80);
971 
972     EXPECT_THAT(cb.mCalls.size(), Eq(1));
973 }
974 
975 // b/154303580.
976 // If the same callback tries to reschedule itself after it's too late, timer opts to apply the
977 // update later, as opposed to blocking the calling thread.
TEST_F(VSyncDispatchTimerQueueTest,doesntSkipSchedulingIfTimerReschedulingIsImminentSameCallback)978 TEST_F(VSyncDispatchTimerQueueTest, doesntSkipSchedulingIfTimerReschedulingIsImminentSameCallback) {
979     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
980 
981     Sequence seq;
982     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
983     EXPECT_CALL(mMockClock, alarmAt(_, 1630)).InSequence(seq);
984     CountingCallback cb(mDispatch);
985 
986     auto result =
987             mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
988     EXPECT_TRUE(result.has_value());
989     EXPECT_EQ(600, result->callbackTime.ns());
990     EXPECT_EQ(1000, result->vsyncTime.ns());
991 
992     mMockClock.setLag(100);
993     mMockClock.advanceBy(620);
994 
995     result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
996     EXPECT_TRUE(result.has_value());
997     EXPECT_EQ(600, result->callbackTime.ns());
998     EXPECT_EQ(1000, result->vsyncTime.ns());
999     mMockClock.advanceBy(80);
1000 
1001     ASSERT_EQ(1, cb.mCalls.size());
1002     EXPECT_EQ(1000, cb.mCalls[0]);
1003 
1004     ASSERT_EQ(1, cb.mWakeupTime.size());
1005     EXPECT_EQ(600, cb.mWakeupTime[0]);
1006 }
1007 
1008 // b/154303580.
TEST_F(VSyncDispatchTimerQueueTest,skipsRearmingWhenNotNextScheduled)1009 TEST_F(VSyncDispatchTimerQueueTest, skipsRearmingWhenNotNextScheduled) {
1010     Sequence seq;
1011     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1012     EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
1013     CountingCallback cb1(mDispatch);
1014     CountingCallback cb2(mDispatch);
1015 
1016     auto result =
1017             mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1018     EXPECT_TRUE(result.has_value());
1019     EXPECT_EQ(600, result->callbackTime.ns());
1020     EXPECT_EQ(1000, result->vsyncTime.ns());
1021     result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
1022     EXPECT_TRUE(result.has_value());
1023     EXPECT_EQ(1900, result->callbackTime.ns());
1024     EXPECT_EQ(2000, result->vsyncTime.ns());
1025 
1026     mMockClock.setLag(100);
1027     mMockClock.advanceBy(620);
1028 
1029     EXPECT_EQ(mDispatch->cancel(cb2), CancelResult::Cancelled);
1030 
1031     mMockClock.advanceBy(80);
1032 
1033     EXPECT_THAT(cb1.mCalls.size(), Eq(1));
1034     EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1035 }
1036 
TEST_F(VSyncDispatchTimerQueueTest,rearmsWhenCancelledAndIsNextScheduled)1037 TEST_F(VSyncDispatchTimerQueueTest, rearmsWhenCancelledAndIsNextScheduled) {
1038     Sequence seq;
1039     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1040     EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
1041     EXPECT_CALL(mMockClock, alarmCancel()).InSequence(seq);
1042     CountingCallback cb1(mDispatch);
1043     CountingCallback cb2(mDispatch);
1044 
1045     auto result =
1046             mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1047     EXPECT_TRUE(result.has_value());
1048     EXPECT_EQ(600, result->callbackTime.ns());
1049     EXPECT_EQ(1000, result->vsyncTime.ns());
1050     result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
1051     EXPECT_TRUE(result.has_value());
1052     EXPECT_EQ(1900, result->callbackTime.ns());
1053     EXPECT_EQ(2000, result->vsyncTime.ns());
1054 
1055     mMockClock.setLag(100);
1056     mMockClock.advanceBy(620);
1057 
1058     EXPECT_EQ(mDispatch->cancel(cb1), CancelResult::Cancelled);
1059 
1060     EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1061     EXPECT_THAT(cb2.mCalls.size(), Eq(0));
1062     mMockClock.advanceToNextCallback();
1063 
1064     EXPECT_THAT(cb1.mCalls.size(), Eq(0));
1065     EXPECT_THAT(cb2.mCalls.size(), Eq(1));
1066 }
1067 
TEST_F(VSyncDispatchTimerQueueTest,laggedTimerGroupsCallbacksWithinLag)1068 TEST_F(VSyncDispatchTimerQueueTest, laggedTimerGroupsCallbacksWithinLag) {
1069     CountingCallback cb1(mDispatch);
1070     CountingCallback cb2(mDispatch);
1071 
1072     Sequence seq;
1073     EXPECT_CALL(*mStubTracker.get(),
1074                 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
1075             .InSequence(seq)
1076             .WillOnce(Return(1000));
1077     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1078     EXPECT_CALL(*mStubTracker.get(),
1079                 nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
1080             .InSequence(seq)
1081             .WillOnce(Return(1000));
1082 
1083     auto result =
1084             mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1085     EXPECT_TRUE(result.has_value());
1086     EXPECT_EQ(600, result->callbackTime.ns());
1087     EXPECT_EQ(1000, result->vsyncTime.ns());
1088     result = mDispatch->schedule(cb2, {.workDuration = 390, .readyDuration = 0, .lastVsync = 1000});
1089     EXPECT_TRUE(result.has_value());
1090     EXPECT_EQ(610, result->callbackTime.ns());
1091     EXPECT_EQ(1000, result->vsyncTime.ns());
1092 
1093     mMockClock.setLag(100);
1094     mMockClock.advanceBy(700);
1095 
1096     ASSERT_THAT(cb1.mWakeupTime.size(), Eq(1));
1097     EXPECT_THAT(cb1.mWakeupTime[0], Eq(600));
1098     ASSERT_THAT(cb1.mReadyTime.size(), Eq(1));
1099     EXPECT_THAT(cb1.mReadyTime[0], Eq(1000));
1100     ASSERT_THAT(cb2.mWakeupTime.size(), Eq(1));
1101     EXPECT_THAT(cb2.mWakeupTime[0], Eq(610));
1102     ASSERT_THAT(cb2.mReadyTime.size(), Eq(1));
1103     EXPECT_THAT(cb2.mReadyTime[0], Eq(1000));
1104 }
1105 
TEST_F(VSyncDispatchTimerQueueTest,basicAlarmSettingFutureWithReadyDuration)1106 TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithReadyDuration) {
1107     auto intended = mPeriod - 230;
1108     EXPECT_CALL(mMockClock, alarmAt(_, 900));
1109 
1110     CountingCallback cb(mDispatch);
1111     const auto result =
1112             mDispatch->schedule(cb,
1113                                 {.workDuration = 70, .readyDuration = 30, .lastVsync = intended});
1114     EXPECT_TRUE(result.has_value());
1115     EXPECT_EQ(900, result->callbackTime.ns());
1116     EXPECT_EQ(1000, result->vsyncTime.ns());
1117     advanceToNextCallback();
1118 
1119     ASSERT_THAT(cb.mCalls.size(), Eq(1));
1120     EXPECT_THAT(cb.mCalls[0], Eq(mPeriod));
1121     ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1122     EXPECT_THAT(cb.mWakeupTime[0], 900);
1123     ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1124     EXPECT_THAT(cb.mReadyTime[0], 970);
1125 }
1126 
TEST_F(VSyncDispatchTimerQueueTest,updatesVsyncTimeForCloseWakeupTime)1127 TEST_F(VSyncDispatchTimerQueueTest, updatesVsyncTimeForCloseWakeupTime) {
1128     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
1129 
1130     Sequence seq;
1131     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1132 
1133     CountingCallback cb(mDispatch);
1134 
1135     mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1136     mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
1137 
1138     advanceToNextCallback();
1139 
1140     advanceToNextCallback();
1141 
1142     ASSERT_THAT(cb.mCalls.size(), Eq(1));
1143     EXPECT_THAT(cb.mCalls[0], Eq(2000));
1144     ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1145     EXPECT_THAT(cb.mWakeupTime[0], Eq(600));
1146     ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1147     EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
1148 }
1149 
TEST_F(VSyncDispatchTimerQueueTest,doesNotUpdatesVsyncTimeForCloseWakeupTime)1150 TEST_F(VSyncDispatchTimerQueueTest, doesNotUpdatesVsyncTimeForCloseWakeupTime) {
1151     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
1152 
1153     Sequence seq;
1154     EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
1155     EXPECT_CALL(mMockClock, alarmAt(_, 0)).InSequence(seq);
1156 
1157     CountingCallback cb(mDispatch);
1158 
1159     mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
1160     mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
1161 
1162     advanceToNextCallback();
1163 
1164     advanceToNextCallback();
1165 
1166     ASSERT_THAT(cb.mCalls.size(), Eq(1));
1167     EXPECT_THAT(cb.mCalls[0], Eq(1000));
1168     ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1169     EXPECT_THAT(cb.mWakeupTime[0], Eq(0));
1170     ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1171     EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1172 }
1173 
TEST_F(VSyncDispatchTimerQueueTest,skipAVsyc)1174 TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
1175     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
1176 
1177     EXPECT_CALL(mMockClock, alarmAt(_, 500));
1178     CountingCallback cb(mDispatch);
1179     auto result =
1180             mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
1181     EXPECT_TRUE(result.has_value());
1182     EXPECT_EQ(500, result->callbackTime.ns());
1183     EXPECT_EQ(1000, result->vsyncTime.ns());
1184     mMockClock.advanceBy(300);
1185 
1186     result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
1187     EXPECT_TRUE(result.has_value());
1188     EXPECT_EQ(1200, result->callbackTime.ns());
1189     EXPECT_EQ(2000, result->vsyncTime.ns());
1190 
1191     advanceToNextCallback();
1192     ASSERT_THAT(cb.mCalls.size(), Eq(1));
1193 }
1194 
TEST_F(VSyncDispatchTimerQueueTest,dontskipAVsyc)1195 TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
1196     SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
1197 
1198     Sequence seq;
1199     EXPECT_CALL(mMockClock, alarmAt(_, 500)).InSequence(seq);
1200     EXPECT_CALL(mMockClock, alarmAt(_, 300)).InSequence(seq);
1201     CountingCallback cb(mDispatch);
1202     auto result =
1203             mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
1204     EXPECT_TRUE(result.has_value());
1205     EXPECT_EQ(500, result->callbackTime.ns());
1206     EXPECT_EQ(1000, result->vsyncTime.ns());
1207     mMockClock.advanceBy(300);
1208 
1209     result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
1210     EXPECT_TRUE(result.has_value());
1211     EXPECT_EQ(300, result->callbackTime.ns());
1212     EXPECT_EQ(1000, result->vsyncTime.ns());
1213 
1214     advanceToNextCallback();
1215     ASSERT_THAT(cb.mCalls.size(), Eq(1));
1216     EXPECT_THAT(cb.mCalls[0], Eq(1000));
1217     ASSERT_THAT(cb.mWakeupTime.size(), Eq(1));
1218     EXPECT_THAT(cb.mWakeupTime[0], Eq(300));
1219     ASSERT_THAT(cb.mReadyTime.size(), Eq(1));
1220     EXPECT_THAT(cb.mReadyTime[0], Eq(1000));
1221 }
1222 
1223 class VSyncDispatchTimerQueueEntryTest : public testing::Test {
1224 protected:
1225     nsecs_t const mPeriod = 1000;
1226     nsecs_t const mVsyncMoveThreshold = 200;
1227     std::shared_ptr<NiceMock<MockVSyncTracker>> mStubTracker =
1228             std::make_shared<NiceMock<MockVSyncTracker>>(mPeriod);
1229 };
1230 
TEST_F(VSyncDispatchTimerQueueEntryTest,stateAfterInitialization)1231 TEST_F(VSyncDispatchTimerQueueEntryTest, stateAfterInitialization) {
1232     std::string name("basicname");
1233     VSyncDispatchTimerQueueEntry entry(
1234             name, [](auto, auto, auto) {}, mVsyncMoveThreshold);
1235     EXPECT_THAT(entry.name(), Eq(name));
1236     EXPECT_FALSE(entry.lastExecutedVsyncTarget());
1237     EXPECT_FALSE(entry.wakeupTime());
1238 }
1239 
TEST_F(VSyncDispatchTimerQueueEntryTest,stateScheduling)1240 TEST_F(VSyncDispatchTimerQueueEntryTest, stateScheduling) {
1241     VSyncDispatchTimerQueueEntry entry(
1242             "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1243 
1244     EXPECT_FALSE(entry.wakeupTime());
1245     const auto scheduleResult =
1246             entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1247                            *mStubTracker, 0);
1248     EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1249     EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
1250     auto const wakeup = entry.wakeupTime();
1251     ASSERT_TRUE(wakeup);
1252     EXPECT_THAT(*wakeup, Eq(900));
1253 
1254     entry.disarm();
1255     EXPECT_FALSE(entry.wakeupTime());
1256 }
1257 
TEST_F(VSyncDispatchTimerQueueEntryTest,stateSchedulingReallyLongWakeupLatency)1258 TEST_F(VSyncDispatchTimerQueueEntryTest, stateSchedulingReallyLongWakeupLatency) {
1259     auto const duration = 500;
1260     auto const now = 8750;
1261 
1262     EXPECT_CALL(*mStubTracker.get(),
1263                 nextAnticipatedVSyncTimeFrom(now + duration, std::optional<nsecs_t>(994)))
1264             .Times(1)
1265             .WillOnce(Return(10000));
1266     VSyncDispatchTimerQueueEntry entry(
1267             "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1268 
1269     EXPECT_FALSE(entry.wakeupTime());
1270     const auto scheduleResult =
1271             entry.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 994},
1272                            *mStubTracker, now);
1273     EXPECT_EQ(9500, scheduleResult.callbackTime.ns());
1274     EXPECT_EQ(10000, scheduleResult.vsyncTime.ns());
1275     auto const wakeup = entry.wakeupTime();
1276     ASSERT_TRUE(wakeup);
1277     EXPECT_THAT(*wakeup, Eq(9500));
1278 }
1279 
TEST_F(VSyncDispatchTimerQueueEntryTest,runCallback)1280 TEST_F(VSyncDispatchTimerQueueEntryTest, runCallback) {
1281     auto callCount = 0;
1282     auto vsyncCalledTime = 0;
1283     auto wakeupCalledTime = 0;
1284     auto readyCalledTime = 0;
1285     VSyncDispatchTimerQueueEntry entry(
1286             "test",
1287             [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1288                 callCount++;
1289                 vsyncCalledTime = vsyncTime;
1290                 wakeupCalledTime = wakeupTime;
1291                 readyCalledTime = readyTime;
1292             },
1293             mVsyncMoveThreshold);
1294 
1295     const auto scheduleResult =
1296             entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1297                            *mStubTracker, 0);
1298     EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1299     EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
1300     auto const wakeup = entry.wakeupTime();
1301     ASSERT_TRUE(wakeup);
1302     EXPECT_THAT(*wakeup, Eq(900));
1303 
1304     auto const ready = entry.readyTime();
1305     ASSERT_TRUE(ready);
1306     EXPECT_THAT(*ready, Eq(1000));
1307 
1308     entry.callback(entry.executing(), *wakeup, *ready);
1309 
1310     EXPECT_THAT(callCount, Eq(1));
1311     EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1312     EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1313     EXPECT_FALSE(entry.wakeupTime());
1314     auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1315     ASSERT_TRUE(lastCalledTarget);
1316     EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1317 }
1318 
TEST_F(VSyncDispatchTimerQueueEntryTest,updateCallback)1319 TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
1320     EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
1321             .Times(2)
1322             .WillOnce(Return(1000))
1323             .WillOnce(Return(1020));
1324 
1325     VSyncDispatchTimerQueueEntry entry(
1326             "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1327 
1328     EXPECT_FALSE(entry.wakeupTime());
1329     entry.update(*mStubTracker, 0);
1330     EXPECT_FALSE(entry.wakeupTime());
1331 
1332     const auto scheduleResult =
1333             entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1334                            *mStubTracker, 0);
1335     EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1336     EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
1337     auto wakeup = entry.wakeupTime();
1338     ASSERT_TRUE(wakeup);
1339     EXPECT_THAT(wakeup, Eq(900));
1340 
1341     entry.update(*mStubTracker, 0);
1342     wakeup = entry.wakeupTime();
1343     ASSERT_TRUE(wakeup);
1344     EXPECT_THAT(*wakeup, Eq(920));
1345 }
1346 
TEST_F(VSyncDispatchTimerQueueEntryTest,skipsUpdateIfJustScheduled)1347 TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
1348     VSyncDispatchTimerQueueEntry entry(
1349             "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1350     EXPECT_EQ(900,
1351               entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1352                              *mStubTracker.get(), 0)
1353                       .callbackTime.ns());
1354     entry.update(*mStubTracker.get(), 0);
1355 
1356     auto const wakeup = entry.wakeupTime();
1357     ASSERT_TRUE(wakeup);
1358     EXPECT_THAT(*wakeup, Eq(wakeup));
1359 }
1360 
TEST_F(VSyncDispatchTimerQueueEntryTest,willSnapToNextTargettableVSync)1361 TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
1362     VSyncDispatchTimerQueueEntry entry(
1363             "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1364     auto scheduleResult =
1365             entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1366                            *mStubTracker, 0);
1367 
1368     EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1369     EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
1370     entry.executing(); // 1000 is executing
1371     // had 1000 not been executing, this could have been scheduled for time 800.
1372     scheduleResult = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
1373                                     *mStubTracker, 0);
1374     EXPECT_EQ(1800, scheduleResult.callbackTime.ns());
1375     EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
1376     EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
1377     EXPECT_THAT(*entry.readyTime(), Eq(2000));
1378 
1379     scheduleResult = entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
1380                                     *mStubTracker, 0);
1381     EXPECT_EQ(1950, scheduleResult.callbackTime.ns());
1382     EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
1383     EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
1384     EXPECT_THAT(*entry.readyTime(), Eq(2000));
1385 
1386     scheduleResult = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 1001},
1387                                     *mStubTracker, 0);
1388     EXPECT_EQ(1800, scheduleResult.callbackTime.ns());
1389     EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
1390     EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
1391     EXPECT_THAT(*entry.readyTime(), Eq(2000));
1392 }
1393 
TEST_F(VSyncDispatchTimerQueueEntryTest,willRequestNextEstimateWhenSnappingToNextTargettableVSync)1394 TEST_F(VSyncDispatchTimerQueueEntryTest,
1395        willRequestNextEstimateWhenSnappingToNextTargettableVSync) {
1396     VSyncDispatchTimerQueueEntry entry(
1397             "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1398 
1399     Sequence seq;
1400     EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
1401             .InSequence(seq)
1402             .WillOnce(Return(1000));
1403     EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
1404             .InSequence(seq)
1405             .WillOnce(Return(1000));
1406     EXPECT_CALL(*mStubTracker.get(),
1407                 nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold,
1408                                              std::optional<nsecs_t>(1000)))
1409             .InSequence(seq)
1410             .WillOnce(Return(2000));
1411 
1412     auto scheduleResult =
1413             entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1414                            *mStubTracker, 0);
1415     EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1416     EXPECT_EQ(1000, scheduleResult.vsyncTime.ns());
1417 
1418     entry.executing(); // 1000 is executing
1419 
1420     scheduleResult = entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
1421                                     *mStubTracker, 0);
1422     EXPECT_EQ(1800, scheduleResult.callbackTime.ns());
1423     EXPECT_EQ(2000, scheduleResult.vsyncTime.ns());
1424 }
1425 
TEST_F(VSyncDispatchTimerQueueEntryTest,reportsScheduledIfStillTime)1426 TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
1427     VSyncDispatchTimerQueueEntry entry("test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1428     EXPECT_EQ(900,
1429               entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
1430                              *mStubTracker, 0)
1431                       .callbackTime.ns());
1432     EXPECT_EQ(800,
1433               entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
1434                              *mStubTracker, 0)
1435                       .callbackTime.ns());
1436     EXPECT_EQ(950,
1437               entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
1438                              *mStubTracker, 0)
1439                       .callbackTime.ns());
1440     {
1441         SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, true);
1442         EXPECT_EQ(0,
1443                   entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
1444                                  *mStubTracker, 0)
1445                           .callbackTime.ns());
1446     }
1447     {
1448         SET_FLAG_FOR_TEST(flags::dont_skip_on_early_ro, false);
1449         EXPECT_EQ(800,
1450                   entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
1451                                  *mStubTracker, 0)
1452                           .callbackTime.ns());
1453     }
1454 }
1455 
TEST_F(VSyncDispatchTimerQueueEntryTest,storesPendingUpdatesUntilUpdateAndDontSkip)1456 TEST_F(VSyncDispatchTimerQueueEntryTest, storesPendingUpdatesUntilUpdateAndDontSkip) {
1457     static constexpr auto effectualOffset = 200;
1458     VSyncDispatchTimerQueueEntry entry(
1459             "test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
1460     EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1461     entry.addPendingWorkloadUpdate(*mStubTracker.get(), 0,
1462                                    {.workDuration = 100, .readyDuration = 0, .lastVsync = 400});
1463     entry.addPendingWorkloadUpdate(*mStubTracker.get(), 0,
1464                                    {.workDuration = effectualOffset,
1465                                     .readyDuration = 0,
1466                                     .lastVsync = 400});
1467     EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
1468     entry.update(*mStubTracker, 0);
1469     EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
1470     EXPECT_THAT(*entry.wakeupTime(), Eq(mPeriod - effectualOffset));
1471 }
1472 
TEST_F(VSyncDispatchTimerQueueEntryTest,runCallbackWithReadyDuration)1473 TEST_F(VSyncDispatchTimerQueueEntryTest, runCallbackWithReadyDuration) {
1474     auto callCount = 0;
1475     auto vsyncCalledTime = 0;
1476     auto wakeupCalledTime = 0;
1477     auto readyCalledTime = 0;
1478     VSyncDispatchTimerQueueEntry entry(
1479             "test",
1480             [&](auto vsyncTime, auto wakeupTime, auto readyTime) {
1481                 callCount++;
1482                 vsyncCalledTime = vsyncTime;
1483                 wakeupCalledTime = wakeupTime;
1484                 readyCalledTime = readyTime;
1485             },
1486             mVsyncMoveThreshold);
1487 
1488     const auto scheduleResult =
1489             entry.schedule({.workDuration = 70, .readyDuration = 30, .lastVsync = 500},
1490                            *mStubTracker, 0);
1491     EXPECT_EQ(900, scheduleResult.callbackTime.ns());
1492     EXPECT_EQ(mPeriod, scheduleResult.vsyncTime.ns());
1493     auto const wakeup = entry.wakeupTime();
1494     ASSERT_TRUE(wakeup);
1495     EXPECT_THAT(*wakeup, Eq(900));
1496 
1497     auto const ready = entry.readyTime();
1498     ASSERT_TRUE(ready);
1499     EXPECT_THAT(*ready, Eq(970));
1500 
1501     entry.callback(entry.executing(), *wakeup, *ready);
1502 
1503     EXPECT_THAT(callCount, Eq(1));
1504     EXPECT_THAT(vsyncCalledTime, Eq(mPeriod));
1505     EXPECT_THAT(wakeupCalledTime, Eq(*wakeup));
1506     EXPECT_FALSE(entry.wakeupTime());
1507     auto lastCalledTarget = entry.lastExecutedVsyncTarget();
1508     ASSERT_TRUE(lastCalledTarget);
1509     EXPECT_THAT(*lastCalledTarget, Eq(mPeriod));
1510 }
1511 
1512 } // namespace android::scheduler
1513 
1514 // TODO(b/129481165): remove the #pragma below and fix conversion issues
1515 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
1516