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 /*
19 Reference for some of the classes and functions has been taken from unittests
20 present in frameworks/native/services/surfaceflinger/tests/unittests
21 */
22
23 #pragma once
24
25 #include <scheduler/TimeKeeper.h>
26
27 #include "Clock.h"
28 #include "Layer.h"
29 #include "Scheduler/EventThread.h"
30 #include "Scheduler/Scheduler.h"
31 #include "Scheduler/VSyncTracker.h"
32 #include "Scheduler/VsyncModulator.h"
33
34 namespace android::fuzz {
35
36 class FuzzImplClock : public android::scheduler::Clock {
37 public:
now()38 nsecs_t now() const { return 1; }
39 };
40
41 class ClockWrapper : public android::scheduler::Clock {
42 public:
ClockWrapper(std::shared_ptr<android::scheduler::Clock> const & clock)43 ClockWrapper(std::shared_ptr<android::scheduler::Clock> const& clock) : mClock(clock) {}
44
now()45 nsecs_t now() const { return mClock->now(); }
46
47 private:
48 std::shared_ptr<android::scheduler::Clock> const mClock;
49 };
50
51 } // namespace android::fuzz
52
53 namespace android {
54
55 using namespace std::chrono_literals;
56
57 class FakeClock : public Clock {
58 public:
59 virtual ~FakeClock() = default;
now()60 std::chrono::steady_clock::time_point now() const override { return mNow; }
61
advanceTime(std::chrono::nanoseconds delta)62 void advanceTime(std::chrono::nanoseconds delta) { mNow += delta; }
63
64 private:
65 std::chrono::steady_clock::time_point mNow;
66 };
67
68 class FuzzImplLayer : public Layer {
69 public:
FuzzImplLayer(SurfaceFlinger * flinger,std::string name)70 FuzzImplLayer(SurfaceFlinger* flinger, std::string name)
71 : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {}
FuzzImplLayer(SurfaceFlinger * flinger)72 explicit FuzzImplLayer(SurfaceFlinger* flinger) : FuzzImplLayer(flinger, "FuzzLayer") {}
73
getType()74 const char* getType() const override { return ""; }
75
isVisible()76 bool isVisible() const override { return true; }
77
createClone(uint32_t)78 sp<Layer> createClone(uint32_t /* mirrorRootId */) override { return nullptr; }
79 };
80
81 class FuzzImplVSyncTracker : public scheduler::VSyncTracker {
82 public:
FuzzImplVSyncTracker(nsecs_t period)83 FuzzImplVSyncTracker(nsecs_t period) { mPeriod = period; }
84
85 FuzzImplVSyncTracker() = default;
86
addVsyncTimestamp(nsecs_t)87 bool addVsyncTimestamp(nsecs_t /* timestamp */) override { return true; }
88
nextAnticipatedVSyncTimeFrom(nsecs_t)89 nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t /* timePoint */) const override { return 1; }
90
currentPeriod()91 nsecs_t currentPeriod() const override { return 1; }
92
setPeriod(nsecs_t)93 void setPeriod(nsecs_t /* period */) override {}
94
resetModel()95 void resetModel() override {}
96
needsMoreSamples()97 bool needsMoreSamples() const override { return true; }
98
isVSyncInPhase(nsecs_t,Fps)99 bool isVSyncInPhase(nsecs_t /* timePoint */, Fps /* frameRate */) const override {
100 return true;
101 }
102
setRenderRate(Fps)103 void setRenderRate(Fps) override {}
104
nextVSyncTime(nsecs_t timePoint)105 nsecs_t nextVSyncTime(nsecs_t timePoint) const {
106 if (timePoint % mPeriod == 0) {
107 return timePoint;
108 }
109 return (timePoint - (timePoint % mPeriod) + mPeriod);
110 }
111
dump(std::string &)112 void dump(std::string& /* result */) const override {}
113
114 protected:
115 nsecs_t mPeriod;
116 };
117
118 class FuzzImplVSyncDispatch : public scheduler::VSyncDispatch {
119 public:
registerCallback(Callback,std::string)120 CallbackToken registerCallback(Callback /* callbackFn */,
121 std::string /* callbackName */) override {
122 return CallbackToken{};
123 }
124
unregisterCallback(CallbackToken)125 void unregisterCallback(CallbackToken /* token */) override {}
126
schedule(CallbackToken,ScheduleTiming)127 scheduler::ScheduleResult schedule(CallbackToken /* token */,
128 ScheduleTiming /* scheduleTiming */) override {
129 return (scheduler::ScheduleResult)0;
130 }
131
update(CallbackToken,ScheduleTiming)132 scheduler::ScheduleResult update(CallbackToken /* token */,
133 ScheduleTiming /* scheduleTiming */) override {
134 return (scheduler::ScheduleResult)0;
135 }
136
cancel(CallbackToken)137 scheduler::CancelResult cancel(CallbackToken /* token */) override {
138 return (scheduler::CancelResult)0;
139 }
140
dump(std::string &)141 void dump(std::string& /* result */) const override {}
142 };
143
144 } // namespace android
145
146 namespace android::scheduler {
147
148 class ControllableClock : public TimeKeeper {
149 public:
now()150 nsecs_t now() const { return 1; };
alarmAt(std::function<void ()>,nsecs_t)151 void alarmAt(std::function<void()> /* callback */, nsecs_t /* time */) override {}
alarmCancel()152 void alarmCancel() override {}
dump(std::string &)153 void dump(std::string& /* result */) const override {}
154
alarmAtDefaultBehavior(std::function<void ()> const & callback,nsecs_t time)155 void alarmAtDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
156 mCallback = callback;
157 mNextCallbackTime = time;
158 }
159
fakeTime()160 nsecs_t fakeTime() const { return mCurrentTime; }
161
advanceToNextCallback()162 void advanceToNextCallback() {
163 mCurrentTime = mNextCallbackTime;
164 if (mCallback) {
165 mCallback();
166 }
167 }
168
advanceBy(nsecs_t advancement)169 void advanceBy(nsecs_t advancement) {
170 mCurrentTime += advancement;
171 if (mCurrentTime >= (mNextCallbackTime + mLag) && mCallback) {
172 mCallback();
173 }
174 };
175
setLag(nsecs_t lag)176 void setLag(nsecs_t lag) { mLag = lag; }
177
178 private:
179 std::function<void()> mCallback;
180 nsecs_t mNextCallbackTime = 0;
181 nsecs_t mCurrentTime = 0;
182 nsecs_t mLag = 0;
183 };
184
Now()185 static VsyncModulator::TimePoint Now() {
186 static VsyncModulator::TimePoint now;
187 return now += VsyncModulator::MIN_EARLY_TRANSACTION_TIME;
188 }
189
190 class FuzzImplVsyncModulator : public VsyncModulator {
191 public:
FuzzImplVsyncModulator(const VsyncConfigSet & config,Now now)192 FuzzImplVsyncModulator(const VsyncConfigSet& config, Now now) : VsyncModulator(config, now) {}
193
binderDied(const wp<IBinder> & token)194 void binderDied(const wp<IBinder>& token) { VsyncModulator::binderDied(token); }
195 };
196 } // namespace android::scheduler
197