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