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

Commit 44fcd6d0 authored by android-build-team Robot's avatar android-build-team Robot Committed by android-build-merger
Browse files

Merge changes Ife3ef43f,I50ec5d8b into pi-dev am: af0c7830

am: 09d6e4a2

Change-Id: I307192d74bc8bba142af114f332bac42eb9a7d3c
parents 08de8bae 09d6e4a2
Loading
Loading
Loading
Loading
+585 −4
Original line number Original line Diff line number Diff line
@@ -386,6 +386,11 @@ struct PhysicalDisplayVariant
                                 DisplayVariant<type, type, width, height, critical, Async::FALSE,
                                 DisplayVariant<type, type, width, height, critical, Async::FALSE,
                                                Secure::TRUE, GRALLOC_USAGE_PHYSICAL_DISPLAY>> {};
                                                Secure::TRUE, GRALLOC_USAGE_PHYSICAL_DISPLAY>> {};


// An invalid display
using InvalidDisplayVariant =
        DisplayVariant<DisplayDevice::DISPLAY_ID_INVALID, DisplayDevice::DISPLAY_ID_INVALID, 0, 0,
                       Critical::FALSE, Async::FALSE, Secure::FALSE, 0>;

// A primary display is a physical display that is critical
// A primary display is a physical display that is critical
using PrimaryDisplayVariant =
using PrimaryDisplayVariant =
        PhysicalDisplayVariant<1001, DisplayDevice::DISPLAY_PRIMARY, 3840, 2160, Critical::TRUE>;
        PhysicalDisplayVariant<1001, DisplayDevice::DISPLAY_PRIMARY, 3840, 2160, Critical::TRUE>;
@@ -645,6 +650,8 @@ using HdrHlgDisplayCase =
using HdrDolbyVisionDisplayCase =
using HdrDolbyVisionDisplayCase =
        Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
        Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
             HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>>;
             HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>>;
using InvalidDisplayCase = Case<InvalidDisplayVariant, WideColorSupportNotConfiguredVariant,
                                NonHwcDisplayHdrSupportVariant>;


/* ------------------------------------------------------------------------
/* ------------------------------------------------------------------------
 *
 *
@@ -1571,7 +1578,7 @@ TEST_F(HandleTransactionLockedTest, processesDisplayLayerStackChanges) {
    // --------------------------------------------------------------------
    // --------------------------------------------------------------------
    // Postconditions
    // Postconditions


    EXPECT_EQ(newLayerStack, getDisplayDevice(display.token())->getLayerStack());
    EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
}
}


TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
@@ -1599,7 +1606,7 @@ TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
    // --------------------------------------------------------------------
    // --------------------------------------------------------------------
    // Postconditions
    // Postconditions


    EXPECT_EQ(newTransform, getDisplayDevice(display.token())->getOrientation());
    EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
}
}


TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
@@ -1627,7 +1634,7 @@ TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
    // --------------------------------------------------------------------
    // --------------------------------------------------------------------
    // Postconditions
    // Postconditions


    EXPECT_EQ(newViewport, getDisplayDevice(display.token())->getViewport());
    EXPECT_EQ(newViewport, display.mutableDisplayDevice()->getViewport());
}
}


TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
@@ -1655,7 +1662,7 @@ TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
    // --------------------------------------------------------------------
    // --------------------------------------------------------------------
    // Postconditions
    // Postconditions


    EXPECT_EQ(newFrame, getDisplayDevice(display.token())->getFrame());
    EXPECT_EQ(newFrame, display.mutableDisplayDevice()->getFrame());
}
}


TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
@@ -1740,5 +1747,579 @@ TEST_F(HandleTransactionLockedTest, processesDisplayHeightChanges) {
    mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
    mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
}
}


/* ------------------------------------------------------------------------
 * SurfaceFlinger::setDisplayStateLocked
 */

TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
    // --------------------------------------------------------------------
    // Preconditions

    // We have an unknown display token not associated with a known display
    sp<BBinder> displayToken = new BBinder();

    // The requested display state references the unknown display.
    DisplayState state;
    state.what = DisplayState::eLayerStackChanged;
    state.token = displayToken;
    state.layerStack = 456;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags are empty
    EXPECT_EQ(0u, flags);

    // The display token still doesn't match anything known.
    EXPECT_FALSE(hasCurrentDisplayState(displayToken));
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithInvalidDisplay) {
    using Case = InvalidDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // An invalid display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The invalid display has some state
    display.mutableCurrentDisplayState().layerStack = 654u;

    // The requested display state tries to change the display state.
    DisplayState state;
    state.what = DisplayState::eLayerStackChanged;
    state.token = display.token();
    state.layerStack = 456;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags are empty
    EXPECT_EQ(0u, flags);

    // The current display layer stack value is unchanged.
    EXPECT_EQ(654u, getCurrentDisplayState(display.token()).layerStack);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
    using Case = SimplePrimaryDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is already set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // No changes are made to the display
    DisplayState state;
    state.what = 0;
    state.token = display.token();

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags are empty
    EXPECT_EQ(0u, flags);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
    using Case = SimplePrimaryDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is already set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // There is a surface that can be set.
    sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();

    // The current display state has the surface set
    display.mutableCurrentDisplayState().surface = surface;

    // The incoming request sets the same surface
    DisplayState state;
    state.what = DisplayState::eSurfaceChanged;
    state.token = display.token();
    state.surface = surface;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags are empty
    EXPECT_EQ(0u, flags);

    // The current display state is unchanged.
    EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
    using Case = SimplePrimaryDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is already set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // There is a surface that can be set.
    sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();

    // The current display state does not have a surface
    display.mutableCurrentDisplayState().surface = nullptr;

    // The incoming request sets a surface
    DisplayState state;
    state.what = DisplayState::eSurfaceChanged;
    state.token = display.token();
    state.surface = surface;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags indicate a transaction is needed
    EXPECT_EQ(eDisplayTransactionNeeded, flags);

    // The current display layer stack state is set to the new value
    EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
    using Case = SimplePrimaryDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is already set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The display has a layer stack set
    display.mutableCurrentDisplayState().layerStack = 456u;

    // The incoming request sets the same layer stack
    DisplayState state;
    state.what = DisplayState::eLayerStackChanged;
    state.token = display.token();
    state.layerStack = 456u;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags are empty
    EXPECT_EQ(0u, flags);

    // The current display state is unchanged
    EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
    using Case = SimplePrimaryDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The display has a layer stack set
    display.mutableCurrentDisplayState().layerStack = 654u;

    // The incoming request sets a different layer stack
    DisplayState state;
    state.what = DisplayState::eLayerStackChanged;
    state.token = display.token();
    state.layerStack = 456u;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags indicate a transaction is needed
    EXPECT_EQ(eDisplayTransactionNeeded, flags);

    // The desired display state has been set to the new value.
    EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
    using Case = SimplePrimaryDisplayCase;
    constexpr int initialOrientation = 180;
    const Rect initialFrame = {1, 2, 3, 4};
    const Rect initialViewport = {5, 6, 7, 8};

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The current display state projection state is all set
    display.mutableCurrentDisplayState().orientation = initialOrientation;
    display.mutableCurrentDisplayState().frame = initialFrame;
    display.mutableCurrentDisplayState().viewport = initialViewport;

    // The incoming request sets the same projection state
    DisplayState state;
    state.what = DisplayState::eDisplayProjectionChanged;
    state.token = display.token();
    state.orientation = initialOrientation;
    state.frame = initialFrame;
    state.viewport = initialViewport;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags are empty
    EXPECT_EQ(0u, flags);

    // The current display state is unchanged
    EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);

    EXPECT_EQ(initialFrame, display.getCurrentDisplayState().frame);
    EXPECT_EQ(initialViewport, display.getCurrentDisplayState().viewport);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
    using Case = SimplePrimaryDisplayCase;
    constexpr int initialOrientation = 90;
    constexpr int desiredOrientation = 180;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The current display state has an orientation set
    display.mutableCurrentDisplayState().orientation = initialOrientation;

    // The incoming request sets a different orientation
    DisplayState state;
    state.what = DisplayState::eDisplayProjectionChanged;
    state.token = display.token();
    state.orientation = desiredOrientation;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags indicate a transaction is needed
    EXPECT_EQ(eDisplayTransactionNeeded, flags);

    // The current display state has the new value.
    EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
    using Case = SimplePrimaryDisplayCase;
    const Rect initialFrame = {0, 0, 0, 0};
    const Rect desiredFrame = {5, 6, 7, 8};

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The current display state does not have a frame
    display.mutableCurrentDisplayState().frame = initialFrame;

    // The incoming request sets a frame
    DisplayState state;
    state.what = DisplayState::eDisplayProjectionChanged;
    state.token = display.token();
    state.frame = desiredFrame;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags indicate a transaction is needed
    EXPECT_EQ(eDisplayTransactionNeeded, flags);

    // The current display state has the new value.
    EXPECT_EQ(desiredFrame, display.getCurrentDisplayState().frame);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfViewportChanged) {
    using Case = SimplePrimaryDisplayCase;
    const Rect initialViewport = {0, 0, 0, 0};
    const Rect desiredViewport = {5, 6, 7, 8};

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The current display state does not have a viewport
    display.mutableCurrentDisplayState().viewport = initialViewport;

    // The incoming request sets a viewport
    DisplayState state;
    state.what = DisplayState::eDisplayProjectionChanged;
    state.token = display.token();
    state.viewport = desiredViewport;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags indicate a transaction is needed
    EXPECT_EQ(eDisplayTransactionNeeded, flags);

    // The current display state has the new value.
    EXPECT_EQ(desiredViewport, display.getCurrentDisplayState().viewport);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
    using Case = SimplePrimaryDisplayCase;
    constexpr uint32_t initialWidth = 1024;
    constexpr uint32_t initialHeight = 768;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The current display state has a size set
    display.mutableCurrentDisplayState().width = initialWidth;
    display.mutableCurrentDisplayState().height = initialHeight;

    // The incoming request sets the same display size
    DisplayState state;
    state.what = DisplayState::eDisplaySizeChanged;
    state.token = display.token();
    state.width = initialWidth;
    state.height = initialHeight;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags are empty
    EXPECT_EQ(0u, flags);

    // The current display state is unchanged
    EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
    EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
    using Case = SimplePrimaryDisplayCase;
    constexpr uint32_t initialWidth = 0;
    constexpr uint32_t desiredWidth = 1024;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The display does not yet have a width
    display.mutableCurrentDisplayState().width = initialWidth;

    // The incoming request sets a display width
    DisplayState state;
    state.what = DisplayState::eDisplaySizeChanged;
    state.token = display.token();
    state.width = desiredWidth;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags indicate a transaction is needed
    EXPECT_EQ(eDisplayTransactionNeeded, flags);

    // The current display state has the new value.
    EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
}

TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
    using Case = SimplePrimaryDisplayCase;
    constexpr uint32_t initialHeight = 0;
    constexpr uint32_t desiredHeight = 768;

    // --------------------------------------------------------------------
    // Preconditions

    // A display is set up
    auto display = Case::Display::makeFakeExistingDisplayInjector(this);
    display.inject();

    // The display does not yet have a height
    display.mutableCurrentDisplayState().height = initialHeight;

    // The incoming request sets a display height
    DisplayState state;
    state.what = DisplayState::eDisplaySizeChanged;
    state.token = display.token();
    state.height = desiredHeight;

    // --------------------------------------------------------------------
    // Invocation

    uint32_t flags = mFlinger.setDisplayStateLocked(state);

    // --------------------------------------------------------------------
    // Postconditions

    // The returned flags indicate a transaction is needed
    EXPECT_EQ(eDisplayTransactionNeeded, flags);

    // The current display state has the new value.
    EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
}

/* ------------------------------------------------------------------------
 * SurfaceFlinger::onInitializeDisplays
 */

TEST_F(DisplayTransactionTest, onInitializeDisplaysSetsUpPrimaryDisplay) {
    using Case = SimplePrimaryDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // A primary display is set up
    Case::Display::injectHwcDisplay(this);
    auto primaryDisplay = Case::Display::makeFakeExistingDisplayInjector(this);
    primaryDisplay.inject();

    // --------------------------------------------------------------------
    // Call Expectations

    // We expect the surface interceptor to possibly be used, but we treat it as
    // disabled since it is called as a side effect rather than directly by this
    // function.
    EXPECT_CALL(*mSurfaceInterceptor, isEnabled()).WillOnce(Return(false));

    // We expect a call to get the active display config.
    Case::Display::setupHwcGetActiveConfigCallExpectations(this);

    // We expect invalidate() to be invoked once to trigger display transaction
    // processing.
    EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);

    // --------------------------------------------------------------------
    // Invocation

    mFlinger.onInitializeDisplays();

    // --------------------------------------------------------------------
    // Postconditions

    // The primary display should have a current state
    ASSERT_TRUE(hasCurrentDisplayState(primaryDisplay.token()));
    const auto& primaryDisplayState = getCurrentDisplayState(primaryDisplay.token());
    // The layer stack state should be set to zero
    EXPECT_EQ(0u, primaryDisplayState.layerStack);
    // The orientation state should be set to zero
    EXPECT_EQ(0, primaryDisplayState.orientation);

    // The frame state should be set to INVALID
    EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);

    // The viewport state should be set to INVALID
    EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.viewport);

    // The width and height should both be zero
    EXPECT_EQ(0u, primaryDisplayState.width);
    EXPECT_EQ(0u, primaryDisplayState.height);

    // The display should be set to HWC_POWER_MODE_NORMAL
    ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
    auto displayDevice = primaryDisplay.mutableDisplayDevice();
    EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());

    // The display refresh period should be set in the frame tracker.
    FrameStats stats;
    mFlinger.getAnimFrameTracker().getStats(&stats);
    EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);

    // The display transaction needed flag should be set.
    EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));

    // The compositor timing should be set to default values
    const auto& compositorTiming = mFlinger.getCompositorTiming();
    EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
    EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
    EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
}

} // namespace
} // namespace
} // namespace android
} // namespace android
+22 −1
Original line number Original line Diff line number Diff line
@@ -85,6 +85,17 @@ public:
        return mFlinger->onHotplugReceived(sequenceId, display, connection);
        return mFlinger->onHotplugReceived(sequenceId, display, connection);
    }
    }


    auto setDisplayStateLocked(const DisplayState& s) { return mFlinger->setDisplayStateLocked(s); }

    auto onInitializeDisplays() { return mFlinger->onInitializeDisplays(); }

    /* ------------------------------------------------------------------------
     * Read-only access to private data to assert post-conditions.
     */

    const auto& getAnimFrameTracker() const { return mFlinger->mAnimFrameTracker; }
    const auto& getCompositorTiming() const { return mFlinger->getBE().mCompositorTiming; }

    /* ------------------------------------------------------------------------
    /* ------------------------------------------------------------------------
     * Read-write access to private data to set up preconditions and assert
     * Read-write access to private data to set up preconditions and assert
     * post-conditions.
     * post-conditions.
@@ -247,6 +258,16 @@ public:
            return mFlinger.mutableCurrentState().displays.editValueFor(mDisplayToken);
            return mFlinger.mutableCurrentState().displays.editValueFor(mDisplayToken);
        }
        }


        const auto& getDrawingDisplayState() {
            return mFlinger.mutableDrawingState().displays.valueFor(mDisplayToken);
        }

        const auto& getCurrentDisplayState() {
            return mFlinger.mutableCurrentState().displays.valueFor(mDisplayToken);
        }

        auto& mutableDisplayDevice() { return mFlinger.mutableDisplays().valueFor(mDisplayToken); }

        auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
        auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
            mNativeWindow = nativeWindow;
            mNativeWindow = nativeWindow;
            return *this;
            return *this;
@@ -280,7 +301,7 @@ public:
            mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
            mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
            mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
            mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);


            if (mType < DisplayDevice::DISPLAY_VIRTUAL) {
            if (mType >= DisplayDevice::DISPLAY_PRIMARY && mType < DisplayDevice::DISPLAY_VIRTUAL) {
                mFlinger.mutableBuiltinDisplays()[mType] = mDisplayToken;
                mFlinger.mutableBuiltinDisplays()[mType] = mDisplayToken;
            }
            }