SF: Test coverage for setupNewDisplayDeviceInternal

Adds unit tests to cover
SurfaceFlinger::setupnewDisplayDeviceInternal().

Test: libsurfaceflinger_unittest passes on Pixel XL
Bug: 74827900
Change-Id: Iba75a955314bdcd1d9ee54bb3d9eda1a8d082f34
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 2dd8e5f..d3b637b 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -60,6 +60,14 @@
      * Forwarding for functions being tested
      */
 
+    auto setupNewDisplayDeviceInternal(const wp<IBinder>& display, int hwcId,
+                                       const DisplayDeviceState& state,
+                                       const sp<DisplaySurface>& dispSurface,
+                                       const sp<IGraphicBufferProducer>& producer) {
+        return mFlinger->setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface,
+                                                       producer);
+    }
+
     auto handleTransactionLocked(uint32_t transactionFlags) {
         return mFlinger->handleTransactionLocked(transactionFlags);
     }
@@ -69,9 +77,12 @@
      * post-conditions.
      */
 
+    auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
+
     auto& mutableBuiltinDisplays() { return mFlinger->mBuiltinDisplays; }
     auto& mutableCurrentState() { return mFlinger->mCurrentState; }
     auto& mutableDisplays() { return mFlinger->mDisplays; }
+    auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
     auto& mutableDrawingState() { return mFlinger->mDrawingState; }
     auto& mutableEventControlThread() { return mFlinger->mEventControlThread; }
     auto& mutableEventQueue() { return mFlinger->mEventQueue; }
@@ -79,6 +90,7 @@
     auto& mutableInterceptor() { return mFlinger->mInterceptor; }
     auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
     auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
+    auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
 
     auto& mutableHwcDisplayData() { return mFlinger->getBE().mHwc->mDisplayData; }
     auto& mutableHwcDisplaySlots() { return mFlinger->getBE().mHwc->mHwcDisplaySlots; }
@@ -101,6 +113,7 @@
      * Wrapper classes for Read-write access to private data to set up
      * preconditions and assert post-conditions.
      */
+
     struct HWC2Display : public HWC2::Display {
         HWC2Display(Hwc2::Composer& composer,
                     const std::unordered_set<HWC2::Capability>& capabilities, hwc2_display_t id,
@@ -115,7 +128,163 @@
         auto& mutableConfigs() { return this->mConfigs; }
     };
 
+    class FakeHwcDisplayInjector {
+    public:
+        static constexpr hwc2_display_t DEFAULT_HWC_DISPLAY_ID = 1000;
+        static constexpr int32_t DEFAULT_WIDTH = 1920;
+        static constexpr int32_t DEFAULT_HEIGHT = 1280;
+        static constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
+        static constexpr int32_t DEFAULT_DPI = 320;
+        static constexpr int32_t DEFAULT_ACTIVE_CONFIG = 0;
+
+        FakeHwcDisplayInjector(DisplayDevice::DisplayType type, HWC2::DisplayType hwcDisplayType)
+              : mType(type), mHwcDisplayType(hwcDisplayType) {}
+
+        auto& setHwcDisplayId(hwc2_display_t displayId) {
+            mHwcDisplayId = displayId;
+            return *this;
+        }
+
+        auto& setWidth(int32_t width) {
+            mWidth = width;
+            return *this;
+        }
+
+        auto& setHeight(int32_t height) {
+            mHeight = height;
+            return *this;
+        }
+
+        auto& setRefreshRate(int32_t refreshRate) {
+            mRefreshRate = refreshRate;
+            return *this;
+        }
+
+        auto& setDpiX(int32_t dpi) {
+            mDpiX = dpi;
+            return *this;
+        }
+
+        auto& setDpiY(int32_t dpi) {
+            mDpiY = dpi;
+            return *this;
+        }
+
+        auto& setActiveConfig(int32_t config) {
+            mActiveConfig = config;
+            return *this;
+        }
+
+        auto& addCapability(HWC2::Capability cap) {
+            mCapabilities.emplace(cap);
+            return *this;
+        }
+
+        void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) {
+            auto display = std::make_unique<HWC2Display>(*composer, mCapabilities, mHwcDisplayId,
+                                                         mHwcDisplayType);
+
+            auto config = HWC2::Display::Config::Builder(*display, mActiveConfig);
+            config.setWidth(mWidth);
+            config.setHeight(mHeight);
+            config.setVsyncPeriod(mRefreshRate);
+            config.setDpiX(mDpiX);
+            config.setDpiY(mDpiY);
+            display->mutableConfigs().emplace(mActiveConfig, config.build());
+            display->mutableIsConnected() = true;
+
+            ASSERT_TRUE(flinger->mutableHwcDisplayData().size() > static_cast<size_t>(mType));
+            flinger->mutableHwcDisplayData()[mType].reset();
+            flinger->mutableHwcDisplayData()[mType].hwcDisplay = display.get();
+            flinger->mutableHwcDisplaySlots().emplace(mHwcDisplayId, mType);
+
+            flinger->mFakeHwcDisplays.push_back(std::move(display));
+        }
+
+    private:
+        DisplayDevice::DisplayType mType;
+        HWC2::DisplayType mHwcDisplayType;
+        hwc2_display_t mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
+        int32_t mWidth = DEFAULT_WIDTH;
+        int32_t mHeight = DEFAULT_HEIGHT;
+        int32_t mRefreshRate = DEFAULT_REFRESH_RATE;
+        int32_t mDpiX = DEFAULT_DPI;
+        int32_t mDpiY = DEFAULT_DPI;
+        int32_t mActiveConfig = DEFAULT_ACTIVE_CONFIG;
+        std::unordered_set<HWC2::Capability> mCapabilities;
+    };
+
+    class FakeDisplayDeviceInjector {
+    public:
+        FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger, DisplayDevice::DisplayType type,
+                                  int hwcId)
+              : mFlinger(flinger), mType(type), mHwcId(hwcId) {}
+
+        sp<IBinder> token() const { return mDisplayToken; }
+
+        DisplayDeviceState& mutableDrawingDisplayState() {
+            return mFlinger.mutableDrawingState().displays.editValueFor(mDisplayToken);
+        }
+
+        DisplayDeviceState& mutableCurrentDisplayState() {
+            return mFlinger.mutableCurrentState().displays.editValueFor(mDisplayToken);
+        }
+
+        auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
+            mNativeWindow = nativeWindow;
+            return *this;
+        }
+
+        auto& setDisplaySurface(const sp<DisplaySurface>& displaySurface) {
+            mDisplaySurface = displaySurface;
+            return *this;
+        }
+
+        auto& setRenderSurface(std::unique_ptr<RE::Surface> renderSurface) {
+            mRenderSurface = std::move(renderSurface);
+            return *this;
+        }
+
+        auto& setSecure(bool secure) {
+            mSecure = secure;
+            return *this;
+        }
+
+        sp<DisplayDevice> inject() {
+            sp<DisplayDevice> device =
+                    new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, mSecure, mDisplayToken,
+                                      mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
+                                      0, false, HdrCapabilities(), 0, HWC_POWER_MODE_NORMAL);
+            mFlinger.mutableDisplays().add(mDisplayToken, device);
+
+            DisplayDeviceState state;
+            state.type = mType;
+            state.isSecure = mSecure;
+            mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
+            mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
+
+            if (mType < DisplayDevice::DISPLAY_VIRTUAL) {
+                mFlinger.mutableBuiltinDisplays()[mType] = mDisplayToken;
+            }
+
+            return device;
+        }
+
+    private:
+        TestableSurfaceFlinger& mFlinger;
+        sp<BBinder> mDisplayToken = new BBinder();
+        DisplayDevice::DisplayType mType;
+        int mHwcId;
+        sp<ANativeWindow> mNativeWindow;
+        sp<DisplaySurface> mDisplaySurface;
+        std::unique_ptr<RE::Surface> mRenderSurface;
+        bool mSecure = false;
+    };
+
     sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(SurfaceFlinger::SkipInitialization);
+
+    // We need to keep a reference to these so they are properly destroyed.
+    std::vector<std::unique_ptr<HWC2Display>> mFakeHwcDisplays;
 };
 
 } // namespace android