• 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 /*
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