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 "-Wextra"
20 
21 #undef LOG_TAG
22 #define LOG_TAG "LibSurfaceFlingerUnittests"
23 #define LOG_NDEBUG 0
24 
25 #include <array>
26 
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29 #include <ui/Fence.h>
30 #include <ui/FenceTime.h>
31 
32 #include <scheduler/TimeKeeper.h>
33 
34 #include "mock/DisplayHardware/MockDisplayMode.h"
35 #include "mock/MockVSyncTracker.h"
36 
37 #include "Scheduler/VSyncDispatch.h"
38 #include "Scheduler/VSyncReactor.h"
39 #include "Scheduler/VSyncTracker.h"
40 
41 using namespace testing;
42 using namespace std::literals;
43 
44 namespace android::scheduler {
45 
46 namespace {
47 class MockClock : public Clock {
48 public:
49     MOCK_CONST_METHOD0(now, nsecs_t());
50 };
51 
52 class ClockWrapper : public Clock {
53 public:
ClockWrapper(std::shared_ptr<Clock> const & clock)54     ClockWrapper(std::shared_ptr<Clock> const& clock) : mClock(clock) {}
55 
now() const56     nsecs_t now() const { return mClock->now(); }
57 
58 private:
59     std::shared_ptr<Clock> const mClock;
60 };
61 
generateInvalidFence()62 std::shared_ptr<android::FenceTime> generateInvalidFence() {
63     sp<Fence> fence = sp<Fence>::make();
64     return std::make_shared<android::FenceTime>(fence);
65 }
66 
generatePendingFence()67 std::shared_ptr<android::FenceTime> generatePendingFence() {
68     sp<Fence> fence = sp<Fence>::make(dup(fileno(tmpfile())));
69     return std::make_shared<android::FenceTime>(fence);
70 }
71 
signalFenceWithTime(std::shared_ptr<android::FenceTime> const & fence,nsecs_t time)72 void signalFenceWithTime(std::shared_ptr<android::FenceTime> const& fence, nsecs_t time) {
73     android::FenceTime::Snapshot snap(time);
74     fence->applyTrustedSnapshot(snap);
75 }
76 
generateSignalledFenceWithTime(nsecs_t time)77 std::shared_ptr<android::FenceTime> generateSignalledFenceWithTime(nsecs_t time) {
78     sp<Fence> fence = sp<Fence>::make(dup(fileno(tmpfile())));
79     std::shared_ptr<android::FenceTime> ft = std::make_shared<android::FenceTime>(fence);
80     signalFenceWithTime(ft, time);
81     return ft;
82 }
83 
84 constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u);
85 
displayMode(nsecs_t vsyncPeriod)86 ftl::NonNull<DisplayModePtr> displayMode(nsecs_t vsyncPeriod) {
87     const int32_t kGroup = 0;
88     const auto kResolution = ui::Size(1920, 1080);
89     const auto refreshRate = Fps::fromPeriodNsecs(vsyncPeriod);
90     return ftl::as_non_null(mock::createDisplayMode(DisplayModeId(0), refreshRate, kGroup,
91                                                     kResolution, DEFAULT_DISPLAY_ID));
92 }
93 
94 MATCHER_P(DisplayModeMatcher, value, "display mode equals") {
95     return arg->getId() == value->getId() && equalsExceptDisplayModeId(*arg, *value);
96 }
97 
98 } // namespace
99 
100 class VSyncReactorTest : public testing::Test {
101 protected:
VSyncReactorTest()102     VSyncReactorTest()
103           : mMockTracker(std::make_shared<NiceMock<mock::VSyncTracker>>()),
104             mMockClock(std::make_shared<NiceMock<MockClock>>()),
105             mReactor(DEFAULT_DISPLAY_ID, std::make_unique<ClockWrapper>(mMockClock), *mMockTracker,
106                      kPendingLimit, false /* supportKernelIdleTimer */) {
107         ON_CALL(*mMockClock, now()).WillByDefault(Return(mFakeNow));
108         ON_CALL(*mMockTracker, currentPeriod()).WillByDefault(Return(period));
109         ON_CALL(*mMockTracker, addVsyncTimestamp(_)).WillByDefault(Return(true));
110     }
111 
112     std::shared_ptr<mock::VSyncTracker> mMockTracker;
113     std::shared_ptr<MockClock> mMockClock;
114     static constexpr size_t kPendingLimit = 3;
115     static constexpr nsecs_t mDummyTime = 47;
116     static constexpr nsecs_t mPhase = 3000;
117     static constexpr nsecs_t mAnotherPhase = 5200;
118     static constexpr nsecs_t period = 10000;
119     static constexpr nsecs_t mFakeVSyncTime = 2093;
120     static constexpr nsecs_t mFakeWakeupTime = 1892;
121     static constexpr nsecs_t mFakeNow = 2214;
122     static constexpr const char mName[] = "callbacky";
123     VSyncDispatch::CallbackToken const mFakeToken{2398};
124 
125     nsecs_t lastCallbackTime = 0;
126     // StubCallback outerCb;
127     std::function<void(nsecs_t, nsecs_t)> innerCb;
128 
129     VSyncReactor mReactor;
130 };
131 
TEST_F(VSyncReactorTest,addingNullFenceCheck)132 TEST_F(VSyncReactorTest, addingNullFenceCheck) {
133     EXPECT_FALSE(mReactor.addPresentFence(nullptr));
134 }
135 
TEST_F(VSyncReactorTest,addingInvalidFenceSignalsNeedsMoreInfo)136 TEST_F(VSyncReactorTest, addingInvalidFenceSignalsNeedsMoreInfo) {
137     EXPECT_TRUE(mReactor.addPresentFence(generateInvalidFence()));
138 }
139 
TEST_F(VSyncReactorTest,addingSignalledFenceAddsToTracker)140 TEST_F(VSyncReactorTest, addingSignalledFenceAddsToTracker) {
141     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(mDummyTime));
142     EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(mDummyTime)));
143 }
144 
TEST_F(VSyncReactorTest,addingPendingFenceAddsSignalled)145 TEST_F(VSyncReactorTest, addingPendingFenceAddsSignalled) {
146     nsecs_t anotherDummyTime = 2919019201;
147 
148     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(0);
149     auto pendingFence = generatePendingFence();
150     EXPECT_FALSE(mReactor.addPresentFence(pendingFence));
151     Mock::VerifyAndClearExpectations(mMockTracker.get());
152 
153     signalFenceWithTime(pendingFence, mDummyTime);
154 
155     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(mDummyTime));
156     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(anotherDummyTime));
157     EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(anotherDummyTime)));
158 }
159 
TEST_F(VSyncReactorTest,limitsPendingFences)160 TEST_F(VSyncReactorTest, limitsPendingFences) {
161     std::array<std::shared_ptr<android::FenceTime>, kPendingLimit * 2> fences;
162     std::array<nsecs_t, fences.size()> fakeTimes;
163     std::generate(fences.begin(), fences.end(), [] { return generatePendingFence(); });
164     std::generate(fakeTimes.begin(), fakeTimes.end(), [i = 10]() mutable {
165         i++;
166         return i * i;
167     });
168 
169     for (auto const& fence : fences) {
170         mReactor.addPresentFence(fence);
171     }
172 
173     for (auto i = fences.size() - kPendingLimit; i < fences.size(); i++) {
174         EXPECT_CALL(*mMockTracker, addVsyncTimestamp(fakeTimes[i]));
175     }
176 
177     for (auto i = 0u; i < fences.size(); i++) {
178         signalFenceWithTime(fences[i], fakeTimes[i]);
179     }
180     mReactor.addPresentFence(generatePendingFence());
181 }
182 
TEST_F(VSyncReactorTest,ignoresPresentFencesWhenToldTo)183 TEST_F(VSyncReactorTest, ignoresPresentFencesWhenToldTo) {
184     static constexpr size_t aFewTimes = 8;
185     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(mDummyTime)).Times(1);
186 
187     mReactor.setIgnorePresentFences(true);
188     for (auto i = 0; i < aFewTimes; i++) {
189         mReactor.addPresentFence(generateSignalledFenceWithTime(mDummyTime));
190     }
191 
192     mReactor.setIgnorePresentFences(false);
193     EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(mDummyTime)));
194 }
195 
TEST_F(VSyncReactorTest,ignoresProperlyAfterAPeriodConfirmation)196 TEST_F(VSyncReactorTest, ignoresProperlyAfterAPeriodConfirmation) {
197     bool periodFlushed = true;
198     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(3);
199     nsecs_t const newPeriod = 5000;
200 
201     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
202 
203     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, std::nullopt, &periodFlushed));
204     EXPECT_FALSE(periodFlushed);
205     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(newPeriod, std::nullopt, &periodFlushed));
206     EXPECT_TRUE(periodFlushed);
207 
208     EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
209 }
210 
TEST_F(VSyncReactorTest,setPeriodCalledOnceConfirmedChange)211 TEST_F(VSyncReactorTest, setPeriodCalledOnceConfirmedChange) {
212     nsecs_t const newPeriod = 5000;
213     EXPECT_CALL(*mMockTracker, setDisplayModePtr(_)).Times(0);
214     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
215 
216     bool periodFlushed = true;
217     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed));
218     EXPECT_FALSE(periodFlushed);
219 
220     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(20000, std::nullopt, &periodFlushed));
221     EXPECT_FALSE(periodFlushed);
222 
223     Mock::VerifyAndClearExpectations(mMockTracker.get());
224     EXPECT_CALL(*mMockTracker, setDisplayModePtr(/*displayMode(newPeriod)*/ _)).Times(1);
225 
226     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(25000, std::nullopt, &periodFlushed));
227     EXPECT_TRUE(periodFlushed);
228 }
229 
TEST_F(VSyncReactorTest,changingPeriodBackAbortsConfirmationProcess)230 TEST_F(VSyncReactorTest, changingPeriodBackAbortsConfirmationProcess) {
231     nsecs_t sampleTime = 0;
232     nsecs_t const newPeriod = 5000;
233     auto modePtr = displayMode(newPeriod);
234     mReactor.onDisplayModeChanged(modePtr, false);
235     bool periodFlushed = true;
236     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
237     EXPECT_FALSE(periodFlushed);
238 
239     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
240     EXPECT_FALSE(periodFlushed);
241 
242     modePtr = displayMode(period);
243     EXPECT_CALL(*mMockTracker, isCurrentMode(modePtr)).WillOnce(Return(true));
244     mReactor.onDisplayModeChanged(modePtr, false);
245     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
246     EXPECT_FALSE(periodFlushed);
247 }
248 
TEST_F(VSyncReactorTest,changingToAThirdPeriodWillWaitForLastPeriod)249 TEST_F(VSyncReactorTest, changingToAThirdPeriodWillWaitForLastPeriod) {
250     nsecs_t sampleTime = 0;
251     nsecs_t const secondPeriod = 5000;
252     nsecs_t const thirdPeriod = 2000;
253 
254     mReactor.onDisplayModeChanged(displayMode(secondPeriod), false);
255     bool periodFlushed = true;
256     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
257     EXPECT_FALSE(periodFlushed);
258     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
259     EXPECT_FALSE(periodFlushed);
260     mReactor.onDisplayModeChanged(displayMode(thirdPeriod), false);
261     EXPECT_TRUE(
262             mReactor.addHwVsyncTimestamp(sampleTime += secondPeriod, std::nullopt, &periodFlushed));
263     EXPECT_FALSE(periodFlushed);
264     EXPECT_FALSE(
265             mReactor.addHwVsyncTimestamp(sampleTime += thirdPeriod, std::nullopt, &periodFlushed));
266     EXPECT_TRUE(periodFlushed);
267 }
268 
TEST_F(VSyncReactorTest,reportedBadTimestampFromPredictorWillReactivateHwVSync)269 TEST_F(VSyncReactorTest, reportedBadTimestampFromPredictorWillReactivateHwVSync) {
270     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_))
271             .WillOnce(Return(false))
272             .WillOnce(Return(true))
273             .WillOnce(Return(true));
274     EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
275     EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
276 
277     nsecs_t skewyPeriod = period >> 1;
278     bool periodFlushed = false;
279     nsecs_t sampleTime = 0;
280     EXPECT_TRUE(
281             mReactor.addHwVsyncTimestamp(sampleTime += skewyPeriod, std::nullopt, &periodFlushed));
282     EXPECT_FALSE(periodFlushed);
283     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(sampleTime += period, std::nullopt, &periodFlushed));
284     EXPECT_FALSE(periodFlushed);
285 }
286 
TEST_F(VSyncReactorTest,reportedBadTimestampFromPredictorWillReactivateHwVSyncPendingFence)287 TEST_F(VSyncReactorTest, reportedBadTimestampFromPredictorWillReactivateHwVSyncPendingFence) {
288     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_))
289             .Times(2)
290             .WillOnce(Return(false))
291             .WillOnce(Return(true));
292 
293     auto fence = generatePendingFence();
294     EXPECT_FALSE(mReactor.addPresentFence(fence));
295     signalFenceWithTime(fence, period >> 1);
296     EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
297 }
298 
TEST_F(VSyncReactorTest,presentFenceAdditionDoesNotInterruptConfirmationProcess)299 TEST_F(VSyncReactorTest, presentFenceAdditionDoesNotInterruptConfirmationProcess) {
300     nsecs_t const newPeriod = 5000;
301     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
302     EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
303 }
304 
TEST_F(VSyncReactorTest,setPeriodCalledFirstTwoEventsNewPeriod)305 TEST_F(VSyncReactorTest, setPeriodCalledFirstTwoEventsNewPeriod) {
306     nsecs_t const newPeriod = 5000;
307     EXPECT_CALL(*mMockTracker, setDisplayModePtr(_)).Times(0);
308     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
309 
310     bool periodFlushed = true;
311     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(5000, std::nullopt, &periodFlushed));
312     EXPECT_FALSE(periodFlushed);
313     Mock::VerifyAndClearExpectations(mMockTracker.get());
314 
315     EXPECT_CALL(*mMockTracker, setDisplayModePtr(DisplayModeMatcher(displayMode(newPeriod))))
316             .Times(1);
317     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(10000, std::nullopt, &periodFlushed));
318     EXPECT_TRUE(periodFlushed);
319 }
320 
TEST_F(VSyncReactorTest,addResyncSampleTypical)321 TEST_F(VSyncReactorTest, addResyncSampleTypical) {
322     nsecs_t const fakeTimestamp = 3032;
323     bool periodFlushed = false;
324 
325     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(fakeTimestamp));
326     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(fakeTimestamp, std::nullopt, &periodFlushed));
327     EXPECT_FALSE(periodFlushed);
328 }
329 
TEST_F(VSyncReactorTest,addResyncSamplePeriodChanges)330 TEST_F(VSyncReactorTest, addResyncSamplePeriodChanges) {
331     bool periodFlushed = false;
332     nsecs_t const newPeriod = 4000;
333 
334     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
335 
336     auto time = 0;
337     auto constexpr numTimestampSubmissions = 10;
338     for (auto i = 0; i < numTimestampSubmissions; i++) {
339         time += period;
340         EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
341         EXPECT_FALSE(periodFlushed);
342     }
343 
344     time += newPeriod;
345     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
346     EXPECT_TRUE(periodFlushed);
347 
348     for (auto i = 0; i < numTimestampSubmissions; i++) {
349         time += newPeriod;
350         EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
351         EXPECT_FALSE(periodFlushed);
352     }
353 }
354 
TEST_F(VSyncReactorTest,addHwVsyncTimestampDozePreempt)355 TEST_F(VSyncReactorTest, addHwVsyncTimestampDozePreempt) {
356     bool periodFlushed = false;
357     nsecs_t const newPeriod = 4000;
358 
359     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
360 
361     auto time = 0;
362     // If the power mode is not DOZE or DOZE_SUSPEND, it is still collecting timestamps.
363     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
364     EXPECT_FALSE(periodFlushed);
365 
366     // Set power mode to DOZE to trigger period flushing.
367     mReactor.setDisplayPowerMode(hal::PowerMode::DOZE);
368     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed));
369     EXPECT_TRUE(periodFlushed);
370 }
371 
TEST_F(VSyncReactorTest,addPresentFenceWhileAwaitingPeriodConfirmationRequestsHwVsync)372 TEST_F(VSyncReactorTest, addPresentFenceWhileAwaitingPeriodConfirmationRequestsHwVsync) {
373     auto time = 0;
374     bool periodFlushed = false;
375     nsecs_t const newPeriod = 4000;
376     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
377 
378     time += period;
379     mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed);
380     EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
381 
382     time += newPeriod;
383     mReactor.addHwVsyncTimestamp(time, std::nullopt, &periodFlushed);
384 
385     EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
386 }
387 
TEST_F(VSyncReactorTest,hwVsyncIsRequestedForTracker)388 TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTracker) {
389     auto time = 0;
390     bool periodFlushed = false;
391     nsecs_t const newPeriod = 4000;
392     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
393 
394     static auto constexpr numSamplesWithNewPeriod = 4;
395     Sequence seq;
396     EXPECT_CALL(*mMockTracker, needsMoreSamples())
397             .Times(numSamplesWithNewPeriod - 2)
398             .InSequence(seq)
399             .WillRepeatedly(Return(true));
400     EXPECT_CALL(*mMockTracker, needsMoreSamples())
401             .Times(1)
402             .InSequence(seq)
403             .WillRepeatedly(Return(false));
404     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(numSamplesWithNewPeriod);
405 
406     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
407 
408     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
409     // confirmed period, but predictor wants numRequest samples. This one and prior are valid.
410     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
411     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
412     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
413 }
414 
TEST_F(VSyncReactorTest,hwVsyncturnsOffOnConfirmationWhenTrackerDoesntRequest)415 TEST_F(VSyncReactorTest, hwVsyncturnsOffOnConfirmationWhenTrackerDoesntRequest) {
416     auto time = 0;
417     bool periodFlushed = false;
418     nsecs_t const newPeriod = 4000;
419     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
420 
421     Sequence seq;
422     EXPECT_CALL(*mMockTracker, needsMoreSamples())
423             .Times(1)
424             .InSequence(seq)
425             .WillRepeatedly(Return(false));
426     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(2);
427 
428     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
429     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
430     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod, std::nullopt, &periodFlushed));
431 }
432 
TEST_F(VSyncReactorTest,hwVsyncIsRequestedForTrackerMultiplePeriodChanges)433 TEST_F(VSyncReactorTest, hwVsyncIsRequestedForTrackerMultiplePeriodChanges) {
434     auto time = 0;
435     bool periodFlushed = false;
436     nsecs_t const newPeriod1 = 4000;
437     nsecs_t const newPeriod2 = 7000;
438 
439     mReactor.onDisplayModeChanged(displayMode(newPeriod1), false);
440 
441     Sequence seq;
442     EXPECT_CALL(*mMockTracker, needsMoreSamples())
443             .Times(4)
444             .InSequence(seq)
445             .WillRepeatedly(Return(true));
446     EXPECT_CALL(*mMockTracker, needsMoreSamples())
447             .Times(1)
448             .InSequence(seq)
449             .WillRepeatedly(Return(false));
450     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(7);
451 
452     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
453     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += period, std::nullopt, &periodFlushed));
454     // confirmed period, but predictor wants numRequest samples. This one and prior are valid.
455     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
456     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
457 
458     mReactor.onDisplayModeChanged(displayMode(newPeriod2), false);
459     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod1, std::nullopt, &periodFlushed));
460     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
461     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
462     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(time += newPeriod2, std::nullopt, &periodFlushed));
463 }
464 
TEST_F(VSyncReactorTest,periodChangeWithGivenVsyncPeriod)465 TEST_F(VSyncReactorTest, periodChangeWithGivenVsyncPeriod) {
466     bool periodFlushed = true;
467     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(3);
468 
469     nsecs_t const newPeriod = 5000;
470     mReactor.onDisplayModeChanged(displayMode(newPeriod), false);
471 
472     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(0, 0, &periodFlushed));
473     EXPECT_FALSE(periodFlushed);
474     EXPECT_TRUE(mReactor.addHwVsyncTimestamp(newPeriod, 0, &periodFlushed));
475     EXPECT_FALSE(periodFlushed);
476     EXPECT_FALSE(mReactor.addHwVsyncTimestamp(newPeriod, newPeriod, &periodFlushed));
477     EXPECT_TRUE(periodFlushed);
478 
479     EXPECT_FALSE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
480 }
481 
TEST_F(VSyncReactorTest,periodIsMeasuredIfIgnoringComposer)482 TEST_F(VSyncReactorTest, periodIsMeasuredIfIgnoringComposer) {
483     // Create a reactor which supports the kernel idle timer
484     auto idleReactor =
485             VSyncReactor(DEFAULT_DISPLAY_ID, std::make_unique<ClockWrapper>(mMockClock),
486                          *mMockTracker, kPendingLimit, true /* supportKernelIdleTimer */);
487 
488     bool periodFlushed = true;
489     EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(5);
490 
491     // First, set the same period, which should only be confirmed when we receive two
492     // matching callbacks
493     idleReactor.onDisplayModeChanged(displayMode(10000), false);
494     EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(0, 0, &periodFlushed));
495     EXPECT_FALSE(periodFlushed);
496     // Correct period but incorrect timestamp delta
497     EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(0, 10000, &periodFlushed));
498     EXPECT_FALSE(periodFlushed);
499     // Correct period and correct timestamp delta
500     EXPECT_FALSE(idleReactor.addHwVsyncTimestamp(10000, 10000, &periodFlushed));
501     EXPECT_TRUE(periodFlushed);
502 
503     // Then, set a new period, which should be confirmed as soon as we receive a callback
504     // reporting the new period
505     nsecs_t const newPeriod = 5000;
506     idleReactor.onDisplayModeChanged(displayMode(newPeriod), false);
507     // Incorrect timestamp delta and period
508     EXPECT_TRUE(idleReactor.addHwVsyncTimestamp(20000, 10000, &periodFlushed));
509     EXPECT_FALSE(periodFlushed);
510     // Incorrect timestamp delta but correct period
511     EXPECT_FALSE(idleReactor.addHwVsyncTimestamp(20000, 5000, &periodFlushed));
512     EXPECT_TRUE(periodFlushed);
513 
514     EXPECT_FALSE(idleReactor.addPresentFence(generateSignalledFenceWithTime(0)));
515 }
516 
517 } // namespace android::scheduler
518 
519 // TODO(b/129481165): remove the #pragma below and fix conversion issues
520 #pragma clang diagnostic pop // ignored "-Wextra"
521