Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90c115d4 authored by Lloyd Pique's avatar Lloyd Pique
Browse files

SF: Flush out SurfaceFlingerFactory

A factory is now passed to the SurfaceFlinger constructor, either one
created specifically to handle normal service initialization, or one
created for the unit tests. SurfaceFlinger uses the factory interface to
construct most of its instances.

This allows (almost) all the top level instances SurfaceFlinger creates
to be replaced as needed by interface-equivalents, such as GMocks in the
case of the unit test.

An older set of factory functions for two specific types is removed in
favor of the new factory interface.

Test: atest libsurfaceflinger_unittest
Test: Marlin boots and appears usable
Bug: None

Change-Id: I070c94effc54ddfe5366978613283525d7a7bf4a
parent 684400c9
Loading
Loading
Loading
Loading
+34 −35
Original line number Diff line number Diff line
@@ -75,7 +75,9 @@
#include "LayerVector.h"
#include "MonitoredProducer.h"
#include "NativeWindowSurface.h"
#include "StartPropertySetThread.h"
#include "SurfaceFlinger.h"
#include "SurfaceInterceptor.h"

#include "DisplayHardware/ComposerHal.h"
#include "DisplayHardware/DisplayIdentification.h"
@@ -88,6 +90,7 @@
#include "Scheduler/EventControlThread.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/InjectVSyncSource.h"
#include "Scheduler/MessageQueue.h"
#include "Scheduler/Scheduler.h"

#include <cutils/compiler.h>
@@ -233,8 +236,10 @@ SurfaceFlingerBE::SurfaceFlingerBE()
        mComposerSequenceId(0) {
}

SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag)
SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory,
                               SurfaceFlinger::SkipInitializationTag)
      : BnSurfaceComposer(),
        mFactory(factory),
        mTransactionPending(false),
        mAnimTransactionPending(false),
        mLayersRemoved(false),
@@ -258,11 +263,10 @@ SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag)
        mHasPoweredOff(false),
        mNumLayers(0),
        mVrFlingerRequestsDisplay(false),
        mMainThreadId(std::this_thread::get_id()),
        mCreateBufferQueue(&BufferQueue::createBufferQueue),
        mCreateNativeWindowSurface(&surfaceflinger::impl::createNativeWindowSurface) {}
        mMainThreadId(std::this_thread::get_id()) {}

SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory)
      : SurfaceFlinger(factory, SkipInitialization) {
    ALOGI("SurfaceFlinger is starting");

    vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
@@ -329,13 +333,9 @@ SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
    }
    ALOGV("Primary Display Orientation is set to %2d.", SurfaceFlinger::primaryDisplayOrientation);

    // Note: We create a local temporary with the real DispSync implementation
    // type temporarily so we can initialize it with the configured values,
    // before storing it for more generic use using the interface type.
    auto primaryDispSync = std::make_unique<impl::DispSync>("PrimaryDispSync");
    primaryDispSync->init(SurfaceFlinger::hasSyncFramework,
    mPrimaryDispSync =
            getFactory().createDispSync("PrimaryDispSync", SurfaceFlinger::hasSyncFramework,
                                        SurfaceFlinger::dispSyncPresentTimeOffset);
    mPrimaryDispSync = std::move(primaryDispSync);

    // debugging stuff...
    char value[PROPERTY_VALUE_MAX];
@@ -585,7 +585,7 @@ void SurfaceFlinger::init() {

    // start the EventThread
    if (mUseScheduler) {
        mScheduler = std::make_unique<Scheduler>(
        mScheduler = getFactory().createScheduler(
                [this](bool enabled) { setVsyncEnabled(HWC_DISPLAY_PRIMARY, enabled); });
        mAppConnectionHandle =
                mScheduler->createConnection("appConnection", SurfaceFlinger::vsyncPhaseOffsetNs,
@@ -640,8 +640,7 @@ void SurfaceFlinger::init() {

    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
            "Starting with vr flinger active is not currently supported.");
    getBE().mHwc.reset(
            new HWComposer(std::make_unique<Hwc2::impl::Composer>(getBE().mHwcServiceName)));
    getBE().mHwc = getFactory().createHWComposer(getBE().mHwcServiceName);
    getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
    // Process any initial hotplug and resulting display changes.
    processDisplayHotplugEventsLocked();
@@ -678,7 +677,7 @@ void SurfaceFlinger::init() {
        }
    }

    mEventControlThread = std::make_unique<impl::EventControlThread>(
    mEventControlThread = getFactory().createEventControlThread(
            [this](bool enabled) { setVsyncEnabled(HWC_DISPLAY_PRIMARY, enabled); });

    // initialize our drawing state
@@ -690,12 +689,10 @@ void SurfaceFlinger::init() {
    getBE().mRenderEngine->primeCache();

    // Inform native graphics APIs whether the present timestamp is supported:
    if (getHwComposer().hasCapability(
            HWC2::Capability::PresentFenceIsNotReliable)) {
        mStartPropertySetThread = new StartPropertySetThread(false);
    } else {
        mStartPropertySetThread = new StartPropertySetThread(true);
    }

    const bool presentFenceReliable =
            !getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable);
    mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);

    if (mStartPropertySetThread->Start() != NO_ERROR) {
        ALOGE("Run StartPropertySetThread failed!");
@@ -1420,8 +1417,8 @@ void SurfaceFlinger::updateVrFlinger() {

    resetDisplayState();
    getBE().mHwc.reset(); // Delete the current instance before creating the new one
    getBE().mHwc.reset(new HWComposer(std::make_unique<Hwc2::impl::Composer>(
            vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName)));
    getBE().mHwc = getFactory().createHWComposer(
            vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName);
    getBE().mHwc->registerCallback(this, ++getBE().mComposerSequenceId);

    LOG_ALWAYS_FATAL_IF(!getBE().mHwc->getComposer()->isRemote(),
@@ -2345,7 +2342,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
                getHwComposer().getSupportedPerFrameMetadata(displayId);
    }

    auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
    auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
    auto nativeWindow = nativeWindowSurface->getNativeWindow();
    creationArgs.nativeWindow = nativeWindow;

@@ -2378,7 +2375,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
    // virtual displays are always considered enabled
    creationArgs.initialPowerMode = state.isVirtual() ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;

    sp<DisplayDevice> display = new DisplayDevice(std::move(creationArgs));
    sp<DisplayDevice> display = getFactory().createDisplayDevice(std::move(creationArgs));

    if (maxFrameBufferAcquiredBuffers >= 3) {
        nativeWindowSurface->preallocateBuffers();
@@ -2493,7 +2490,7 @@ void SurfaceFlinger::processDisplayChangesLocked() {
                sp<IGraphicBufferProducer> producer;
                sp<IGraphicBufferProducer> bqProducer;
                sp<IGraphicBufferConsumer> bqConsumer;
                mCreateBufferQueue(&bqProducer, &bqConsumer, false);
                getFactory().createBufferQueue(&bqProducer, &bqConsumer, false);

                int32_t displayId = -1;
                if (state.isVirtual()) {
@@ -3763,7 +3760,7 @@ status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, const
    }

    sp<BufferQueueLayer> layer =
            new BufferQueueLayer(LayerCreationArgs(this, client, name, w, h, flags));
            getFactory().createBufferQueueLayer(LayerCreationArgs(this, client, name, w, h, flags));
    status_t err = layer->setDefaultBufferProperties(w, h, format);
    if (err == NO_ERROR) {
        *handle = layer->getHandle();
@@ -3779,7 +3776,7 @@ status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, const
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                sp<IBinder>* handle, sp<Layer>* outLayer) {
    sp<BufferStateLayer> layer =
            new BufferStateLayer(LayerCreationArgs(this, client, name, w, h, flags));
            getFactory().createBufferStateLayer(LayerCreationArgs(this, client, name, w, h, flags));
    *handle = layer->getHandle();
    *outLayer = layer;

@@ -3790,7 +3787,7 @@ status_t SurfaceFlinger::createColorLayer(const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
        sp<IBinder>* handle, sp<Layer>* outLayer)
{
    *outLayer = new ColorLayer(LayerCreationArgs(this, client, name, w, h, flags));
    *outLayer = getFactory().createColorLayer(LayerCreationArgs(this, client, name, w, h, flags));
    *handle = (*outLayer)->getHandle();
    return NO_ERROR;
}
@@ -3799,7 +3796,8 @@ status_t SurfaceFlinger::createContainerLayer(const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
        sp<IBinder>* handle, sp<Layer>* outLayer)
{
    *outLayer = new ContainerLayer(LayerCreationArgs(this, client, name, w, h, flags));
    *outLayer =
            getFactory().createContainerLayer(LayerCreationArgs(this, client, name, w, h, flags));
    *handle = (*outLayer)->getHandle();
    return NO_ERROR;
}
@@ -5155,7 +5153,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
                drawLayers();
            } else {
                Rect bounds = getBounds();
                screenshotParentLayer = new ContainerLayer(
                screenshotParentLayer = mFlinger->getFactory().createContainerLayer(
                        LayerCreationArgs(mFlinger, nullptr, String8("Screenshot Parent"),
                                          bounds.getWidth(), bounds.getHeight(), 0));

@@ -5240,9 +5238,10 @@ status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
    // TODO(b/116112787) Make buffer usage a parameter.
    const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
            GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
    *outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),
                                   static_cast<android_pixel_format>(reqPixelFormat), 1, usage,
                                   "screenshot");
    *outBuffer =
            getFactory().createGraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),
                                             static_cast<android_pixel_format>(reqPixelFormat), 1,
                                             usage, "screenshot");

    // This mutex protects syncFd and captureResult for communication of the return values from the
    // main thread back to this Binder thread
+10 −18
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@
#include "LayerBE.h"
#include "LayerStats.h"
#include "LayerVector.h"
#include "StartPropertySetThread.h"
#include "SurfaceFlingerFactory.h"
#include "SurfaceInterceptor.h"
#include "SurfaceTracing.h"

@@ -303,8 +303,8 @@ public:

    struct SkipInitializationTag {};
    static constexpr SkipInitializationTag SkipInitialization;
    explicit SurfaceFlinger(SkipInitializationTag) ANDROID_API;
    SurfaceFlinger() ANDROID_API;
    SurfaceFlinger(surfaceflinger::Factory&, SkipInitializationTag) ANDROID_API;
    explicit SurfaceFlinger(surfaceflinger::Factory&) ANDROID_API;

    // must be called before clients can connect
    void init() ANDROID_API;
@@ -325,6 +325,8 @@ public:
    // force full composition on all displays
    void repaintEverything();

    surfaceflinger::Factory& getFactory() { return mFactory; }

    // returns the default Display
    sp<const DisplayDevice> getDefaultDisplayDevice() const {
        Mutex::Autolock _l(mStateLock);
@@ -599,7 +601,7 @@ private:
    void traverseLayersInDisplay(const sp<const DisplayDevice>& display,
                                 const LayerVector::Visitor& visitor);

    sp<StartPropertySetThread> mStartPropertySetThread = nullptr;
    sp<StartPropertySetThread> mStartPropertySetThread;

    /* ------------------------------------------------------------------------
     * Properties
@@ -785,6 +787,8 @@ private:
     * Attributes
     */

    surfaceflinger::Factory& mFactory;

    // access must be protected by mStateLock
    mutable Mutex mStateLock;
    State mCurrentState{LayerVector::StateSet::Current};
@@ -862,8 +866,7 @@ private:
    nsecs_t mPostFramebufferTime;
    bool mForceFullDamage;
    bool mPropagateBackpressure = true;
    std::unique_ptr<SurfaceInterceptor> mInterceptor =
            std::make_unique<impl::SurfaceInterceptor>(this);
    std::unique_ptr<SurfaceInterceptor> mInterceptor{mFactory.createSurfaceInterceptor(this)};
    SurfaceTracing mTracing;
    LayerStats mLayerStats;
    TimeStats& mTimeStats = TimeStats::getInstance();
@@ -874,7 +877,7 @@ private:
    bool mLayerTripleBufferingDisabled = false;

    // these are thread safe
    mutable std::unique_ptr<MessageQueue> mEventQueue{std::make_unique<impl::MessageQueue>()};
    mutable std::unique_ptr<MessageQueue> mEventQueue{mFactory.createMessageQueue()};
    FrameTracker mAnimFrameTracker;
    std::unique_ptr<DispSync> mPrimaryDispSync;

@@ -921,17 +924,6 @@ private:
    // Applied on Display P3 layers when the render intent is non-colorimetric.
    mat4 mEnhancedSaturationMatrix;

    using CreateBufferQueueFunction =
            std::function<void(sp<IGraphicBufferProducer>* /* outProducer */,
                               sp<IGraphicBufferConsumer>* /* outConsumer */,
                               bool /* consumerIsSurfaceFlinger */)>;
    CreateBufferQueueFunction mCreateBufferQueue;

    using CreateNativeWindowSurfaceFunction =
            std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>(
                    const sp<IGraphicBufferProducer>&)>;
    CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;

    SurfaceFlingerBE mBE;

    bool mUseScheduler = false;
+101 −2
Original line number Diff line number Diff line
@@ -14,13 +14,112 @@
 * limitations under the License.
 */

#include "SurfaceFlingerFactory.h"
#include <ui/GraphicBuffer.h>

#include "BufferQueueLayer.h"
#include "BufferStateLayer.h"
#include "ColorLayer.h"
#include "ContainerLayer.h"
#include "DisplayDevice.h"
#include "Layer.h"
#include "NativeWindowSurface.h"
#include "StartPropertySetThread.h"
#include "SurfaceFlinger.h"
#include "SurfaceFlingerFactory.h"
#include "SurfaceInterceptor.h"

#include "DisplayHardware/ComposerHal.h"
#include "Scheduler/DispSync.h"
#include "Scheduler/EventControlThread.h"
#include "Scheduler/MessageQueue.h"
#include "Scheduler/Scheduler.h"

namespace android::surfaceflinger {

sp<SurfaceFlinger> createSurfaceFlinger() {
    return new SurfaceFlinger();
    class Factory final : public surfaceflinger::Factory {
    public:
        Factory() = default;
        ~Factory() = default;

        std::unique_ptr<DispSync> createDispSync(const char* name, bool hasSyncFramework,
                                                 int64_t dispSyncPresentTimeOffset) override {
            // Note: We create a local temporary with the real DispSync implementation
            // type temporarily so we can initialize it with the configured values,
            // before storing it for more generic use using the interface type.
            auto primaryDispSync = std::make_unique<android::impl::DispSync>(name);
            primaryDispSync->init(hasSyncFramework, dispSyncPresentTimeOffset);
            return primaryDispSync;
        }

        std::unique_ptr<EventControlThread> createEventControlThread(
                std::function<void(bool)> setVSyncEnabled) override {
            return std::make_unique<android::impl::EventControlThread>(setVSyncEnabled);
        }

        std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override {
            return std::make_unique<HWComposer>(
                    std::make_unique<Hwc2::impl::Composer>(serviceName));
        }

        std::unique_ptr<MessageQueue> createMessageQueue() override {
            return std::make_unique<android::impl::MessageQueue>();
        }

        std::unique_ptr<Scheduler> createScheduler(std::function<void(bool)> callback) override {
            return std::make_unique<Scheduler>(callback);
        }

        std::unique_ptr<SurfaceInterceptor> createSurfaceInterceptor(
                SurfaceFlinger* flinger) override {
            return std::make_unique<android::impl::SurfaceInterceptor>(flinger);
        }

        sp<StartPropertySetThread> createStartPropertySetThread(
                bool timestampPropertyValue) override {
            return new StartPropertySetThread(timestampPropertyValue);
        }

        sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&& creationArgs) override {
            return new DisplayDevice(std::move(creationArgs));
        }

        sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format,
                                              uint32_t layerCount, uint64_t usage,
                                              std::string requestorName) override {
            return new GraphicBuffer(width, height, format, layerCount, usage, requestorName);
        }

        void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                               sp<IGraphicBufferConsumer>* outConsumer,
                               bool consumerIsSurfaceFlinger) override {
            BufferQueue::createBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger);
        }

        std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
                const sp<IGraphicBufferProducer>& producer) override {
            return surfaceflinger::impl::createNativeWindowSurface(producer);
        }

        sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) override {
            return new ContainerLayer(args);
        }

        sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) override {
            return new BufferQueueLayer(args);
        }

        sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) override {
            return new BufferStateLayer(args);
        }

        sp<ColorLayer> createColorLayer(const LayerCreationArgs& args) override {
            return new ColorLayer(args);
        }
    };
    static Factory factory;

    return new SurfaceFlinger(factory);
}

} // namespace android::surfaceflinger
+61 −0
Original line number Diff line number Diff line
@@ -16,15 +16,76 @@

#pragma once

#include <cinttypes>
#include <functional>
#include <memory>
#include <string>

#include <cutils/compiler.h>
#include <utils/StrongPointer.h>

namespace android {

typedef int32_t PixelFormat;

class BufferQueueLayer;
class BufferStateLayer;
class ColorLayer;
class ContainerLayer;
class DisplayDevice;
class DispSync;
class EventControlThread;
class GraphicBuffer;
class HWComposer;
class IGraphicBufferConsumer;
class IGraphicBufferProducer;
class MessageQueue;
class Scheduler;
class StartPropertySetThread;
class SurfaceFlinger;
class SurfaceInterceptor;

struct DisplayDeviceCreationArgs;
struct LayerCreationArgs;

namespace surfaceflinger {

class NativeWindowSurface;

// The interface that SurfaceFlinger uses to create all of the implementations
// of each interface.
class Factory {
public:
    virtual std::unique_ptr<DispSync> createDispSync(const char* name, bool hasSyncFramework,
                                                     int64_t dispSyncPresentTimeOffset) = 0;
    virtual std::unique_ptr<EventControlThread> createEventControlThread(
            std::function<void(bool)> setVSyncEnabled) = 0;
    virtual std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) = 0;
    virtual std::unique_ptr<MessageQueue> createMessageQueue() = 0;
    virtual std::unique_ptr<Scheduler> createScheduler(std::function<void(bool)> callback) = 0;
    virtual std::unique_ptr<SurfaceInterceptor> createSurfaceInterceptor(SurfaceFlinger*) = 0;

    virtual sp<StartPropertySetThread> createStartPropertySetThread(
            bool timestampPropertyValue) = 0;
    virtual sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&&) = 0;
    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height,
                                                  PixelFormat format, uint32_t layerCount,
                                                  uint64_t usage, std::string requestorName) = 0;
    virtual void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                                   sp<IGraphicBufferConsumer>* outConsumer,
                                   bool consumerIsSurfaceFlinger) = 0;
    virtual std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
            const sp<IGraphicBufferProducer>&) = 0;

    virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0;
    virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
    virtual sp<ColorLayer> createColorLayer(const LayerCreationArgs& args) = 0;
    virtual sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) = 0;

protected:
    ~Factory() = default;
};

ANDROID_API sp<SurfaceFlinger> createSurfaceFlinger();

} // namespace surfaceflinger
+122 −7
Original line number Diff line number Diff line
@@ -16,22 +16,135 @@

#pragma once

#include "BufferQueueLayer.h"
#include "BufferStateLayer.h"
#include "ColorLayer.h"
#include "ContainerLayer.h"
#include "DisplayDevice.h"
#include "Layer.h"
#include "NativeWindowSurface.h"
#include "StartPropertySetThread.h"
#include "SurfaceFlinger.h"
#include "SurfaceFlingerFactory.h"
#include "SurfaceInterceptor.h"

namespace android {

class EventThread;

namespace renderengine {

class RenderEngine;
}

} // namespace renderengine

namespace Hwc2 {

class Composer;

} // namespace Hwc2

namespace surfaceflinger::test {

class Factory final : public surfaceflinger::Factory {
public:
    ~Factory() = default;

    std::unique_ptr<DispSync> createDispSync(const char*, bool, int64_t) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    std::unique_ptr<EventControlThread> createEventControlThread(
            std::function<void(bool)>) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    std::unique_ptr<HWComposer> createHWComposer(const std::string&) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    std::unique_ptr<MessageQueue> createMessageQueue() override {
        // TODO: Use test-fixture controlled factory
        return std::make_unique<android::impl::MessageQueue>();
    }

    std::unique_ptr<Scheduler> createScheduler(std::function<void(bool)>) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    std::unique_ptr<SurfaceInterceptor> createSurfaceInterceptor(SurfaceFlinger* flinger) override {
        // TODO: Use test-fixture controlled factory
        return std::make_unique<android::impl::SurfaceInterceptor>(flinger);
    }

    sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override {
        // TODO: Use test-fixture controlled factory
        return new StartPropertySetThread(timestampPropertyValue);
    }

    sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&& creationArgs) override {
        // TODO: Use test-fixture controlled factory
        return new DisplayDevice(std::move(creationArgs));
    }

    sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format,
                                          uint32_t layerCount, uint64_t usage,
                                          std::string requestorName) override {
        // TODO: Use test-fixture controlled factory
        return new GraphicBuffer(width, height, format, layerCount, usage, requestorName);
    }

    void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                           sp<IGraphicBufferConsumer>* outConsumer,
                           bool consumerIsSurfaceFlinger) override {
        if (!mCreateBufferQueue) return;
        mCreateBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger);
    }

    std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
            const sp<IGraphicBufferProducer>& producer) override {
        if (!mCreateNativeWindowSurface) return nullptr;
        return mCreateNativeWindowSurface(producer);
    }

    sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs&) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs&) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    sp<ColorLayer> createColorLayer(const LayerCreationArgs&) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    sp<ContainerLayer> createContainerLayer(const LayerCreationArgs&) override {
        // TODO: Use test-fixture controlled factory
        return nullptr;
    }

    using CreateBufferQueueFunction =
            std::function<void(sp<IGraphicBufferProducer>* /* outProducer */,
                               sp<IGraphicBufferConsumer>* /* outConsumer */,
                               bool /* consumerIsSurfaceFlinger */)>;
    CreateBufferQueueFunction mCreateBufferQueue;

    using CreateNativeWindowSurfaceFunction =
            std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>(
                    const sp<IGraphicBufferProducer>&)>;
    CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;
};

} // namespace surfaceflinger::test

class TestableSurfaceFlinger {
public:
    // Extend this as needed for accessing SurfaceFlinger private (and public)
@@ -45,14 +158,15 @@ public:
        mFlinger->getBE().mHwc.reset(new HWComposer(std::move(composer)));
    }

    using CreateBufferQueueFunction = SurfaceFlinger::CreateBufferQueueFunction;
    using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction;
    void setCreateBufferQueueFunction(CreateBufferQueueFunction f) {
        mFlinger->mCreateBufferQueue = f;
        mFactory.mCreateBufferQueue = f;
    }

    using CreateNativeWindowSurfaceFunction = SurfaceFlinger::CreateNativeWindowSurfaceFunction;
    using CreateNativeWindowSurfaceFunction =
            surfaceflinger::test::Factory::CreateNativeWindowSurfaceFunction;
    void setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f) {
        mFlinger->mCreateNativeWindowSurface = f;
        mFactory.mCreateNativeWindowSurface = f;
    }

    using HotplugEvent = SurfaceFlinger::HotplugEvent;
@@ -405,7 +519,8 @@ public:
        DisplayDeviceCreationArgs mCreationArgs;
    };

    sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(SurfaceFlinger::SkipInitialization);
    surfaceflinger::test::Factory mFactory;
    sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);

    // We need to keep a reference to these so they are properly destroyed.
    std::vector<std::unique_ptr<HWC2Display>> mFakeHwcDisplays;