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