• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 <algorithm>
20 #include <chrono>
21 #include <variant>
22 
23 #include <compositionengine/Display.h>
24 #include <compositionengine/LayerFECompositionState.h>
25 #include <compositionengine/OutputLayer.h>
26 #include <compositionengine/impl/CompositionEngine.h>
27 #include <compositionengine/impl/Display.h>
28 #include <compositionengine/impl/OutputLayerCompositionState.h>
29 #include <compositionengine/mock/DisplaySurface.h>
30 #include <gui/ScreenCaptureResults.h>
31 
32 #include "BufferQueueLayer.h"
33 #include "BufferStateLayer.h"
34 #include "ContainerLayer.h"
35 #include "DisplayDevice.h"
36 #include "EffectLayer.h"
37 #include "FakeVsyncConfiguration.h"
38 #include "FrameTracer/FrameTracer.h"
39 #include "Layer.h"
40 #include "NativeWindowSurface.h"
41 #include "Scheduler/MessageQueue.h"
42 #include "Scheduler/RefreshRateConfigs.h"
43 #include "StartPropertySetThread.h"
44 #include "SurfaceFlinger.h"
45 #include "SurfaceFlingerDefaultFactory.h"
46 #include "SurfaceInterceptor.h"
47 #include "TestableScheduler.h"
48 #include "mock/DisplayHardware/MockComposer.h"
49 #include "mock/DisplayHardware/MockDisplayMode.h"
50 #include "mock/MockFrameTimeline.h"
51 #include "mock/MockFrameTracer.h"
52 #include "mock/MockSchedulerCallback.h"
53 
54 namespace android {
55 
56 class EventThread;
57 
58 namespace renderengine {
59 
60 class RenderEngine;
61 
62 } // namespace renderengine
63 
64 namespace Hwc2 {
65 
66 class Composer;
67 
68 } // namespace Hwc2
69 
70 namespace hal = android::hardware::graphics::composer::hal;
71 
72 namespace surfaceflinger::test {
73 
74 class Factory final : public surfaceflinger::Factory {
75 public:
76     ~Factory() = default;
77 
createHWComposer(const std::string &)78     std::unique_ptr<HWComposer> createHWComposer(const std::string&) override {
79         return nullptr;
80     }
81 
createVsyncConfiguration(Fps)82     std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
83             Fps /*currentRefreshRate*/) override {
84         return std::make_unique<scheduler::FakePhaseOffsets>();
85     }
86 
createSurfaceInterceptor()87     sp<SurfaceInterceptor> createSurfaceInterceptor() override {
88         return new android::impl::SurfaceInterceptor();
89     }
90 
createStartPropertySetThread(bool timestampPropertyValue)91     sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override {
92         return new StartPropertySetThread(timestampPropertyValue);
93     }
94 
createDisplayDevice(DisplayDeviceCreationArgs & creationArgs)95     sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs& creationArgs) override {
96         return new DisplayDevice(creationArgs);
97     }
98 
createGraphicBuffer(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,std::string requestorName)99     sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format,
100                                           uint32_t layerCount, uint64_t usage,
101                                           std::string requestorName) override {
102         return new GraphicBuffer(width, height, format, layerCount, usage, requestorName);
103     }
104 
createBufferQueue(sp<IGraphicBufferProducer> * outProducer,sp<IGraphicBufferConsumer> * outConsumer,bool consumerIsSurfaceFlinger)105     void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
106                            sp<IGraphicBufferConsumer>* outConsumer,
107                            bool consumerIsSurfaceFlinger) override {
108         if (!mCreateBufferQueue) {
109             BufferQueue::createBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger);
110             return;
111         }
112         mCreateBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger);
113     }
114 
createMonitoredProducer(const sp<IGraphicBufferProducer> & producer,const sp<SurfaceFlinger> & flinger,const wp<Layer> & layer)115     sp<IGraphicBufferProducer> createMonitoredProducer(const sp<IGraphicBufferProducer>& producer,
116                                                        const sp<SurfaceFlinger>& flinger,
117                                                        const wp<Layer>& layer) override {
118         return new MonitoredProducer(producer, flinger, layer);
119     }
120 
createBufferLayerConsumer(const sp<IGraphicBufferConsumer> & consumer,renderengine::RenderEngine & renderEngine,uint32_t textureName,Layer * layer)121     sp<BufferLayerConsumer> createBufferLayerConsumer(const sp<IGraphicBufferConsumer>& consumer,
122                                                       renderengine::RenderEngine& renderEngine,
123                                                       uint32_t textureName, Layer* layer) override {
124         return new BufferLayerConsumer(consumer, renderEngine, textureName, layer);
125     }
126 
createNativeWindowSurface(const sp<IGraphicBufferProducer> & producer)127     std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
128             const sp<IGraphicBufferProducer>& producer) override {
129         if (!mCreateNativeWindowSurface) return nullptr;
130         return mCreateNativeWindowSurface(producer);
131     }
132 
createCompositionEngine()133     std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
134         return compositionengine::impl::createCompositionEngine();
135     }
136 
createBufferQueueLayer(const LayerCreationArgs &)137     sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs&) override {
138         return nullptr;
139     }
140 
createBufferStateLayer(const LayerCreationArgs &)141     sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs&) override {
142         return nullptr;
143     }
144 
createEffectLayer(const LayerCreationArgs &)145     sp<EffectLayer> createEffectLayer(const LayerCreationArgs&) override { return nullptr; }
146 
createContainerLayer(const LayerCreationArgs &)147     sp<ContainerLayer> createContainerLayer(const LayerCreationArgs&) override {
148         return nullptr;
149     }
150 
createFrameTracer()151     std::unique_ptr<FrameTracer> createFrameTracer() override {
152         return std::make_unique<mock::FrameTracer>();
153     }
154 
155     std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
156             std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid = 0) override {
157         return std::make_unique<mock::FrameTimeline>(timeStats, surfaceFlingerPid);
158     }
159 
160     using CreateBufferQueueFunction =
161             std::function<void(sp<IGraphicBufferProducer>* /* outProducer */,
162                                sp<IGraphicBufferConsumer>* /* outConsumer */,
163                                bool /* consumerIsSurfaceFlinger */)>;
164     CreateBufferQueueFunction mCreateBufferQueue;
165 
166     using CreateNativeWindowSurfaceFunction =
167             std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>(
168                     const sp<IGraphicBufferProducer>&)>;
169     CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;
170 
171     using CreateCompositionEngineFunction =
172             std::function<std::unique_ptr<compositionengine::CompositionEngine>()>;
173     CreateCompositionEngineFunction mCreateCompositionEngine;
174 };
175 
176 } // namespace surfaceflinger::test
177 
178 class TestableSurfaceFlinger {
179 public:
180     using HotplugEvent = SurfaceFlinger::HotplugEvent;
181 
mFlinger(flinger)182     TestableSurfaceFlinger(sp<SurfaceFlinger> flinger = nullptr) : mFlinger(flinger) {
183         if (!mFlinger) {
184             mFlinger = sp<SurfaceFlinger>::make(mFactory, SurfaceFlinger::SkipInitialization);
185         }
186         mFlinger->mAnimationTransactionTimeout = ms2ns(10);
187     }
188 
flinger()189     SurfaceFlinger* flinger() { return mFlinger.get(); }
scheduler()190     scheduler::TestableScheduler* scheduler() { return mScheduler; }
191 
192     // Extend this as needed for accessing SurfaceFlinger private (and public)
193     // functions.
194 
setupRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine)195     void setupRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine) {
196         mFlinger->mCompositionEngine->setRenderEngine(std::move(renderEngine));
197     }
198 
setupComposer(std::unique_ptr<Hwc2::Composer> composer)199     void setupComposer(std::unique_ptr<Hwc2::Composer> composer) {
200         mFlinger->mCompositionEngine->setHwComposer(
201                 std::make_unique<impl::HWComposer>(std::move(composer)));
202     }
203 
setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor> powerAdvisor)204     void setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor> powerAdvisor) {
205         mFlinger->mPowerAdvisor = std::move(powerAdvisor);
206     }
207 
setupTimeStats(const std::shared_ptr<TimeStats> & timeStats)208     void setupTimeStats(const std::shared_ptr<TimeStats>& timeStats) {
209         mFlinger->mCompositionEngine->setTimeStats(timeStats);
210     }
211 
212     enum class SchedulerCallbackImpl { kNoOp, kMock };
213 
214     static constexpr struct OneDisplayMode {
215     } kOneDisplayMode;
216 
217     static constexpr struct TwoDisplayModes {
218     } kTwoDisplayModes;
219 
220     using RefreshRateConfigsPtr = std::shared_ptr<scheduler::RefreshRateConfigs>;
221 
222     using DisplayModesVariant =
223             std::variant<OneDisplayMode, TwoDisplayModes, RefreshRateConfigsPtr>;
224 
225     void setupScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController,
226                         std::unique_ptr<scheduler::VSyncTracker> vsyncTracker,
227                         std::unique_ptr<EventThread> appEventThread,
228                         std::unique_ptr<EventThread> sfEventThread,
229                         SchedulerCallbackImpl callbackImpl = SchedulerCallbackImpl::kNoOp,
230                         DisplayModesVariant modesVariant = kOneDisplayMode,
231                         bool useNiceMock = false) {
232         RefreshRateConfigsPtr configs;
233         if (std::holds_alternative<RefreshRateConfigsPtr>(modesVariant)) {
234             configs = std::move(std::get<RefreshRateConfigsPtr>(modesVariant));
235         } else {
236             constexpr DisplayModeId kModeId60{0};
237             DisplayModes modes = makeModes(mock::createDisplayMode(kModeId60, 60_Hz));
238 
239             if (std::holds_alternative<TwoDisplayModes>(modesVariant)) {
240                 constexpr DisplayModeId kModeId90{1};
241                 modes.try_emplace(kModeId90, mock::createDisplayMode(kModeId90, 90_Hz));
242             }
243 
244             configs = std::make_shared<scheduler::RefreshRateConfigs>(modes, kModeId60);
245         }
246 
247         const auto fps = configs->getActiveMode()->getFps();
248         mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(fps);
249         mFlinger->mVsyncModulator = sp<scheduler::VsyncModulator>::make(
250                 mFlinger->mVsyncConfiguration->getCurrentConfigs());
251 
252         mFlinger->mRefreshRateStats =
253                 std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, fps,
254                                                               hal::PowerMode::OFF);
255 
256         using Callback = scheduler::ISchedulerCallback;
257         Callback& callback = callbackImpl == SchedulerCallbackImpl::kNoOp
258                 ? static_cast<Callback&>(mNoOpSchedulerCallback)
259                 : static_cast<Callback&>(mSchedulerCallback);
260 
261         if (useNiceMock) {
262             mScheduler =
263                     new testing::NiceMock<scheduler::TestableScheduler>(std::move(vsyncController),
264                                                                         std::move(vsyncTracker),
265                                                                         std::move(configs),
266                                                                         callback);
267         } else {
268             mScheduler = new scheduler::TestableScheduler(std::move(vsyncController),
269                                                           std::move(vsyncTracker),
270                                                           std::move(configs), callback);
271         }
272 
273         mFlinger->mAppConnectionHandle = mScheduler->createConnection(std::move(appEventThread));
274         mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread));
275         resetScheduler(mScheduler);
276     }
277 
resetScheduler(scheduler::Scheduler * scheduler)278     void resetScheduler(scheduler::Scheduler* scheduler) { mFlinger->mScheduler.reset(scheduler); }
279 
mutableScheduler()280     scheduler::TestableScheduler& mutableScheduler() { return *mScheduler; }
mockSchedulerCallback()281     scheduler::mock::SchedulerCallback& mockSchedulerCallback() { return mSchedulerCallback; }
282 
mutableVsyncModulator()283     auto& mutableVsyncModulator() { return mFlinger->mVsyncModulator; }
284 
285     using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction;
setCreateBufferQueueFunction(CreateBufferQueueFunction f)286     void setCreateBufferQueueFunction(CreateBufferQueueFunction f) {
287         mFactory.mCreateBufferQueue = f;
288     }
289 
290     using CreateNativeWindowSurfaceFunction =
291             surfaceflinger::test::Factory::CreateNativeWindowSurfaceFunction;
setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f)292     void setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f) {
293         mFactory.mCreateNativeWindowSurface = f;
294     }
295 
setInternalDisplayPrimaries(const ui::DisplayPrimaries & primaries)296     void setInternalDisplayPrimaries(const ui::DisplayPrimaries& primaries) {
297         memcpy(&mFlinger->mInternalDisplayPrimaries, &primaries, sizeof(ui::DisplayPrimaries));
298     }
299 
mutableLayerDrawingState(const sp<Layer> & layer)300     static auto& mutableLayerDrawingState(const sp<Layer>& layer) { return layer->mDrawingState; }
301 
mutableStateLock()302     auto& mutableStateLock() { return mFlinger->mStateLock; }
303 
findOutputLayerForDisplay(const sp<Layer> & layer,const sp<const DisplayDevice> & display)304     static auto findOutputLayerForDisplay(const sp<Layer>& layer,
305                                           const sp<const DisplayDevice>& display) {
306         return layer->findOutputLayerForDisplay(display.get());
307     }
308 
setLayerSidebandStream(const sp<Layer> & layer,const sp<NativeHandle> & sidebandStream)309     static void setLayerSidebandStream(const sp<Layer>& layer,
310                                        const sp<NativeHandle>& sidebandStream) {
311         layer->mDrawingState.sidebandStream = sidebandStream;
312         layer->mSidebandStream = sidebandStream;
313         layer->editCompositionState()->sidebandStream = sidebandStream;
314     }
315 
setLayerCompositionType(const sp<Layer> & layer,aidl::android::hardware::graphics::composer3::Composition type)316     void setLayerCompositionType(const sp<Layer>& layer,
317                                  aidl::android::hardware::graphics::composer3::Composition type) {
318         auto outputLayer = findOutputLayerForDisplay(layer, mFlinger->getDefaultDisplayDevice());
319         LOG_ALWAYS_FATAL_IF(!outputLayer);
320         auto& state = outputLayer->editState();
321         LOG_ALWAYS_FATAL_IF(!outputLayer->getState().hwc);
322         (*state.hwc).hwcCompositionType = type;
323     }
324 
setLayerPotentialCursor(const sp<Layer> & layer,bool potentialCursor)325     static void setLayerPotentialCursor(const sp<Layer>& layer, bool potentialCursor) {
326         layer->mPotentialCursor = potentialCursor;
327     }
328 
setLayerDrawingParent(const sp<Layer> & layer,const sp<Layer> & drawingParent)329     static void setLayerDrawingParent(const sp<Layer>& layer, const sp<Layer>& drawingParent) {
330         layer->mDrawingParent = drawingParent;
331     }
332 
setPowerHintSessionMode(bool early,bool late)333     void setPowerHintSessionMode(bool early, bool late) {
334         mFlinger->mPowerHintSessionMode = {.late = late, .early = early};
335     }
336 
337     /* ------------------------------------------------------------------------
338      * Forwarding for functions being tested
339      */
340 
commit(nsecs_t frameTime,int64_t vsyncId,nsecs_t expectedVSyncTime)341     nsecs_t commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVSyncTime) {
342         mFlinger->commit(frameTime, vsyncId, expectedVSyncTime);
343         return frameTime;
344     }
345 
commit(nsecs_t frameTime,int64_t vsyncId)346     nsecs_t commit(nsecs_t frameTime, int64_t vsyncId) {
347         std::chrono::nanoseconds period = 10ms;
348         return commit(frameTime, vsyncId, frameTime + period.count());
349     }
350 
commit()351     nsecs_t commit() {
352         const nsecs_t now = systemTime();
353         const nsecs_t expectedVsyncTime = now + 10'000'000;
354         return commit(now, kVsyncId, expectedVsyncTime);
355     }
356 
commitAndComposite(const nsecs_t frameTime,const int64_t vsyncId,const nsecs_t expectedVsyncTime)357     void commitAndComposite(const nsecs_t frameTime, const int64_t vsyncId,
358                             const nsecs_t expectedVsyncTime) {
359         mFlinger->composite(commit(frameTime, vsyncId, expectedVsyncTime), kVsyncId);
360     }
361 
commitAndComposite()362     void commitAndComposite() { mFlinger->composite(commit(), kVsyncId); }
363 
createDisplay(const String8 & displayName,bool secure)364     auto createDisplay(const String8& displayName, bool secure) {
365         return mFlinger->createDisplay(displayName, secure);
366     }
367 
destroyDisplay(const sp<IBinder> & displayToken)368     auto destroyDisplay(const sp<IBinder>& displayToken) {
369         return mFlinger->destroyDisplay(displayToken);
370     }
371 
getDisplay(const sp<IBinder> & displayToken)372     auto getDisplay(const sp<IBinder>& displayToken) {
373         Mutex::Autolock lock(mFlinger->mStateLock);
374         return mFlinger->getDisplayDeviceLocked(displayToken);
375     }
376 
enableHalVirtualDisplays(bool enable)377     void enableHalVirtualDisplays(bool enable) { mFlinger->enableHalVirtualDisplays(enable); }
378 
setupNewDisplayDeviceInternal(const wp<IBinder> & displayToken,std::shared_ptr<compositionengine::Display> compositionDisplay,const DisplayDeviceState & state,const sp<compositionengine::DisplaySurface> & dispSurface,const sp<IGraphicBufferProducer> & producer)379     auto setupNewDisplayDeviceInternal(
380             const wp<IBinder>& displayToken,
381             std::shared_ptr<compositionengine::Display> compositionDisplay,
382             const DisplayDeviceState& state,
383             const sp<compositionengine::DisplaySurface>& dispSurface,
384             const sp<IGraphicBufferProducer>& producer) NO_THREAD_SAFETY_ANALYSIS {
385         return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
386                                                        dispSurface, producer);
387     }
388 
commitTransactionsLocked(uint32_t transactionFlags)389     auto commitTransactionsLocked(uint32_t transactionFlags) {
390         Mutex::Autolock lock(mFlinger->mStateLock);
391         return mFlinger->commitTransactionsLocked(transactionFlags);
392     }
393 
onComposerHalHotplug(hal::HWDisplayId hwcDisplayId,hal::Connection connection)394     void onComposerHalHotplug(hal::HWDisplayId hwcDisplayId, hal::Connection connection) {
395         mFlinger->onComposerHalHotplug(hwcDisplayId, connection);
396     }
397 
setDisplayStateLocked(const DisplayState & s)398     auto setDisplayStateLocked(const DisplayState& s) {
399         Mutex::Autolock lock(mFlinger->mStateLock);
400         return mFlinger->setDisplayStateLocked(s);
401     }
402 
403     // Allow reading display state without locking, as if called on the SF main thread.
onInitializeDisplays()404     auto onInitializeDisplays() NO_THREAD_SAFETY_ANALYSIS {
405         return mFlinger->onInitializeDisplays();
406     }
407 
notifyPowerBoost(int32_t boostId)408     auto notifyPowerBoost(int32_t boostId) { return mFlinger->notifyPowerBoost(boostId); }
409 
setDisplayBrightness(const sp<IBinder> & display,const gui::DisplayBrightness & brightness)410     auto setDisplayBrightness(const sp<IBinder>& display,
411                               const gui::DisplayBrightness& brightness) {
412         return mFlinger->setDisplayBrightness(display, brightness);
413     }
414 
415     // Allow reading display state without locking, as if called on the SF main thread.
setPowerModeInternal(const sp<DisplayDevice> & display,hal::PowerMode mode)416     auto setPowerModeInternal(const sp<DisplayDevice>& display,
417                               hal::PowerMode mode) NO_THREAD_SAFETY_ANALYSIS {
418         return mFlinger->setPowerModeInternal(display, mode);
419     }
420 
renderScreenImpl(const RenderArea & renderArea,SurfaceFlinger::TraverseLayersFunction traverseLayers,const std::shared_ptr<renderengine::ExternalTexture> & buffer,bool forSystem,bool regionSampling)421     auto renderScreenImpl(const RenderArea& renderArea,
422                                 SurfaceFlinger::TraverseLayersFunction traverseLayers,
423                                 const std::shared_ptr<renderengine::ExternalTexture>& buffer,
424                                 bool forSystem, bool regionSampling) {
425         ScreenCaptureResults captureResults;
426         return mFlinger->renderScreenImpl(renderArea, traverseLayers, buffer, forSystem,
427                                                 regionSampling, false /* grayscale */,
428                                                 captureResults);
429     }
430 
traverseLayersInLayerStack(ui::LayerStack layerStack,int32_t uid,const LayerVector::Visitor & visitor)431     auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid,
432                                     const LayerVector::Visitor& visitor) {
433         return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid, visitor);
434     }
435 
getDisplayNativePrimaries(const sp<IBinder> & displayToken,ui::DisplayPrimaries & primaries)436     auto getDisplayNativePrimaries(const sp<IBinder>& displayToken,
437                                    ui::DisplayPrimaries &primaries) {
438         return mFlinger->SurfaceFlinger::getDisplayNativePrimaries(displayToken, primaries);
439     }
440 
getTransactionQueue()441     auto& getTransactionQueue() { return mFlinger->mTransactionQueue; }
getPendingTransactionQueue()442     auto& getPendingTransactionQueue() { return mFlinger->mPendingTransactionQueues; }
getTransactionCommittedSignals()443     auto& getTransactionCommittedSignals() { return mFlinger->mTransactionCommittedSignals; }
444 
setTransactionState(const FrameTimelineInfo & frameTimelineInfo,const Vector<ComposerState> & states,const Vector<DisplayState> & displays,uint32_t flags,const sp<IBinder> & applyToken,const InputWindowCommands & inputWindowCommands,int64_t desiredPresentTime,bool isAutoTimestamp,const client_cache_t & uncacheBuffer,bool hasListenerCallbacks,std::vector<ListenerCallbacks> & listenerCallbacks,uint64_t transactionId)445     auto setTransactionState(
446             const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,
447             const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
448             const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
449             bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
450             std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
451         return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken,
452                                              inputWindowCommands, desiredPresentTime,
453                                              isAutoTimestamp, uncacheBuffer, hasListenerCallbacks,
454                                              listenerCallbacks, transactionId);
455     }
456 
flushTransactionQueues()457     auto flushTransactionQueues() { return mFlinger->flushTransactionQueues(0); };
458 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)459     auto onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
460         return mFlinger->onTransact(code, data, reply, flags);
461     }
462 
getGPUContextPriority()463     auto getGPUContextPriority() { return mFlinger->getGPUContextPriority(); }
464 
calculateMaxAcquiredBufferCount(Fps refreshRate,std::chrono::nanoseconds presentLatency)465     auto calculateMaxAcquiredBufferCount(Fps refreshRate,
466                                          std::chrono::nanoseconds presentLatency) const {
467         return SurfaceFlinger::calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
468     }
469 
setDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,ui::DisplayModeId defaultMode,bool allowGroupSwitching,float primaryRefreshRateMin,float primaryRefreshRateMax,float appRequestRefreshRateMin,float appRequestRefreshRateMax)470     auto setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken, ui::DisplayModeId defaultMode,
471                                     bool allowGroupSwitching, float primaryRefreshRateMin,
472                                     float primaryRefreshRateMax, float appRequestRefreshRateMin,
473                                     float appRequestRefreshRateMax) {
474         return mFlinger->setDesiredDisplayModeSpecs(displayToken, defaultMode, allowGroupSwitching,
475                                                     primaryRefreshRateMin, primaryRefreshRateMax,
476                                                     appRequestRefreshRateMin,
477                                                     appRequestRefreshRateMax);
478     }
479 
onActiveDisplayChanged(const sp<DisplayDevice> & activeDisplay)480     void onActiveDisplayChanged(const sp<DisplayDevice>& activeDisplay) {
481         Mutex::Autolock lock(mFlinger->mStateLock);
482         mFlinger->onActiveDisplayChangedLocked(activeDisplay);
483     }
484 
createLayer(LayerCreationArgs & args,sp<IBinder> * outHandle,const sp<IBinder> & parentHandle,int32_t * outLayerId,const sp<Layer> & parentLayer,uint32_t * outTransformHint)485     auto createLayer(LayerCreationArgs& args, sp<IBinder>* outHandle,
486                      const sp<IBinder>& parentHandle, int32_t* outLayerId,
487                      const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
488         return mFlinger->createLayer(args, outHandle, parentHandle, outLayerId, parentLayer,
489                                      outTransformHint);
490     }
491 
mirrorLayer(const LayerCreationArgs & args,const sp<IBinder> & mirrorFromHandle,sp<IBinder> * outHandle,int32_t * outLayerId)492     auto mirrorLayer(const LayerCreationArgs& args, const sp<IBinder>& mirrorFromHandle,
493                      sp<IBinder>* outHandle, int32_t* outLayerId) {
494         return mFlinger->mirrorLayer(args, mirrorFromHandle, outHandle, outLayerId);
495     }
496 
497     /* ------------------------------------------------------------------------
498      * Read-only access to private data to assert post-conditions.
499      */
500 
getAnimFrameTracker()501     const auto& getAnimFrameTracker() const { return mFlinger->mAnimFrameTracker; }
getHasPoweredOff()502     const auto& getHasPoweredOff() const { return mFlinger->mHasPoweredOff; }
getVisibleRegionsDirty()503     const auto& getVisibleRegionsDirty() const { return mFlinger->mVisibleRegionsDirty; }
getHwComposer()504     auto& getHwComposer() const {
505         return static_cast<impl::HWComposer&>(mFlinger->getHwComposer());
506     }
getCompositionEngine()507     auto& getCompositionEngine() const { return mFlinger->getCompositionEngine(); }
508 
getCompositorTiming()509     const auto& getCompositorTiming() const { return mFlinger->getBE().mCompositorTiming; }
510 
getFrameTracer()511     mock::FrameTracer* getFrameTracer() const {
512         return static_cast<mock::FrameTracer*>(mFlinger->mFrameTracer.get());
513     }
514 
getAnimationTransactionTimeout()515     nsecs_t getAnimationTransactionTimeout() const {
516         return mFlinger->mAnimationTransactionTimeout;
517     }
518 
519     /* ------------------------------------------------------------------------
520      * Read-write access to private data to set up preconditions and assert
521      * post-conditions.
522      */
523 
displays()524     const auto& displays() const { return mFlinger->mDisplays; }
currentState()525     const auto& currentState() const { return mFlinger->mCurrentState; }
drawingState()526     const auto& drawingState() const { return mFlinger->mDrawingState; }
transactionFlags()527     const auto& transactionFlags() const { return mFlinger->mTransactionFlags; }
hwcPhysicalDisplayIdMap()528     const auto& hwcPhysicalDisplayIdMap() const { return getHwComposer().mPhysicalDisplayIdMap; }
529 
mutableHasWideColorDisplay()530     auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
531 
mutableCurrentState()532     auto& mutableCurrentState() { return mFlinger->mCurrentState; }
mutableDisplayColorSetting()533     auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
mutableDisplays()534     auto& mutableDisplays() { return mFlinger->mDisplays; }
mutableDrawingState()535     auto& mutableDrawingState() { return mFlinger->mDrawingState; }
mutableGeometryDirty()536     auto& mutableGeometryDirty() { return mFlinger->mGeometryDirty; }
mutableInterceptor()537     auto& mutableInterceptor() { return mFlinger->mInterceptor; }
mutableMainThreadId()538     auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
mutablePendingHotplugEvents()539     auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
mutablePhysicalDisplayTokens()540     auto& mutablePhysicalDisplayTokens() { return mFlinger->mPhysicalDisplayTokens; }
mutableTexturePool()541     auto& mutableTexturePool() { return mFlinger->mTexturePool; }
mutableTransactionFlags()542     auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
mutableDebugDisableHWC()543     auto& mutableDebugDisableHWC() { return mFlinger->mDebugDisableHWC; }
mutableMaxRenderTargetSize()544     auto& mutableMaxRenderTargetSize() { return mFlinger->mMaxRenderTargetSize; }
545 
mutableHwcDisplayData()546     auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; }
mutableHwcPhysicalDisplayIdMap()547     auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
mutablePrimaryHwcDisplayId()548     auto& mutablePrimaryHwcDisplayId() { return getHwComposer().mPrimaryHwcDisplayId; }
mutableActiveDisplayToken()549     auto& mutableActiveDisplayToken() { return mFlinger->mActiveDisplayToken; }
550 
fromHandle(const sp<IBinder> & handle)551     auto fromHandle(const sp<IBinder>& handle) {
552         return mFlinger->fromHandle(handle);
553     }
554 
~TestableSurfaceFlinger()555     ~TestableSurfaceFlinger() {
556         // All these pointer and container clears help ensure that GMock does
557         // not report a leaked object, since the SurfaceFlinger instance may
558         // still be referenced by something despite our best efforts to destroy
559         // it after each test is done.
560         mutableDisplays().clear();
561         mutableCurrentState().displays.clear();
562         mutableDrawingState().displays.clear();
563         mutableInterceptor().clear();
564         mFlinger->mScheduler.reset();
565         mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
566         mFlinger->mCompositionEngine->setRenderEngine(
567                 std::unique_ptr<renderengine::RenderEngine>());
568     }
569 
570     /* ------------------------------------------------------------------------
571      * Wrapper classes for Read-write access to private data to set up
572      * preconditions and assert post-conditions.
573      */
574     struct HWC2Display : public HWC2::impl::Display {
HWC2DisplayHWC2Display575         HWC2Display(
576                 Hwc2::Composer& composer,
577                 const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&
578                         capabilities,
579                 hal::HWDisplayId id, hal::DisplayType type)
580               : HWC2::impl::Display(composer, capabilities, id, type) {}
~HWC2DisplayHWC2Display581         ~HWC2Display() {
582             // Prevents a call to disable vsyncs.
583             mType = hal::DisplayType::INVALID;
584         }
585 
mutableIsConnectedHWC2Display586         auto& mutableIsConnected() { return this->mIsConnected; }
mutableLayersHWC2Display587         auto& mutableLayers() { return this->mLayers; }
588     };
589 
590     class FakeHwcDisplayInjector {
591     public:
592         static constexpr hal::HWDisplayId DEFAULT_HWC_DISPLAY_ID = 1000;
593         static constexpr ui::Size DEFAULT_RESOLUTION{1920, 1280};
594         static constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
595         static constexpr int32_t DEFAULT_CONFIG_GROUP = 7;
596         static constexpr int32_t DEFAULT_DPI = 320;
597         static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0;
598         static constexpr hal::PowerMode DEFAULT_POWER_MODE = hal::PowerMode::ON;
599 
FakeHwcDisplayInjector(HalDisplayId displayId,hal::DisplayType hwcDisplayType,bool isPrimary)600         FakeHwcDisplayInjector(HalDisplayId displayId, hal::DisplayType hwcDisplayType,
601                                bool isPrimary)
602               : mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {}
603 
setHwcDisplayId(hal::HWDisplayId displayId)604         auto& setHwcDisplayId(hal::HWDisplayId displayId) {
605             mHwcDisplayId = displayId;
606             return *this;
607         }
608 
setResolution(ui::Size resolution)609         auto& setResolution(ui::Size resolution) {
610             mResolution = resolution;
611             return *this;
612         }
613 
setVsyncPeriod(nsecs_t vsyncPeriod)614         auto& setVsyncPeriod(nsecs_t vsyncPeriod) {
615             mVsyncPeriod = vsyncPeriod;
616             return *this;
617         }
618 
setDpiX(int32_t dpi)619         auto& setDpiX(int32_t dpi) {
620             mDpiX = dpi;
621             return *this;
622         }
623 
setDpiY(int32_t dpi)624         auto& setDpiY(int32_t dpi) {
625             mDpiY = dpi;
626             return *this;
627         }
628 
setActiveConfig(hal::HWConfigId config)629         auto& setActiveConfig(hal::HWConfigId config) {
630             mActiveConfig = config;
631             return *this;
632         }
633 
setCapabilities(const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability> * capabilities)634         auto& setCapabilities(
635                 const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>*
636                         capabilities) {
637             mCapabilities = capabilities;
638             return *this;
639         }
640 
setPowerMode(hal::PowerMode mode)641         auto& setPowerMode(hal::PowerMode mode) {
642             mPowerMode = mode;
643             return *this;
644         }
645 
inject(TestableSurfaceFlinger * flinger,Hwc2::mock::Composer * composer)646         void inject(TestableSurfaceFlinger* flinger, Hwc2::mock::Composer* composer) {
647             using ::testing::_;
648             using ::testing::DoAll;
649             using ::testing::Return;
650             using ::testing::SetArgPointee;
651 
652             static const std::unordered_set<
653                     aidl::android::hardware::graphics::composer3::Capability>
654                     defaultCapabilities;
655             if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities;
656 
657             // Caution - Make sure that any values passed by reference here do
658             // not refer to an instance owned by FakeHwcDisplayInjector. This
659             // class has temporary lifetime, while the constructed HWC2::Display
660             // is much longer lived.
661             auto display = std::make_unique<HWC2Display>(*composer, *mCapabilities, mHwcDisplayId,
662                                                          mHwcDisplayType);
663 
664             display->mutableIsConnected() = true;
665             display->setPowerMode(mPowerMode);
666             flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display);
667 
668             EXPECT_CALL(*composer, getDisplayConfigs(mHwcDisplayId, _))
669                     .WillRepeatedly(
670                             DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{mActiveConfig}),
671                                   Return(hal::Error::NONE)));
672 
673             EXPECT_CALL(*composer,
674                         getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::WIDTH, _))
675                     .WillRepeatedly(DoAll(SetArgPointee<3>(mResolution.getWidth()),
676                                           Return(hal::Error::NONE)));
677 
678             EXPECT_CALL(*composer,
679                         getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::HEIGHT,
680                                             _))
681                     .WillRepeatedly(DoAll(SetArgPointee<3>(mResolution.getHeight()),
682                                           Return(hal::Error::NONE)));
683 
684             EXPECT_CALL(*composer,
685                         getDisplayAttribute(mHwcDisplayId, mActiveConfig,
686                                             hal::Attribute::VSYNC_PERIOD, _))
687                     .WillRepeatedly(DoAll(SetArgPointee<3>(static_cast<int32_t>(mVsyncPeriod)),
688                                           Return(hal::Error::NONE)));
689 
690             EXPECT_CALL(*composer,
691                         getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::DPI_X, _))
692                     .WillRepeatedly(DoAll(SetArgPointee<3>(mDpiX), Return(hal::Error::NONE)));
693 
694             EXPECT_CALL(*composer,
695                         getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::DPI_Y, _))
696                     .WillRepeatedly(DoAll(SetArgPointee<3>(mDpiY), Return(hal::Error::NONE)));
697 
698             EXPECT_CALL(*composer,
699                         getDisplayAttribute(mHwcDisplayId, mActiveConfig,
700                                             hal::Attribute::CONFIG_GROUP, _))
701                     .WillRepeatedly(
702                             DoAll(SetArgPointee<3>(mConfigGroup), Return(hal::Error::NONE)));
703 
704             if (mHwcDisplayType == hal::DisplayType::PHYSICAL) {
705                 const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId);
706                 LOG_ALWAYS_FATAL_IF(!physicalId);
707                 flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, *physicalId);
708                 if (mIsPrimary) {
709                     flinger->mutablePrimaryHwcDisplayId() = mHwcDisplayId;
710                 } else {
711                     // If there is an external HWC display, there should always be a primary ID
712                     // as well. Set it to some arbitrary value.
713                     auto& primaryId = flinger->mutablePrimaryHwcDisplayId();
714                     if (!primaryId) primaryId = mHwcDisplayId - 1;
715                 }
716             }
717         }
718 
719     private:
720         const HalDisplayId mDisplayId;
721         const hal::DisplayType mHwcDisplayType;
722         const bool mIsPrimary;
723 
724         hal::HWDisplayId mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
725         ui::Size mResolution = DEFAULT_RESOLUTION;
726         nsecs_t mVsyncPeriod = DEFAULT_VSYNC_PERIOD;
727         int32_t mDpiX = DEFAULT_DPI;
728         int32_t mDpiY = DEFAULT_DPI;
729         int32_t mConfigGroup = DEFAULT_CONFIG_GROUP;
730         hal::HWConfigId mActiveConfig = DEFAULT_ACTIVE_CONFIG;
731         hal::PowerMode mPowerMode = DEFAULT_POWER_MODE;
732         const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>*
733                 mCapabilities = nullptr;
734     };
735 
736     class FakeDisplayDeviceInjector {
737     public:
FakeDisplayDeviceInjector(TestableSurfaceFlinger & flinger,std::shared_ptr<compositionengine::Display> display,std::optional<ui::DisplayConnectionType> connectionType,std::optional<hal::HWDisplayId> hwcDisplayId,bool isPrimary)738         FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger,
739                                   std::shared_ptr<compositionengine::Display> display,
740                                   std::optional<ui::DisplayConnectionType> connectionType,
741                                   std::optional<hal::HWDisplayId> hwcDisplayId, bool isPrimary)
742               : mFlinger(flinger),
743                 mCreationArgs(flinger.mFlinger.get(), flinger.mFlinger->getHwComposer(),
744                               mDisplayToken, display),
745                 mHwcDisplayId(hwcDisplayId) {
746             mCreationArgs.connectionType = connectionType;
747             mCreationArgs.isPrimary = isPrimary;
748             mCreationArgs.initialPowerMode = hal::PowerMode::ON;
749         }
750 
token()751         sp<IBinder> token() const { return mDisplayToken; }
752 
mutableDrawingDisplayState()753         DisplayDeviceState& mutableDrawingDisplayState() {
754             return mFlinger.mutableDrawingState().displays.editValueFor(mDisplayToken);
755         }
756 
mutableCurrentDisplayState()757         DisplayDeviceState& mutableCurrentDisplayState() {
758             return mFlinger.mutableCurrentState().displays.editValueFor(mDisplayToken);
759         }
760 
getDrawingDisplayState()761         const auto& getDrawingDisplayState() {
762             return mFlinger.mutableDrawingState().displays.valueFor(mDisplayToken);
763         }
764 
getCurrentDisplayState()765         const auto& getCurrentDisplayState() {
766             return mFlinger.mutableCurrentState().displays.valueFor(mDisplayToken);
767         }
768 
mutableDisplayDevice()769         const sp<DisplayDevice>& mutableDisplayDevice() {
770             return mFlinger.mutableDisplays().get(mDisplayToken)->get();
771         }
772 
773         // If `configs` is nullptr, the injector creates RefreshRateConfigs from the `modes`.
774         // Otherwise, it uses `configs`, which the caller must create using the same `modes`.
775         //
776         // TODO(b/182939859): Once `modes` can be retrieved from RefreshRateConfigs, remove
777         // the `configs` parameter in favor of an alternative setRefreshRateConfigs API.
778         auto& setDisplayModes(DisplayModes modes, DisplayModeId activeModeId,
779                               std::shared_ptr<scheduler::RefreshRateConfigs> configs = nullptr) {
780             mCreationArgs.supportedModes = std::move(modes);
781             mCreationArgs.activeModeId = activeModeId;
782             mCreationArgs.refreshRateConfigs = std::move(configs);
783             return *this;
784         }
785 
setNativeWindow(const sp<ANativeWindow> & nativeWindow)786         auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
787             mCreationArgs.nativeWindow = nativeWindow;
788             return *this;
789         }
790 
setDisplaySurface(const sp<compositionengine::DisplaySurface> & displaySurface)791         auto& setDisplaySurface(const sp<compositionengine::DisplaySurface>& displaySurface) {
792             mCreationArgs.displaySurface = displaySurface;
793             return *this;
794         }
795 
setSecure(bool secure)796         auto& setSecure(bool secure) {
797             mCreationArgs.isSecure = secure;
798             return *this;
799         }
800 
setPowerMode(std::optional<hal::PowerMode> mode)801         auto& setPowerMode(std::optional<hal::PowerMode> mode) {
802             mCreationArgs.initialPowerMode = mode;
803             return *this;
804         }
805 
setHwcColorModes(const std::unordered_map<ui::ColorMode,std::vector<ui::RenderIntent>> hwcColorModes)806         auto& setHwcColorModes(
807                 const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>
808                         hwcColorModes) {
809             mCreationArgs.hwcColorModes = hwcColorModes;
810             return *this;
811         }
812 
setHasWideColorGamut(bool hasWideColorGamut)813         auto& setHasWideColorGamut(bool hasWideColorGamut) {
814             mCreationArgs.hasWideColorGamut = hasWideColorGamut;
815             return *this;
816         }
817 
setPhysicalOrientation(ui::Rotation orientation)818         auto& setPhysicalOrientation(ui::Rotation orientation) {
819             mCreationArgs.physicalOrientation = orientation;
820             return *this;
821         }
822 
inject()823         sp<DisplayDevice> inject() NO_THREAD_SAFETY_ANALYSIS {
824             const auto displayId = mCreationArgs.compositionDisplay->getDisplayId();
825 
826             auto& modes = mCreationArgs.supportedModes;
827             auto& activeModeId = mCreationArgs.activeModeId;
828 
829             if (displayId && !mCreationArgs.refreshRateConfigs) {
830                 if (const auto physicalId = PhysicalDisplayId::tryCast(*displayId)) {
831                     if (modes.empty()) {
832                         constexpr DisplayModeId kModeId{0};
833                         DisplayModePtr mode =
834                                 DisplayMode::Builder(FakeHwcDisplayInjector::DEFAULT_ACTIVE_CONFIG)
835                                         .setId(kModeId)
836                                         .setPhysicalDisplayId(*physicalId)
837                                         .setResolution(FakeHwcDisplayInjector::DEFAULT_RESOLUTION)
838                                         .setVsyncPeriod(
839                                                 FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)
840                                         .setDpiX(FakeHwcDisplayInjector::DEFAULT_DPI)
841                                         .setDpiY(FakeHwcDisplayInjector::DEFAULT_DPI)
842                                         .setGroup(FakeHwcDisplayInjector::DEFAULT_CONFIG_GROUP)
843                                         .build();
844 
845                         modes = ftl::init::map(kModeId, std::move(mode));
846                         activeModeId = kModeId;
847                     }
848 
849                     mCreationArgs.refreshRateConfigs =
850                             std::make_shared<scheduler::RefreshRateConfigs>(modes, activeModeId);
851                 }
852             }
853 
854             DisplayDeviceState state;
855             if (const auto type = mCreationArgs.connectionType) {
856                 LOG_ALWAYS_FATAL_IF(!displayId);
857                 const auto physicalId = PhysicalDisplayId::tryCast(*displayId);
858                 LOG_ALWAYS_FATAL_IF(!physicalId);
859                 LOG_ALWAYS_FATAL_IF(!mHwcDisplayId);
860 
861                 const auto activeMode = modes.get(activeModeId);
862                 LOG_ALWAYS_FATAL_IF(!activeMode);
863 
864                 state.physical = {.id = *physicalId,
865                                   .type = *type,
866                                   .hwcDisplayId = *mHwcDisplayId,
867                                   .deviceProductInfo = {},
868                                   .supportedModes = modes,
869                                   .activeMode = activeMode->get()};
870 
871                 if (mCreationArgs.isPrimary) {
872                     mFlinger.mutableActiveDisplayToken() = mDisplayToken;
873                 }
874             }
875 
876             state.isSecure = mCreationArgs.isSecure;
877 
878             sp<DisplayDevice> display = sp<DisplayDevice>::make(mCreationArgs);
879             if (!display->isVirtual()) {
880                 display->setActiveMode(activeModeId);
881             }
882             mFlinger.mutableDisplays().emplace_or_replace(mDisplayToken, display);
883 
884             mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
885             mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
886 
887             if (const auto& physical = state.physical) {
888                 mFlinger.mutablePhysicalDisplayTokens().emplace_or_replace(physical->id,
889                                                                            mDisplayToken);
890             }
891 
892             return display;
893         }
894 
895     private:
896         TestableSurfaceFlinger& mFlinger;
897         sp<BBinder> mDisplayToken = new BBinder();
898         DisplayDeviceCreationArgs mCreationArgs;
899         const std::optional<hal::HWDisplayId> mHwcDisplayId;
900     };
901 
902 private:
903     constexpr static int64_t kVsyncId = 123;
904 
905     surfaceflinger::test::Factory mFactory;
906     sp<SurfaceFlinger> mFlinger;
907     scheduler::mock::SchedulerCallback mSchedulerCallback;
908     scheduler::mock::NoOpSchedulerCallback mNoOpSchedulerCallback;
909     scheduler::TestableScheduler* mScheduler = nullptr;
910 };
911 
912 } // namespace android
913