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