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

Commit 161f9fd3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Reparent children before reparenting to null"

parents 8c742d0b 14d7692c
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -3957,15 +3957,6 @@ uint32_t SurfaceFlinger::setClientStateLocked(
        // We don't trigger a traversal here because if no other state is
        // changed, we don't want this to cause any more work
    }
    if (what & layer_state_t::eReparent) {
        bool hadParent = layer->hasParent();
        if (layer->reparent(s.parentHandleForChild)) {
            if (!hadParent) {
                mCurrentState.layersSortedByZ.remove(layer);
            }
            flags |= eTransactionNeeded|eTraversalNeeded;
        }
    }
    if (what & layer_state_t::eReparentChildren) {
        if (layer->reparentChildren(s.reparentHandle)) {
            flags |= eTransactionNeeded|eTraversalNeeded;
@@ -4026,6 +4017,19 @@ uint32_t SurfaceFlinger::setClientStateLocked(
            flags |= eTraversalNeeded;
        }
    }
    // This has to happen after we reparent children because when we reparent to null we remove
    // child layers from current state and remove its relative z. If the children are reparented in
    // the same transaction, then we have to make sure we reparent the children first so we do not
    // lose its relative z order.
    if (what & layer_state_t::eReparent) {
        bool hadParent = layer->hasParent();
        if (layer->reparent(s.parentHandleForChild)) {
            if (!hadParent) {
                mCurrentState.layersSortedByZ.remove(layer);
            }
            flags |= eTransactionNeeded | eTraversalNeeded;
        }
    }
    std::vector<sp<CallbackHandle>> callbackHandles;
    if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!listenerCallbacks.empty())) {
        for (const auto& [listener, callbackIds] : listenerCallbacks) {
+28 −0
Original line number Diff line number Diff line
@@ -4686,6 +4686,34 @@ TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
    }
}

TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
    sp<SurfaceControl> mGrandChild =
            createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
    fillSurfaceRGBA8(mGrandChild, 111, 111, 111);

    // draw grand child behind the foreground surface
    asTransaction([&](Transaction& t) {
        t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1);
    });

    {
        SCOPED_TRACE("Child visible");
        ScreenCapture::captureScreen(&mCapture);
        mCapture->checkPixel(64, 64, 200, 200, 200);
    }

    asTransaction([&](Transaction& t) {
        t.reparent(mChild, nullptr);
        t.reparentChildren(mChild, mFGSurfaceControl->getHandle());
    });

    {
        SCOPED_TRACE("foreground visible reparenting grandchild");
        ScreenCapture::captureScreen(&mCapture);
        mCapture->checkPixel(64, 64, 195, 63, 63);
    }
}

TEST_F(ChildLayerTest, DetachChildrenSameClient) {
    asTransaction([&](Transaction& t) {
        t.show(mChild);