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

Commit bdb8b804 authored by chaviw's avatar chaviw
Browse files

Set isRelativeOf flag when calling setZOrderRelativeOf

The current code sets the isRelativeFlag to true when setRelativeLayer
is called and false when setLayer is called. However, those two requests
are only coming from client requests. There are places where zRelativeOf
is removed for other reasons. Therefore, set isRelativeOf flag when
calling setZOrderRelativeOf based on whether relativeOf is null or not.
This will ensure it covers all places that zRelativeOf is updated.

Fixes: 142534793
Test: RelativeZTest.LayerAndRelativeRemoved
Change-Id: I338592f2e2e88598f2d8a4c0957b551da310a4bf
parent b92c27b6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -908,7 +908,6 @@ bool Layer::setLayer(int32_t z) {
        }
        setZOrderRelativeOf(nullptr);
    }
    mCurrentState.isRelativeOf = false;
    setTransactionFlags(eTransactionNeeded);
    return true;
}
@@ -931,6 +930,8 @@ void Layer::setZOrderRelativeOf(const wp<Layer>& relativeOf) {
    mCurrentState.zOrderRelativeOf = relativeOf;
    mCurrentState.sequence++;
    mCurrentState.modified = true;
    mCurrentState.isRelativeOf = relativeOf != nullptr;

    setTransactionFlags(eTransactionNeeded);
}

@@ -952,7 +953,6 @@ bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relati
    mCurrentState.sequence++;
    mCurrentState.modified = true;
    mCurrentState.z = relativeZ;
    mCurrentState.isRelativeOf = true;

    auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
    if (oldZOrderRelativeOf != nullptr) {
+59 −0
Original line number Diff line number Diff line
@@ -144,4 +144,63 @@ TEST_F(RelativeZTest, LayerRemovedOffscreenRelativeParent) {
        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
    }
}

TEST_F(RelativeZTest, LayerAndRelativeRemoved) {
    std::unique_ptr<ScreenCapture> sc;

    // Background layer (RED)
    // Foregroud layer (GREEN)
    //   Child layer (BLUE) (relative to relativeToLayer layer)
    //   Relative layer (WHITE)
    sp<SurfaceControl> childLayer =
            createColorLayer("Child layer", Color::BLUE, mForegroundLayer.get());
    sp<SurfaceControl> relativeToLayer =
            createColorLayer("Relative layer", Color::WHITE, mForegroundLayer.get());

    Transaction{}
            .setRelativeLayer(childLayer, relativeToLayer->getHandle(), 1)
            .show(childLayer)
            .show(relativeToLayer)
            .apply();

    {
        // The childLayer should be in front of relativeToLayer.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
    }

    // Remove layer that childLayer is relative to
    // Background layer (RED)
    // Foregroud layer (GREEN)
    //   Child layer (BLUE) (relative to relativeToLayer layer)
    Transaction{}.reparent(relativeToLayer, nullptr).apply();
    relativeToLayer = 0;

    {
        // The child layer is relative to an deleted layer so it won't be drawn.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
    }

    // Background layer (RED)
    // Foregroud layer (GREEN)
    Transaction{}.reparent(childLayer, nullptr).apply();

    {
        // The child layer is offscreen, so it won't be drawn.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
    }

    // Background layer (RED)
    // Foregroud layer (GREEN)
    //   Child layer (BLUE)
    Transaction{}.reparent(childLayer, mForegroundLayer->getHandle()).apply();

    {
        // The relative z info for child layer should be reset, leaving the child layer on top.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
    }
}
} // namespace android