xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/tests/unittests/TestableScheduler.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 #pragma once
18 
19 #include <ftl/fake_guard.h>
20 #include <gmock/gmock.h>
21 #include <gui/ISurfaceComposer.h>
22 
23 #include <scheduler/interface/ICompositor.h>
24 
25 #include "Scheduler/EventThread.h"
26 #include "Scheduler/LayerHistory.h"
27 #include "Scheduler/Scheduler.h"
28 #include "Scheduler/VSyncTracker.h"
29 #include "Scheduler/VsyncController.h"
30 #include "Scheduler/VsyncSchedule.h"
31 #include "mock/MockVSyncDispatch.h"
32 #include "mock/MockVSyncTracker.h"
33 #include "mock/MockVsyncController.h"
34 
35 namespace android {
36 class TestableSurfaceFlinger;
37 } // namespace android
38 
39 namespace android::scheduler {
40 
41 class TestableScheduler : public Scheduler, private ICompositor {
42 public:
43     TestableScheduler(RefreshRateSelectorPtr selectorPtr,
44                       TestableSurfaceFlinger& testableSurfaceFlinger, ISchedulerCallback& callback);
45 
TestableScheduler(std::unique_ptr<VsyncController> controller,std::shared_ptr<VSyncTracker> tracker,RefreshRateSelectorPtr selectorPtr,surfaceflinger::Factory & factory,TimeStats & timeStats,ISchedulerCallback & schedulerCallback)46     TestableScheduler(std::unique_ptr<VsyncController> controller,
47                       std::shared_ptr<VSyncTracker> tracker, RefreshRateSelectorPtr selectorPtr,
48                       surfaceflinger::Factory& factory, TimeStats& timeStats,
49                       ISchedulerCallback& schedulerCallback)
50           : Scheduler(*this, schedulerCallback,
51                       (FeatureFlags)Feature::kContentDetection |
52                               Feature::kSmallDirtyContentDetection,
53                       factory, selectorPtr->getActiveMode().fps, timeStats) {
54         const auto displayId = selectorPtr->getActiveMode().modePtr->getPhysicalDisplayId();
55         registerDisplay(displayId, std::move(selectorPtr), std::move(controller),
56                         std::move(tracker), displayId);
57 
58         ON_CALL(*this, postMessage).WillByDefault([](sp<MessageHandler>&& handler) {
59             // Execute task to prevent broken promise exception on destruction.
60             handler->handleMessage(Message());
61         });
62     }
63 
64     MOCK_METHOD(void, scheduleConfigure, (), (override));
65     MOCK_METHOD(void, scheduleFrame, (Duration), (override));
66     MOCK_METHOD(void, postMessage, (sp<MessageHandler>&&), (override));
67 
doFrameSignal(ICompositor & compositor,VsyncId vsyncId)68     void doFrameSignal(ICompositor& compositor, VsyncId vsyncId) {
69         ftl::FakeGuard guard1(kMainThreadContext);
70         ftl::FakeGuard guard2(mDisplayLock);
71         Scheduler::onFrameSignal(compositor, vsyncId, TimePoint());
72     }
73 
setEventThread(Cycle cycle,std::unique_ptr<EventThread> eventThreadPtr)74     void setEventThread(Cycle cycle, std::unique_ptr<EventThread> eventThreadPtr) {
75         if (cycle == Cycle::Render) {
76             mRenderEventThread = std::move(eventThreadPtr);
77         } else {
78             mLastCompositeEventThread = std::move(eventThreadPtr);
79         }
80     }
81 
refreshRateSelector()82     auto refreshRateSelector() { return pacesetterSelectorPtr(); }
83 
84     void registerDisplay(
85             PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
86             std::optional<PhysicalDisplayId> activeDisplayIdOpt = {},
87             std::shared_ptr<VSyncTracker> vsyncTracker = std::make_shared<mock::VSyncTracker>()) {
88         registerDisplay(displayId, std::move(selectorPtr),
89                         std::make_unique<mock::VsyncController>(), vsyncTracker,
90                         activeDisplayIdOpt.value_or(displayId));
91     }
92 
registerDisplay(PhysicalDisplayId displayId,RefreshRateSelectorPtr selectorPtr,std::unique_ptr<VsyncController> controller,std::shared_ptr<VSyncTracker> tracker,PhysicalDisplayId activeDisplayId)93     void registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
94                          std::unique_ptr<VsyncController> controller,
95                          std::shared_ptr<VSyncTracker> tracker, PhysicalDisplayId activeDisplayId) {
96         ftl::FakeGuard guard(kMainThreadContext);
97         Scheduler::registerDisplayInternal(displayId, std::move(selectorPtr),
98                                            std::shared_ptr<VsyncSchedule>(
99                                                    new VsyncSchedule(displayId, std::move(tracker),
100                                                                      std::make_shared<
101                                                                              mock::VSyncDispatch>(),
102                                                                      std::move(controller),
103                                                                      mockRequestHardwareVsync
104                                                                              .AsStdFunction())),
105                                            activeDisplayId);
106     }
107 
108     testing::MockFunction<void(PhysicalDisplayId, bool)> mockRequestHardwareVsync;
109 
setDisplayPowerMode(PhysicalDisplayId displayId,hal::PowerMode powerMode)110     void setDisplayPowerMode(PhysicalDisplayId displayId, hal::PowerMode powerMode) {
111         ftl::FakeGuard guard(kMainThreadContext);
112         Scheduler::setDisplayPowerMode(displayId, powerMode);
113     }
114 
pacesetterDisplayId()115     std::optional<PhysicalDisplayId> pacesetterDisplayId() const NO_THREAD_SAFETY_ANALYSIS {
116         return mPacesetterDisplayId;
117     }
118 
setPacesetterDisplay(PhysicalDisplayId displayId)119     void setPacesetterDisplay(PhysicalDisplayId displayId) {
120         ftl::FakeGuard guard(kMainThreadContext);
121         Scheduler::setPacesetterDisplay(displayId);
122     }
123 
getDisplayPowerMode(PhysicalDisplayId id)124     std::optional<hal::PowerMode> getDisplayPowerMode(PhysicalDisplayId id) {
125         ftl::FakeGuard guard1(kMainThreadContext);
126         ftl::FakeGuard guard2(mDisplayLock);
127         return mDisplays.get(id).transform(
128                 [](const Display& display) { return display.powerMode; });
129     }
130 
131     using Scheduler::resyncAllToHardwareVsync;
132 
mutableLayerHistory()133     auto& mutableLayerHistory() { return mLayerHistory; }
mutableAttachedChoreographers()134     auto& mutableAttachedChoreographers() NO_THREAD_SAFETY_ANALYSIS {
135         return mAttachedChoreographers;
136     }
137 
layerHistorySize()138     size_t layerHistorySize() NO_THREAD_SAFETY_ANALYSIS {
139         return mLayerHistory.mActiveLayerInfos.size() + mLayerHistory.mInactiveLayerInfos.size();
140     }
141 
getNumActiveLayers()142     size_t getNumActiveLayers() NO_THREAD_SAFETY_ANALYSIS {
143         return mLayerHistory.mActiveLayerInfos.size();
144     }
145 
146     void replaceTouchTimer(int64_t millis,
147                            std::function<void(bool isReset)>&& testCallback = nullptr) {
148         if (mTouchTimer) {
149             mTouchTimer.reset();
150         }
151         mTouchTimer.emplace(
152                 "Testable Touch timer", std::chrono::milliseconds(millis),
153                 [this, testCallback] {
154                     touchTimerCallback(TimerState::Reset);
155                     if (testCallback != nullptr) {
156                         testCallback(true);
157                     }
158                 },
159                 [this, testCallback] {
160                     touchTimerCallback(TimerState::Expired);
161                     if (testCallback != nullptr) {
162                         testCallback(false);
163                     }
164                 });
165         mTouchTimer->start();
166     }
167 
isTouchActive()168     bool isTouchActive() {
169         std::lock_guard<std::mutex> lock(mPolicyLock);
170         return mPolicy.touch == Scheduler::TouchState::Active;
171     }
172 
setTouchStateAndIdleTimerPolicy(GlobalSignals globalSignals)173     void setTouchStateAndIdleTimerPolicy(GlobalSignals globalSignals) {
174         std::lock_guard<std::mutex> lock(mPolicyLock);
175         mPolicy.touch = globalSignals.touch ? TouchState::Active : TouchState::Inactive;
176         mPolicy.idleTimer = globalSignals.idle ? TimerState::Expired : TimerState::Reset;
177     }
178 
179     using Scheduler::TimerState;
180 
181     using Scheduler::idleTimerCallback;
182     using Scheduler::touchTimerCallback;
183 
setContentRequirements(std::vector<RefreshRateSelector::LayerRequirement> layers)184     void setContentRequirements(std::vector<RefreshRateSelector::LayerRequirement> layers) {
185         std::lock_guard<std::mutex> lock(mPolicyLock);
186         mPolicy.contentRequirements = std::move(layers);
187     }
188 
189     using Scheduler::DisplayModeChoice;
190     using Scheduler::DisplayModeChoiceMap;
191 
chooseDisplayModes()192     DisplayModeChoiceMap chooseDisplayModes() NO_THREAD_SAFETY_ANALYSIS {
193         return Scheduler::chooseDisplayModes();
194     }
195 
196     using Scheduler::onDisplayModeChanged;
197 
setInitialHwVsyncEnabled(PhysicalDisplayId id,bool enabled)198     void setInitialHwVsyncEnabled(PhysicalDisplayId id, bool enabled) {
199         auto schedule = getVsyncSchedule(id);
200         std::lock_guard<std::mutex> lock(schedule->mHwVsyncLock);
201         schedule->mHwVsyncState = enabled ? VsyncSchedule::HwVsyncState::Enabled
202                                           : VsyncSchedule::HwVsyncState::Disabled;
203     }
204 
updateAttachedChoreographers(const surfaceflinger::frontend::LayerHierarchy & layerHierarchy,Fps displayRefreshRate)205     void updateAttachedChoreographers(
206             const surfaceflinger::frontend::LayerHierarchy& layerHierarchy,
207             Fps displayRefreshRate) {
208         Scheduler::updateAttachedChoreographers(layerHierarchy, displayRefreshRate);
209     }
210 
211     using Scheduler::onHardwareVsyncRequest;
212 
213 private:
214     // ICompositor overrides:
configure()215     void configure() override {}
commit(PhysicalDisplayId,const scheduler::FrameTargets &)216     bool commit(PhysicalDisplayId, const scheduler::FrameTargets&) override { return false; }
composite(PhysicalDisplayId,const scheduler::FrameTargeters &)217     CompositeResultsPerDisplay composite(PhysicalDisplayId,
218                                          const scheduler::FrameTargeters&) override {
219         return {};
220     }
sample()221     void sample() override {}
sendNotifyExpectedPresentHint(PhysicalDisplayId)222     void sendNotifyExpectedPresentHint(PhysicalDisplayId) override {}
223 };
224 
225 } // namespace android::scheduler
226