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::scheduler { 36 37 class TestableScheduler : public Scheduler, private ICompositor { 38 public: TestableScheduler(RefreshRateSelectorPtr selectorPtr,ISchedulerCallback & callback)39 TestableScheduler(RefreshRateSelectorPtr selectorPtr, ISchedulerCallback& callback) 40 : TestableScheduler(std::make_unique<mock::VsyncController>(), 41 std::make_shared<mock::VSyncTracker>(), std::move(selectorPtr), 42 /* modulatorPtr */ nullptr, callback) {} 43 TestableScheduler(std::unique_ptr<VsyncController> controller,std::shared_ptr<VSyncTracker> tracker,RefreshRateSelectorPtr selectorPtr,sp<VsyncModulator> modulatorPtr,ISchedulerCallback & callback)44 TestableScheduler(std::unique_ptr<VsyncController> controller, 45 std::shared_ptr<VSyncTracker> tracker, RefreshRateSelectorPtr selectorPtr, 46 sp<VsyncModulator> modulatorPtr, ISchedulerCallback& callback) 47 : Scheduler(*this, callback, Feature::kContentDetection, std::move(modulatorPtr)) { 48 const auto displayId = selectorPtr->getActiveMode().modePtr->getPhysicalDisplayId(); 49 registerDisplay(displayId, std::move(selectorPtr), std::move(controller), 50 std::move(tracker)); 51 52 ON_CALL(*this, postMessage).WillByDefault([](sp<MessageHandler>&& handler) { 53 // Execute task to prevent broken promise exception on destruction. 54 handler->handleMessage(Message()); 55 }); 56 } 57 58 MOCK_METHOD(void, scheduleConfigure, (), (override)); 59 MOCK_METHOD(void, scheduleFrame, (), (override)); 60 MOCK_METHOD(void, postMessage, (sp<MessageHandler>&&), (override)); 61 62 // Used to inject mock event thread. createConnection(std::unique_ptr<EventThread> eventThread)63 ConnectionHandle createConnection(std::unique_ptr<EventThread> eventThread) { 64 return Scheduler::createConnection(std::move(eventThread)); 65 } 66 refreshRateSelector()67 auto refreshRateSelector() { return pacesetterSelectorPtr(); } 68 registerDisplay(PhysicalDisplayId displayId,RefreshRateSelectorPtr selectorPtr)69 void registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) { 70 registerDisplay(displayId, std::move(selectorPtr), 71 std::make_unique<mock::VsyncController>(), 72 std::make_shared<mock::VSyncTracker>()); 73 } 74 registerDisplay(PhysicalDisplayId displayId,RefreshRateSelectorPtr selectorPtr,std::unique_ptr<VsyncController> controller,std::shared_ptr<VSyncTracker> tracker)75 void registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr, 76 std::unique_ptr<VsyncController> controller, 77 std::shared_ptr<VSyncTracker> tracker) { 78 ftl::FakeGuard guard(kMainThreadContext); 79 Scheduler::registerDisplayInternal(displayId, std::move(selectorPtr), 80 std::shared_ptr<VsyncSchedule>( 81 new VsyncSchedule(displayId, std::move(tracker), 82 std::make_shared< 83 mock::VSyncDispatch>(), 84 std::move(controller), 85 mockRequestHardwareVsync 86 .AsStdFunction()))); 87 } 88 89 testing::MockFunction<void(PhysicalDisplayId, bool)> mockRequestHardwareVsync; 90 unregisterDisplay(PhysicalDisplayId displayId)91 void unregisterDisplay(PhysicalDisplayId displayId) { 92 ftl::FakeGuard guard(kMainThreadContext); 93 Scheduler::unregisterDisplay(displayId); 94 } 95 pacesetterDisplayId()96 std::optional<PhysicalDisplayId> pacesetterDisplayId() const NO_THREAD_SAFETY_ANALYSIS { 97 return mPacesetterDisplayId; 98 } 99 setPacesetterDisplay(PhysicalDisplayId displayId)100 void setPacesetterDisplay(PhysicalDisplayId displayId) { 101 ftl::FakeGuard guard(kMainThreadContext); 102 Scheduler::setPacesetterDisplay(displayId); 103 } 104 mutableAppConnectionHandle()105 auto& mutableAppConnectionHandle() { return mAppConnectionHandle; } mutableLayerHistory()106 auto& mutableLayerHistory() { return mLayerHistory; } 107 layerHistorySize()108 size_t layerHistorySize() NO_THREAD_SAFETY_ANALYSIS { 109 return mLayerHistory.mActiveLayerInfos.size() + mLayerHistory.mInactiveLayerInfos.size(); 110 } 111 getNumActiveLayers()112 size_t getNumActiveLayers() NO_THREAD_SAFETY_ANALYSIS { 113 return mLayerHistory.mActiveLayerInfos.size(); 114 } 115 replaceTouchTimer(int64_t millis)116 void replaceTouchTimer(int64_t millis) { 117 if (mTouchTimer) { 118 mTouchTimer.reset(); 119 } 120 mTouchTimer.emplace( 121 "Testable Touch timer", std::chrono::milliseconds(millis), 122 [this] { touchTimerCallback(TimerState::Reset); }, 123 [this] { touchTimerCallback(TimerState::Expired); }); 124 mTouchTimer->start(); 125 } 126 isTouchActive()127 bool isTouchActive() { 128 std::lock_guard<std::mutex> lock(mPolicyLock); 129 return mPolicy.touch == Scheduler::TouchState::Active; 130 } 131 setTouchStateAndIdleTimerPolicy(GlobalSignals globalSignals)132 void setTouchStateAndIdleTimerPolicy(GlobalSignals globalSignals) { 133 std::lock_guard<std::mutex> lock(mPolicyLock); 134 mPolicy.touch = globalSignals.touch ? TouchState::Active : TouchState::Inactive; 135 mPolicy.idleTimer = globalSignals.idle ? TimerState::Expired : TimerState::Reset; 136 } 137 setContentRequirements(std::vector<RefreshRateSelector::LayerRequirement> layers)138 void setContentRequirements(std::vector<RefreshRateSelector::LayerRequirement> layers) { 139 std::lock_guard<std::mutex> lock(mPolicyLock); 140 mPolicy.contentRequirements = std::move(layers); 141 } 142 143 using Scheduler::DisplayModeChoice; 144 using Scheduler::DisplayModeChoiceMap; 145 chooseDisplayModes()146 DisplayModeChoiceMap chooseDisplayModes() NO_THREAD_SAFETY_ANALYSIS { 147 return Scheduler::chooseDisplayModes(); 148 } 149 dispatchCachedReportedMode()150 void dispatchCachedReportedMode() { 151 std::lock_guard<std::mutex> lock(mPolicyLock); 152 Scheduler::dispatchCachedReportedMode(); 153 } 154 clearCachedReportedMode()155 void clearCachedReportedMode() { 156 std::lock_guard<std::mutex> lock(mPolicyLock); 157 mPolicy.cachedModeChangedParams.reset(); 158 } 159 onNonPrimaryDisplayModeChanged(ConnectionHandle handle,const FrameRateMode & mode)160 void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, const FrameRateMode& mode) { 161 Scheduler::onNonPrimaryDisplayModeChanged(handle, mode); 162 } 163 setInitialHwVsyncEnabled(PhysicalDisplayId id,bool enabled)164 void setInitialHwVsyncEnabled(PhysicalDisplayId id, bool enabled) { 165 auto schedule = getVsyncSchedule(id); 166 std::lock_guard<std::mutex> lock(schedule->mHwVsyncLock); 167 schedule->mHwVsyncState = enabled ? VsyncSchedule::HwVsyncState::Enabled 168 : VsyncSchedule::HwVsyncState::Disabled; 169 } 170 171 using Scheduler::onHardwareVsyncRequest; 172 173 private: 174 // ICompositor overrides: configure()175 void configure() override {} commit(PhysicalDisplayId,const scheduler::FrameTargets &)176 bool commit(PhysicalDisplayId, const scheduler::FrameTargets&) override { return false; } composite(PhysicalDisplayId,const scheduler::FrameTargeters &)177 CompositeResultsPerDisplay composite(PhysicalDisplayId, 178 const scheduler::FrameTargeters&) override { 179 return {}; 180 } sample()181 void sample() override {} 182 }; 183 184 } // namespace android::scheduler 185