• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 
18 #include <ftl/enum.h>
19 #include <fuzzer/FuzzedDataProvider.h>
20 #include <processgroup/sched_policy.h>
21 
22 #include <scheduler/IVsyncSource.h>
23 #include <scheduler/PresentLatencyTracker.h>
24 
25 #include "Scheduler/OneShotTimer.h"
26 #include "Scheduler/RefreshRateSelector.h"
27 #include "Scheduler/VSyncDispatchTimerQueue.h"
28 #include "Scheduler/VSyncPredictor.h"
29 #include "Scheduler/VSyncReactor.h"
30 
31 #include "mock/MockVSyncDispatch.h"
32 #include "mock/MockVSyncTracker.h"
33 
34 #include "surfaceflinger_fuzzers_utils.h"
35 #include "surfaceflinger_scheduler_fuzzer.h"
36 
37 namespace android::fuzz {
38 
39 using hardware::graphics::composer::hal::PowerMode;
40 
41 constexpr nsecs_t kVsyncPeriods[] = {(30_Hz).getPeriodNsecs(), (60_Hz).getPeriodNsecs(),
42                                      (72_Hz).getPeriodNsecs(), (90_Hz).getPeriodNsecs(),
43                                      (120_Hz).getPeriodNsecs()};
44 
45 constexpr auto kLayerVoteTypes = ftl::enum_range<scheduler::RefreshRateSelector::LayerVoteType>();
46 constexpr auto kCompositionCoverage = ftl::enum_range<CompositionCoverage>();
47 
48 constexpr PowerMode kPowerModes[] = {PowerMode::ON, PowerMode::DOZE, PowerMode::OFF,
49                                      PowerMode::DOZE_SUSPEND, PowerMode::ON_SUSPEND};
50 
51 constexpr uint16_t kRandomStringLength = 256;
52 constexpr std::chrono::duration kSyncPeriod(16ms);
53 constexpr PhysicalDisplayId kDisplayId = PhysicalDisplayId::fromPort(42u);
54 
55 template <typename T>
dump(T * component,FuzzedDataProvider * fdp)56 void dump(T* component, FuzzedDataProvider* fdp) {
57     std::string res = fdp->ConsumeRandomLengthString(kRandomStringLength);
58     component->dump(res);
59 }
60 
makeFakeFence()61 inline sp<Fence> makeFakeFence() {
62     return sp<Fence>::make(memfd_create("fd", MFD_ALLOW_SEALING));
63 }
64 
65 class SchedulerFuzzer {
66 public:
SchedulerFuzzer(const uint8_t * data,size_t size)67     SchedulerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
68     void process();
69 
70 private:
71     void fuzzRefreshRateSelection();
72     void fuzzRefreshRateSelector();
73     void fuzzPresentLatencyTracker();
74     void fuzzFrameTargeter();
75     void fuzzVSyncModulator();
76     void fuzzVSyncPredictor();
77     void fuzzVSyncReactor();
78     void fuzzLayerHistory();
79     void fuzzCallbackToken(scheduler::VSyncDispatchTimerQueue* dispatch);
80     void fuzzVSyncDispatchTimerQueue();
81     void fuzzOneShotTimer();
82     void fuzzEventThread();
83     PhysicalDisplayId getPhysicalDisplayId();
84 
85     FuzzedDataProvider mFdp;
86 
87     std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule;
88 };
89 
getPhysicalDisplayId()90 PhysicalDisplayId SchedulerFuzzer::getPhysicalDisplayId() {
91     PhysicalDisplayId internalDispId = PhysicalDisplayId::fromPort(111u);
92     PhysicalDisplayId externalDispId = PhysicalDisplayId::fromPort(222u);
93     PhysicalDisplayId randomDispId = PhysicalDisplayId::fromPort(mFdp.ConsumeIntegral<uint16_t>());
94     PhysicalDisplayId dispId64Bit = PhysicalDisplayId::fromEdid(0xffu, 0xffffu, 0xffff'ffffu);
95     PhysicalDisplayId displayId = mFdp.PickValueInArray<PhysicalDisplayId>(
96             {internalDispId, externalDispId, dispId64Bit, randomDispId});
97     return displayId;
98 }
99 
fuzzEventThread()100 void SchedulerFuzzer::fuzzEventThread() {
101     mVsyncSchedule = std::shared_ptr<scheduler::VsyncSchedule>(
102             new scheduler::VsyncSchedule(getPhysicalDisplayId(),
103                                          std::make_shared<mock::VSyncTracker>(),
104                                          std::make_shared<mock::VSyncDispatch>(), nullptr));
105     const auto getVsyncPeriod = [](uid_t /* uid */) { return kSyncPeriod.count(); };
106     std::unique_ptr<android::impl::EventThread> thread = std::make_unique<
107             android::impl::EventThread>("fuzzer", mVsyncSchedule, nullptr, nullptr, getVsyncPeriod,
108                                         (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>(),
109                                         (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>());
110 
111     thread->onHotplugReceived(getPhysicalDisplayId(), mFdp.ConsumeBool());
112     sp<EventThreadConnection> connection =
113             sp<EventThreadConnection>::make(thread.get(), mFdp.ConsumeIntegral<uint16_t>(),
114                                             nullptr);
115     thread->requestNextVsync(connection);
116     thread->setVsyncRate(mFdp.ConsumeIntegral<uint32_t>() /*rate*/, connection);
117 
118     thread->setDuration((std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>(),
119                         (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>());
120     thread->registerDisplayEventConnection(connection);
121     thread->enableSyntheticVsync(mFdp.ConsumeBool());
122     dump<android::impl::EventThread>(thread.get(), &mFdp);
123 }
124 
fuzzCallbackToken(scheduler::VSyncDispatchTimerQueue * dispatch)125 void SchedulerFuzzer::fuzzCallbackToken(scheduler::VSyncDispatchTimerQueue* dispatch) {
126     scheduler::VSyncDispatch::CallbackToken tmp = dispatch->registerCallback(
127             [&](auto, auto, auto) {
128                 dispatch->schedule(tmp,
129                                    {.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
130                                     .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
131                                     .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()});
132             },
133             "o.o");
134     dispatch->schedule(tmp,
135                        {.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
136                         .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
137                         .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()});
138     dispatch->unregisterCallback(tmp);
139     dispatch->cancel(tmp);
140 }
141 
fuzzVSyncDispatchTimerQueue()142 void SchedulerFuzzer::fuzzVSyncDispatchTimerQueue() {
143     auto stubTracker = std::make_shared<FuzzImplVSyncTracker>(mFdp.ConsumeIntegral<nsecs_t>());
144     scheduler::VSyncDispatchTimerQueue
145             mDispatch{std::make_unique<scheduler::ControllableClock>(), stubTracker,
146                       mFdp.ConsumeIntegral<nsecs_t>() /*dispatchGroupThreshold*/,
147                       mFdp.ConsumeIntegral<nsecs_t>() /*vSyncMoveThreshold*/};
148 
149     fuzzCallbackToken(&mDispatch);
150 
151     dump<scheduler::VSyncDispatchTimerQueue>(&mDispatch, &mFdp);
152 
153     scheduler::VSyncDispatchTimerQueueEntry entry(
154             "fuzz", [](auto, auto, auto) {},
155             mFdp.ConsumeIntegral<nsecs_t>() /*vSyncMoveThreshold*/);
156     entry.update(*stubTracker, 0);
157     entry.schedule({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
158                     .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
159                     .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()},
160                    *stubTracker, 0);
161     entry.disarm();
162     entry.ensureNotRunning();
163     entry.schedule({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
164                     .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
165                     .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()},
166                    *stubTracker, 0);
167     auto const wakeup = entry.wakeupTime();
168     auto const ready = entry.readyTime();
169     entry.callback(entry.executing(), *wakeup, *ready);
170     entry.addPendingWorkloadUpdate({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
171                                     .readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
172                                     .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()});
173     dump<scheduler::VSyncDispatchTimerQueueEntry>(&entry, &mFdp);
174 }
175 
fuzzVSyncPredictor()176 void SchedulerFuzzer::fuzzVSyncPredictor() {
177     uint16_t now = mFdp.ConsumeIntegral<uint16_t>();
178     uint16_t historySize = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX);
179     uint16_t minimumSamplesForPrediction = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX);
180     scheduler::VSyncPredictor tracker{kDisplayId, mFdp.ConsumeIntegral<uint16_t>() /*period*/,
181                                       historySize, minimumSamplesForPrediction,
182                                       mFdp.ConsumeIntegral<uint32_t>() /*outlierTolerancePercent*/};
183     uint16_t period = mFdp.ConsumeIntegral<uint16_t>();
184     tracker.setPeriod(period);
185     for (uint16_t i = 0; i < minimumSamplesForPrediction; ++i) {
186         if (!tracker.needsMoreSamples()) {
187             break;
188         }
189         tracker.addVsyncTimestamp(now += period);
190     }
191     tracker.nextAnticipatedVSyncTimeFrom(now);
192     tracker.resetModel();
193 }
194 
fuzzOneShotTimer()195 void SchedulerFuzzer::fuzzOneShotTimer() {
196     FakeClock* clock = new FakeClock();
197     std::unique_ptr<scheduler::OneShotTimer> idleTimer = std::make_unique<scheduler::OneShotTimer>(
198             mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/,
199             (std::chrono::milliseconds)mFdp.ConsumeIntegral<uint8_t>() /*val*/,
200             [] {} /*resetCallback*/, [] {} /*timeoutCallback*/, std::unique_ptr<FakeClock>(clock));
201     idleTimer->start();
202     idleTimer->reset();
203     idleTimer->stop();
204 }
205 
fuzzLayerHistory()206 void SchedulerFuzzer::fuzzLayerHistory() {
207     TestableSurfaceFlinger flinger;
208     flinger.setupScheduler(std::make_unique<android::mock::VsyncController>(),
209                            std::make_unique<android::mock::VSyncTracker>(),
210                            std::make_unique<android::mock::EventThread>(),
211                            std::make_unique<android::mock::EventThread>());
212     flinger.setupTimeStats(std::make_unique<android::mock::TimeStats>());
213     std::unique_ptr<android::renderengine::RenderEngine> renderEngine =
214             std::make_unique<android::renderengine::mock::RenderEngine>();
215     flinger.setupRenderEngine(std::move(renderEngine));
216     flinger.setupComposer(std::make_unique<android::Hwc2::mock::Composer>());
217 
218     scheduler::TestableScheduler* scheduler = flinger.scheduler();
219 
220     scheduler::LayerHistory& historyV1 = scheduler->mutableLayerHistory();
221     nsecs_t time1 = systemTime();
222     nsecs_t time2 = time1;
223     uint8_t historySize = mFdp.ConsumeIntegral<uint8_t>();
224 
225     sp<FuzzImplLayer> layer1 = sp<FuzzImplLayer>::make(flinger.flinger());
226     sp<FuzzImplLayer> layer2 = sp<FuzzImplLayer>::make(flinger.flinger());
227 
228     for (int i = 0; i < historySize; ++i) {
229         historyV1.record(layer1->getSequence(), layer1->getLayerProps(), time1, time1,
230                          scheduler::LayerHistory::LayerUpdateType::Buffer);
231         historyV1.record(layer2->getSequence(), layer2->getLayerProps(), time2, time2,
232                          scheduler::LayerHistory::LayerUpdateType::Buffer);
233         time1 += mFdp.PickValueInArray(kVsyncPeriods);
234         time2 += mFdp.PickValueInArray(kVsyncPeriods);
235     }
236     historyV1.summarize(*scheduler->refreshRateSelector(), time1);
237     historyV1.summarize(*scheduler->refreshRateSelector(), time2);
238 
239     scheduler->createConnection(std::make_unique<android::mock::EventThread>());
240 
241     scheduler::ConnectionHandle handle;
242     scheduler->createDisplayEventConnection(handle);
243     scheduler->setDuration(handle, (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>(),
244                            (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>());
245 
246     std::string result = mFdp.ConsumeRandomLengthString(kRandomStringLength);
247     utils::Dumper dumper(result);
248     scheduler->dump(dumper);
249 }
250 
fuzzVSyncReactor()251 void SchedulerFuzzer::fuzzVSyncReactor() {
252     std::shared_ptr<FuzzImplVSyncTracker> vSyncTracker = std::make_shared<FuzzImplVSyncTracker>();
253     scheduler::VSyncReactor reactor(kDisplayId,
254                                     std::make_unique<ClockWrapper>(
255                                             std::make_shared<FuzzImplClock>()),
256                                     *vSyncTracker, mFdp.ConsumeIntegral<uint8_t>() /*pendingLimit*/,
257                                     false);
258 
259     reactor.startPeriodTransition(mFdp.ConsumeIntegral<nsecs_t>(), mFdp.ConsumeBool());
260     bool periodFlushed = false; // Value does not matter, since this is an out
261                                 // param from addHwVsyncTimestamp.
262     reactor.addHwVsyncTimestamp(0, std::nullopt, &periodFlushed);
263     reactor.addHwVsyncTimestamp(mFdp.ConsumeIntegral<nsecs_t>() /*newPeriod*/, std::nullopt,
264                                 &periodFlushed);
265 
266     const auto fence = std::make_shared<FenceTime>(makeFakeFence());
267     vSyncTracker->addVsyncTimestamp(mFdp.ConsumeIntegral<nsecs_t>());
268     FenceTime::Snapshot snap(mFdp.ConsumeIntegral<nsecs_t>());
269     fence->applyTrustedSnapshot(snap);
270     reactor.setIgnorePresentFences(mFdp.ConsumeBool());
271     reactor.addPresentFence(fence);
272     dump<scheduler::VSyncReactor>(&reactor, &mFdp);
273 }
274 
fuzzVSyncModulator()275 void SchedulerFuzzer::fuzzVSyncModulator() {
276     enum {
277         SF_OFFSET_LATE,
278         APP_OFFSET_LATE,
279         SF_DURATION_LATE,
280         APP_DURATION_LATE,
281         SF_OFFSET_EARLY,
282         APP_OFFSET_EARLY,
283         SF_DURATION_EARLY,
284         APP_DURATION_EARLY,
285         SF_OFFSET_EARLY_GPU,
286         APP_OFFSET_EARLY_GPU,
287         SF_DURATION_EARLY_GPU,
288         APP_DURATION_EARLY_GPU,
289         HWC_MIN_WORK_DURATION,
290     };
291     using Schedule = scheduler::TransactionSchedule;
292     using nanos = std::chrono::nanoseconds;
293     using FuzzImplVsyncModulator = scheduler::FuzzImplVsyncModulator;
294     const scheduler::VsyncConfig early{SF_OFFSET_EARLY, APP_OFFSET_EARLY, nanos(SF_DURATION_LATE),
295                                        nanos(APP_DURATION_LATE)};
296     const scheduler::VsyncConfig earlyGpu{SF_OFFSET_EARLY_GPU, APP_OFFSET_EARLY_GPU,
297                                           nanos(SF_DURATION_EARLY), nanos(APP_DURATION_EARLY)};
298     const scheduler::VsyncConfig late{SF_OFFSET_LATE, APP_OFFSET_LATE, nanos(SF_DURATION_EARLY_GPU),
299                                       nanos(APP_DURATION_EARLY_GPU)};
300     const scheduler::VsyncConfigSet offsets = {early, earlyGpu, late, nanos(HWC_MIN_WORK_DURATION)};
301     sp<FuzzImplVsyncModulator> vSyncModulator =
302             sp<FuzzImplVsyncModulator>::make(offsets, scheduler::Now);
303     (void)vSyncModulator->setVsyncConfigSet(offsets);
304     (void)vSyncModulator->setTransactionSchedule(Schedule::Late);
305     const auto token = sp<BBinder>::make();
306     (void)vSyncModulator->setTransactionSchedule(Schedule::EarlyStart, token);
307     vSyncModulator->binderDied(token);
308 }
309 
fuzzRefreshRateSelection()310 void SchedulerFuzzer::fuzzRefreshRateSelection() {
311     TestableSurfaceFlinger flinger;
312     flinger.setupScheduler(std::make_unique<android::mock::VsyncController>(),
313                            std::make_unique<android::mock::VSyncTracker>(),
314                            std::make_unique<android::mock::EventThread>(),
315                            std::make_unique<android::mock::EventThread>());
316 
317     sp<Client> client;
318     LayerCreationArgs args(flinger.flinger(), client,
319                            mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/,
320                            mFdp.ConsumeIntegral<uint16_t>() /*layerFlags*/, LayerMetadata());
321     sp<Layer> layer = sp<Layer>::make(args);
322 
323     layer->setFrameRateSelectionPriority(mFdp.ConsumeIntegral<int16_t>());
324 }
325 
fuzzRefreshRateSelector()326 void SchedulerFuzzer::fuzzRefreshRateSelector() {
327     using RefreshRateSelector = scheduler::RefreshRateSelector;
328     using LayerRequirement = RefreshRateSelector::LayerRequirement;
329     using RefreshRateStats = scheduler::RefreshRateStats;
330 
331     const uint16_t minRefreshRate = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX >> 1);
332     const uint16_t maxRefreshRate =
333             mFdp.ConsumeIntegralInRange<uint16_t>(minRefreshRate + 1, UINT16_MAX);
334 
335     const DisplayModeId modeId{mFdp.ConsumeIntegralInRange<uint8_t>(0, 10)};
336 
337     DisplayModes displayModes;
338     for (uint16_t fps = minRefreshRate; fps < maxRefreshRate; ++fps) {
339         displayModes.try_emplace(modeId,
340                                  mock::createDisplayMode(modeId,
341                                                          Fps::fromValue(static_cast<float>(fps))));
342     }
343 
344     RefreshRateSelector refreshRateSelector(displayModes, modeId);
345 
346     const RefreshRateSelector::GlobalSignals globalSignals = {.touch = false, .idle = false};
347     std::vector<LayerRequirement> layers = {{.weight = mFdp.ConsumeFloatingPoint<float>()}};
348 
349     refreshRateSelector.getRankedFrameRates(layers, globalSignals);
350 
351     layers[0].name = mFdp.ConsumeRandomLengthString(kRandomStringLength);
352     layers[0].ownerUid = mFdp.ConsumeIntegral<uint16_t>();
353     layers[0].desiredRefreshRate = Fps::fromValue(mFdp.ConsumeFloatingPoint<float>());
354     layers[0].vote = mFdp.PickValueInArray(kLayerVoteTypes.values);
355     auto frameRateOverrides =
356             refreshRateSelector.getFrameRateOverrides(layers,
357                                                       Fps::fromValue(
358                                                               mFdp.ConsumeFloatingPoint<float>()),
359                                                       globalSignals);
360 
361     {
362         ftl::FakeGuard guard(kMainThreadContext);
363 
364         refreshRateSelector.setPolicy(
365                 RefreshRateSelector::
366                         DisplayManagerPolicy{modeId,
367                                              {Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()),
368                                               Fps::fromValue(mFdp.ConsumeFloatingPoint<float>())}});
369         refreshRateSelector.setPolicy(
370                 RefreshRateSelector::OverridePolicy{modeId,
371                                                     {Fps::fromValue(
372                                                              mFdp.ConsumeFloatingPoint<float>()),
373                                                      Fps::fromValue(
374                                                              mFdp.ConsumeFloatingPoint<float>())}});
375         refreshRateSelector.setPolicy(RefreshRateSelector::NoOverridePolicy{});
376 
377         refreshRateSelector.setActiveMode(modeId,
378                                           Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()));
379     }
380 
381     RefreshRateSelector::isFractionalPairOrMultiple(Fps::fromValue(
382                                                             mFdp.ConsumeFloatingPoint<float>()),
383                                                     Fps::fromValue(
384                                                             mFdp.ConsumeFloatingPoint<float>()));
385     RefreshRateSelector::getFrameRateDivisor(Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()),
386                                              Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()));
387 
388     android::mock::TimeStats timeStats;
389     RefreshRateStats refreshRateStats(timeStats, Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()),
390                                       PowerMode::OFF);
391 
392     const auto fpsOpt = displayModes.get(modeId).transform(
393             [](const DisplayModePtr& mode) { return mode->getFps(); });
394     refreshRateStats.setRefreshRate(*fpsOpt);
395 
396     refreshRateStats.setPowerMode(mFdp.PickValueInArray(kPowerModes));
397 }
398 
fuzzPresentLatencyTracker()399 void SchedulerFuzzer::fuzzPresentLatencyTracker() {
400     scheduler::PresentLatencyTracker tracker;
401 
402     int i = 5;
403     while (i-- > 0) {
404         tracker.trackPendingFrame(getFuzzedTimePoint(mFdp),
405                                   std::make_shared<FenceTime>(makeFakeFence()));
406     }
407 }
408 
fuzzFrameTargeter()409 void SchedulerFuzzer::fuzzFrameTargeter() {
410     scheduler::FrameTargeter frameTargeter(kDisplayId, mFdp.ConsumeBool());
411 
412     const struct VsyncSource final : scheduler::IVsyncSource {
413         explicit VsyncSource(FuzzedDataProvider& fuzzer) : fuzzer(fuzzer) {}
414         FuzzedDataProvider& fuzzer;
415 
416         Period period() const { return getFuzzedDuration(fuzzer); }
417         TimePoint vsyncDeadlineAfter(TimePoint) const { return getFuzzedTimePoint(fuzzer); }
418     } vsyncSource{mFdp};
419 
420     int i = 10;
421     while (i-- > 0) {
422         frameTargeter.beginFrame({.frameBeginTime = getFuzzedTimePoint(mFdp),
423                                   .vsyncId = getFuzzedVsyncId(mFdp),
424                                   .expectedVsyncTime = getFuzzedTimePoint(mFdp),
425                                   .sfWorkDuration = getFuzzedDuration(mFdp)},
426                                  vsyncSource);
427 
428         frameTargeter.setPresentFence(makeFakeFence());
429 
430         frameTargeter.endFrame(
431                 {.compositionCoverage = mFdp.PickValueInArray(kCompositionCoverage.values)});
432     }
433 }
434 
process()435 void SchedulerFuzzer::process() {
436     fuzzRefreshRateSelection();
437     fuzzRefreshRateSelector();
438     fuzzPresentLatencyTracker();
439     fuzzFrameTargeter();
440     fuzzVSyncModulator();
441     fuzzVSyncPredictor();
442     fuzzVSyncReactor();
443     fuzzLayerHistory();
444     fuzzEventThread();
445     fuzzVSyncDispatchTimerQueue();
446     fuzzOneShotTimer();
447 }
448 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)449 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
450     SchedulerFuzzer schedulerFuzzer(data, size);
451     schedulerFuzzer.process();
452     return 0;
453 }
454 
455 } // namespace android::fuzz
456