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