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, (), (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             mRenderEventConnection = mRenderEventThread->createEventConnection();
78         } else {
79             mLastCompositeEventThread = std::move(eventThreadPtr);
80             mLastCompositeEventConnection = mLastCompositeEventThread->createEventConnection();
81         }
82     }
83 
refreshRateSelector()84     auto refreshRateSelector() { return pacesetterSelectorPtr(); }
85 
86     void registerDisplay(
87             PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
88             std::optional<PhysicalDisplayId> activeDisplayIdOpt = {},
89             std::shared_ptr<VSyncTracker> vsyncTracker = std::make_shared<mock::VSyncTracker>()) {
90         registerDisplay(displayId, std::move(selectorPtr),
91                         std::make_unique<mock::VsyncController>(), vsyncTracker,
92                         activeDisplayIdOpt.value_or(displayId));
93     }
94 
registerDisplay(PhysicalDisplayId displayId,RefreshRateSelectorPtr selectorPtr,std::unique_ptr<VsyncController> controller,std::shared_ptr<VSyncTracker> tracker,PhysicalDisplayId activeDisplayId)95     void registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
96                          std::unique_ptr<VsyncController> controller,
97                          std::shared_ptr<VSyncTracker> tracker, PhysicalDisplayId activeDisplayId) {
98         ftl::FakeGuard guard(kMainThreadContext);
99         Scheduler::registerDisplayInternal(displayId, std::move(selectorPtr),
100                                            std::shared_ptr<VsyncSchedule>(
101                                                    new VsyncSchedule(displayId, std::move(tracker),
102                                                                      std::make_shared<
103                                                                              mock::VSyncDispatch>(),
104                                                                      std::move(controller),
105                                                                      mockRequestHardwareVsync
106                                                                              .AsStdFunction())),
107                                            activeDisplayId);
108     }
109 
110     testing::MockFunction<void(PhysicalDisplayId, bool)> mockRequestHardwareVsync;
111 
setDisplayPowerMode(PhysicalDisplayId displayId,hal::PowerMode powerMode)112     void setDisplayPowerMode(PhysicalDisplayId displayId, hal::PowerMode powerMode) {
113         ftl::FakeGuard guard(kMainThreadContext);
114         Scheduler::setDisplayPowerMode(displayId, powerMode);
115     }
116 
pacesetterDisplayId()117     std::optional<PhysicalDisplayId> pacesetterDisplayId() const NO_THREAD_SAFETY_ANALYSIS {
118         return mPacesetterDisplayId;
119     }
120 
setPacesetterDisplay(PhysicalDisplayId displayId)121     void setPacesetterDisplay(PhysicalDisplayId displayId) {
122         ftl::FakeGuard guard(kMainThreadContext);
123         Scheduler::setPacesetterDisplay(displayId);
124     }
125 
getDisplayPowerMode(PhysicalDisplayId id)126     std::optional<hal::PowerMode> getDisplayPowerMode(PhysicalDisplayId id) {
127         ftl::FakeGuard guard1(kMainThreadContext);
128         ftl::FakeGuard guard2(mDisplayLock);
129         return mDisplays.get(id).transform(
130                 [](const Display& display) { return display.powerMode; });
131     }
132 
133     using Scheduler::resyncAllToHardwareVsync;
134 
mutableLayerHistory()135     auto& mutableLayerHistory() { return mLayerHistory; }
mutableAttachedChoreographers()136     auto& mutableAttachedChoreographers() { return mAttachedChoreographers; }
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 
setContentRequirements(std::vector<RefreshRateSelector::LayerRequirement> layers)179     void setContentRequirements(std::vector<RefreshRateSelector::LayerRequirement> layers) {
180         std::lock_guard<std::mutex> lock(mPolicyLock);
181         mPolicy.contentRequirements = std::move(layers);
182     }
183 
184     using Scheduler::DisplayModeChoice;
185     using Scheduler::DisplayModeChoiceMap;
186 
chooseDisplayModes()187     DisplayModeChoiceMap chooseDisplayModes() NO_THREAD_SAFETY_ANALYSIS {
188         return Scheduler::chooseDisplayModes();
189     }
190 
dispatchCachedReportedMode()191     void dispatchCachedReportedMode() {
192         std::lock_guard<std::mutex> lock(mPolicyLock);
193         Scheduler::dispatchCachedReportedMode();
194     }
195 
clearCachedReportedMode()196     void clearCachedReportedMode() {
197         std::lock_guard<std::mutex> lock(mPolicyLock);
198         mPolicy.cachedModeChangedParams.reset();
199     }
200 
setInitialHwVsyncEnabled(PhysicalDisplayId id,bool enabled)201     void setInitialHwVsyncEnabled(PhysicalDisplayId id, bool enabled) {
202         auto schedule = getVsyncSchedule(id);
203         std::lock_guard<std::mutex> lock(schedule->mHwVsyncLock);
204         schedule->mHwVsyncState = enabled ? VsyncSchedule::HwVsyncState::Enabled
205                                           : VsyncSchedule::HwVsyncState::Disabled;
206     }
207 
updateAttachedChoreographers(const surfaceflinger::frontend::LayerHierarchy & layerHierarchy,Fps displayRefreshRate)208     void updateAttachedChoreographers(
209             const surfaceflinger::frontend::LayerHierarchy& layerHierarchy,
210             Fps displayRefreshRate) {
211         Scheduler::updateAttachedChoreographers(layerHierarchy, displayRefreshRate);
212     }
213 
214     using Scheduler::onHardwareVsyncRequest;
215 
216 private:
217     // ICompositor overrides:
configure()218     void configure() override {}
commit(PhysicalDisplayId,const scheduler::FrameTargets &)219     bool commit(PhysicalDisplayId, const scheduler::FrameTargets&) override { return false; }
composite(PhysicalDisplayId,const scheduler::FrameTargeters &)220     CompositeResultsPerDisplay composite(PhysicalDisplayId,
221                                          const scheduler::FrameTargeters&) override {
222         return {};
223     }
sample()224     void sample() override {}
sendNotifyExpectedPresentHint(PhysicalDisplayId)225     void sendNotifyExpectedPresentHint(PhysicalDisplayId) override {}
226 };
227 
228 } // namespace android::scheduler
229