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 <Scheduler/Scheduler.h>
20 #include <gmock/gmock.h>
21 #include <gui/ISurfaceComposer.h>
22 
23 #include "Scheduler/EventThread.h"
24 #include "Scheduler/LayerHistory.h"
25 #include "Scheduler/Scheduler.h"
26 #include "Scheduler/VSyncTracker.h"
27 #include "Scheduler/VsyncController.h"
28 #include "mock/MockVSyncTracker.h"
29 #include "mock/MockVsyncController.h"
30 
31 namespace android {
32 
33 class TestableScheduler : public Scheduler {
34 public:
TestableScheduler(const std::shared_ptr<scheduler::RefreshRateConfigs> & refreshRateConfigs,ISchedulerCallback & callback)35     TestableScheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>& refreshRateConfigs,
36                       ISchedulerCallback& callback)
37           : TestableScheduler(std::make_unique<mock::VsyncController>(),
38                               std::make_unique<mock::VSyncTracker>(), refreshRateConfigs,
39                               callback) {}
40 
TestableScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController,std::unique_ptr<scheduler::VSyncTracker> vsyncTracker,const std::shared_ptr<scheduler::RefreshRateConfigs> & refreshRateConfigs,ISchedulerCallback & callback)41     TestableScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController,
42                       std::unique_ptr<scheduler::VSyncTracker> vsyncTracker,
43                       const std::shared_ptr<scheduler::RefreshRateConfigs>& refreshRateConfigs,
44                       ISchedulerCallback& callback)
45           : Scheduler({std::move(vsyncController), std::move(vsyncTracker), nullptr},
46                       refreshRateConfigs, callback, createLayerHistory(),
47                       {.useContentDetection = true}) {}
48 
49     // Used to inject mock event thread.
createConnection(std::unique_ptr<EventThread> eventThread)50     ConnectionHandle createConnection(std::unique_ptr<EventThread> eventThread) {
51         return Scheduler::createConnection(std::move(eventThread));
52     }
53 
54     /* ------------------------------------------------------------------------
55      * Read-write access to private data to set up preconditions and assert
56      * post-conditions.
57      */
mutablePrimaryHWVsyncEnabled()58     auto& mutablePrimaryHWVsyncEnabled() { return mPrimaryHWVsyncEnabled; }
mutableHWVsyncAvailable()59     auto& mutableHWVsyncAvailable() { return mHWVsyncAvailable; }
60 
hasLayerHistory()61     bool hasLayerHistory() const { return static_cast<bool>(mLayerHistory); }
62 
mutableLayerHistory()63     auto* mutableLayerHistory() { return mLayerHistory.get(); }
64 
layerHistorySize()65     size_t layerHistorySize() NO_THREAD_SAFETY_ANALYSIS {
66         if (!mLayerHistory) return 0;
67         return mutableLayerHistory()->mLayerInfos.size();
68     }
69 
refreshRateConfigs()70     auto refreshRateConfigs() { return holdRefreshRateConfigs(); }
71 
getNumActiveLayers()72     size_t getNumActiveLayers() NO_THREAD_SAFETY_ANALYSIS {
73         if (!mLayerHistory) return 0;
74         return mutableLayerHistory()->mActiveLayersEnd;
75     }
76 
replaceTouchTimer(int64_t millis)77     void replaceTouchTimer(int64_t millis) {
78         if (mTouchTimer) {
79             mTouchTimer.reset();
80         }
81         mTouchTimer.emplace(
82                 "Testable Touch timer", std::chrono::milliseconds(millis),
83                 [this] { touchTimerCallback(TimerState::Reset); },
84                 [this] { touchTimerCallback(TimerState::Expired); });
85         mTouchTimer->start();
86     }
87 
isTouchActive()88     bool isTouchActive() {
89         std::lock_guard<std::mutex> lock(mFeatureStateLock);
90         return mFeatures.touch == Scheduler::TouchState::Active;
91     }
92 
dispatchCachedReportedMode()93     void dispatchCachedReportedMode() {
94         std::lock_guard<std::mutex> lock(mFeatureStateLock);
95         return Scheduler::dispatchCachedReportedMode();
96     }
97 
clearOptionalFieldsInFeatures()98     void clearOptionalFieldsInFeatures() {
99         std::lock_guard<std::mutex> lock(mFeatureStateLock);
100         mFeatures.cachedModeChangedParams.reset();
101     }
102 
onNonPrimaryDisplayModeChanged(ConnectionHandle handle,DisplayModePtr mode)103     void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) {
104         return Scheduler::onNonPrimaryDisplayModeChanged(handle, mode);
105     }
106 
~TestableScheduler()107     ~TestableScheduler() {
108         // All these pointer and container clears help ensure that GMock does
109         // not report a leaked object, since the Scheduler instance may
110         // still be referenced by something despite our best efforts to destroy
111         // it after each test is done.
112         mVsyncSchedule.controller.reset();
113         mConnections.clear();
114     }
115 };
116 
117 } // namespace android
118