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

Commit 894fd967 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 7571067 from 5a68a6cf to sc-d1-release

Change-Id: I5ed683136a17148280bc05a4c8ffd80cec5d3b9f
parents 72e9c86e 5a68a6cf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -175,7 +175,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te
    LayerFE::ClientCompositionTargetSettings targetSettings{
            .clip = Region(viewport),
            .needsFiltering = false,
            .isSecure = true,
            .isSecure = outputState.isSecure,
            .supportsProtectedContent = false,
            .clearRegion = clearRegion,
            .viewport = viewport,
+69 −3
Original line number Diff line number Diff line
@@ -51,6 +51,15 @@ MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, ""

    return expectedBlurSetting == arg.blurSetting;
}

MATCHER_P(ClientCompositionTargetSettingsSecureEq, expectedSecureSetting, "") {
    *result_listener << "ClientCompositionTargetSettings' SecureSettings aren't equal \n";
    *result_listener << "expected " << expectedSecureSetting << "\n";
    *result_listener << "actual " << arg.isSecure << "\n";

    return expectedSecureSetting == arg.isSecure;
}

static const ui::Size kOutputSize = ui::Size(1, 1);

class CachedSetTest : public testing::Test {
@@ -315,7 +324,7 @@ TEST_F(CachedSetTest, updateAge_BufferUpdate) {
    EXPECT_EQ(0u, cachedSet.getAge());
}

TEST_F(CachedSetTest, render) {
TEST_F(CachedSetTest, renderUnsecureOutput) {
    // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
    CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
    sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
@@ -348,9 +357,66 @@ TEST_F(CachedSetTest, render) {
        return NO_ERROR;
    };

    EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1));
    EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
    EXPECT_CALL(*layerFE1,
                prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(false)))
            .WillOnce(Return(clientCompList1));
    EXPECT_CALL(*layerFE2,
                prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(false)))
            .WillOnce(Return(clientCompList2));
    EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers));
    mOutputState.isSecure = false;
    cachedSet.render(mRenderEngine, mTexturePool, mOutputState);
    expectReadyBuffer(cachedSet);

    EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace());
    EXPECT_EQ(Rect(kOutputSize.width, kOutputSize.height), cachedSet.getTextureBounds());

    // Now check that appending a new cached set properly cleans up RenderEngine resources.
    CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
    cachedSet.append(CachedSet(layer3));
}

TEST_F(CachedSetTest, renderSecureOutput) {
    // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
    CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
    sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
    CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get();
    sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE;

    CachedSet cachedSet(layer1);
    cachedSet.append(CachedSet(layer2));

    std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
    clientCompList1.push_back({});
    clientCompList1[0].alpha = 0.5f;

    std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
    clientCompList2.push_back({});
    clientCompList2[0].alpha = 0.75f;

    const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings,
                                const std::vector<const renderengine::LayerSettings*>& layers,
                                const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
                                base::unique_fd&&, base::unique_fd*) -> size_t {
        EXPECT_EQ(mOutputState.framebufferSpace.content, displaySettings.physicalDisplay);
        EXPECT_EQ(mOutputState.layerStackSpace.content, displaySettings.clip);
        EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.orientation),
                  displaySettings.orientation);
        EXPECT_EQ(0.5f, layers[0]->alpha);
        EXPECT_EQ(0.75f, layers[1]->alpha);
        EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);

        return NO_ERROR;
    };

    EXPECT_CALL(*layerFE1,
                prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(true)))
            .WillOnce(Return(clientCompList1));
    EXPECT_CALL(*layerFE2,
                prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(true)))
            .WillOnce(Return(clientCompList2));
    EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers));
    mOutputState.isSecure = true;
    cachedSet.render(mRenderEngine, mTexturePool, mOutputState);
    expectReadyBuffer(cachedSet);

+10 −10
Original line number Diff line number Diff line
@@ -3382,7 +3382,7 @@ void SurfaceFlinger::invalidateHwcGeometry() {
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                                        const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                                        const sp<IBinder>& parentHandle,
                                        const sp<Layer>& parentLayer, bool addToCurrentState,
                                        const sp<Layer>& parentLayer, bool addToRoot,
                                        uint32_t* outTransformHint) {
    if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) {
        ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
@@ -3394,7 +3394,7 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBind
    if (gbc != nullptr) {
        initialProducer = IInterface::asBinder(gbc);
    }
    setLayerCreatedState(handle, lbc, parentHandle, parentLayer, initialProducer);
    setLayerCreatedState(handle, lbc, parentHandle, parentLayer, initialProducer, addToRoot);

    // Create a transaction includes the initial parent and producer.
    Vector<ComposerState> states;
@@ -3918,7 +3918,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(
    sp<Layer> layer = nullptr;
    if (s.surface) {
        if (what & layer_state_t::eLayerCreated) {
            layer = handleLayerCreatedLocked(s.surface, privileged);
            layer = handleLayerCreatedLocked(s.surface);
            if (layer) {
                // put the created layer into mLayersByLocalBinderToken.
                mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
@@ -4328,9 +4328,9 @@ status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& clie
        return result;
    }

    bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                            addToCurrentState, outTransformHint);
    bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess();
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer, addToRoot,
                            outTransformHint);
    if (result != NO_ERROR) {
        return result;
    }
@@ -6873,10 +6873,10 @@ void SurfaceFlinger::TransactionState::traverseStatesWithBuffers(

void SurfaceFlinger::setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
                                          const wp<IBinder>& parent, const wp<Layer> parentLayer,
                                          const wp<IBinder>& producer) {
                                          const wp<IBinder>& producer, bool addToRoot) {
    Mutex::Autolock lock(mCreatedLayersLock);
    mCreatedLayers[handle->localBinder()] =
            std::make_unique<LayerCreatedState>(layer, parent, parentLayer, producer);
            std::make_unique<LayerCreatedState>(layer, parent, parentLayer, producer, addToRoot);
}

auto SurfaceFlinger::getLayerCreatedState(const sp<IBinder>& handle) {
@@ -6901,7 +6901,7 @@ auto SurfaceFlinger::getLayerCreatedState(const sp<IBinder>& handle) {
    return state;
}

sp<Layer> SurfaceFlinger::handleLayerCreatedLocked(const sp<IBinder>& handle, bool privileged) {
sp<Layer> SurfaceFlinger::handleLayerCreatedLocked(const sp<IBinder>& handle) {
    const auto& state = getLayerCreatedState(handle);
    if (!state) {
        return nullptr;
@@ -6914,7 +6914,7 @@ sp<Layer> SurfaceFlinger::handleLayerCreatedLocked(const sp<IBinder>& handle, bo
    }

    sp<Layer> parent;
    bool allowAddRoot = privileged;
    bool allowAddRoot = state->addToRoot;
    if (state->initialParent != nullptr) {
        parent = fromHandleLocked(state->initialParent.promote()).promote();
        if (parent == nullptr) {
+10 −6
Original line number Diff line number Diff line
@@ -905,7 +905,7 @@ private:
    status_t addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                            const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                            const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
                            bool addToCurrentState, uint32_t* outTransformHint);
                            bool addToRoot, uint32_t* outTransformHint);

    // Traverse through all the layers and compute and cache its bounds.
    void computeLayerBounds();
@@ -1454,11 +1454,12 @@ private:
    mutable Mutex mCreatedLayersLock;
    struct LayerCreatedState {
        LayerCreatedState(const wp<Layer>& layer, const wp<IBinder>& parent,
                          const wp<Layer> parentLayer, const wp<IBinder>& producer)
                          const wp<Layer> parentLayer, const wp<IBinder>& producer, bool addToRoot)
              : layer(layer),
                initialParent(parent),
                initialParentLayer(parentLayer),
                initialProducer(producer) {}
                initialProducer(producer),
                addToRoot(addToRoot) {}
        wp<Layer> layer;
        // Indicates the initial parent of the created layer, only used for creating layer in
        // SurfaceFlinger. If nullptr, it may add the created layer into the current root layers.
@@ -1467,6 +1468,10 @@ private:
        // Indicates the initial graphic buffer producer of the created layer, only used for
        // creating layer in SurfaceFlinger.
        wp<IBinder> initialProducer;
        // Indicates whether the layer getting created should be added at root if there's no parent
        // and has permission ACCESS_SURFACE_FLINGER. If set to false and no parent, the layer will
        // be added offscreen.
        bool addToRoot;
    };

    // A temporay pool that store the created layers and will be added to current state in main
@@ -1474,10 +1479,9 @@ private:
    std::unordered_map<BBinder*, std::unique_ptr<LayerCreatedState>> mCreatedLayers;
    void setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
                              const wp<IBinder>& parent, const wp<Layer> parentLayer,
                              const wp<IBinder>& producer);
                              const wp<IBinder>& producer, bool addToRoot);
    auto getLayerCreatedState(const sp<IBinder>& handle);
    sp<Layer> handleLayerCreatedLocked(const sp<IBinder>& handle, bool privileged)
            REQUIRES(mStateLock);
    sp<Layer> handleLayerCreatedLocked(const sp<IBinder>& handle) REQUIRES(mStateLock);

    std::atomic<ui::Transform::RotationFlags> mDefaultDisplayTransformHint;

+46 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"

#include <private/android_filesystem_config.h>
#include "LayerTransactionTest.h"
#include "utils/TransactionUtils.h"

namespace android {

@@ -227,6 +229,50 @@ TEST_F(MirrorLayerTest, MirrorBufferLayer) {
    }
}

// Test that the mirror layer is initially offscreen.
TEST_F(MirrorLayerTest, InitialMirrorState) {
    const auto display = SurfaceComposerClient::getInternalDisplayToken();
    ui::DisplayMode mode;
    SurfaceComposerClient::getActiveDisplayMode(display, &mode);
    const ui::Size& size = mode.resolution;

    sp<SurfaceControl> mirrorLayer = nullptr;
    {
        // Run as system to get the ACCESS_SURFACE_FLINGER permission when mirroring
        UIDFaker f(AID_SYSTEM);
        // Mirror mChildLayer
        mirrorLayer = mClient->mirrorSurface(mChildLayer.get());
        ASSERT_NE(mirrorLayer, nullptr);
    }

    // Show the mirror layer, but don't reparent to a layer on screen.
    Transaction()
            .setPosition(mirrorLayer, 500, 500)
            .show(mirrorLayer)
            .setLayer(mirrorLayer, INT32_MAX - 1)
            .apply();

    {
        SCOPED_TRACE("Offscreen Mirror");
        auto shot = screenshot();
        shot->expectColor(Rect(0, 0, size.getWidth(), 50), Color::RED);
        shot->expectColor(Rect(0, 0, 50, size.getHeight()), Color::RED);
        shot->expectColor(Rect(450, 0, size.getWidth(), size.getHeight()), Color::RED);
        shot->expectColor(Rect(0, 450, size.getWidth(), size.getHeight()), Color::RED);
        shot->expectColor(Rect(50, 50, 450, 450), Color::GREEN);
    }

    // Add mirrorLayer as child of mParentLayer so it's shown on the display
    Transaction().reparent(mirrorLayer, mParentLayer).apply();

    {
        SCOPED_TRACE("On Screen Mirror");
        auto shot = screenshot();
        // Child mirror
        shot->expectColor(Rect(550, 550, 950, 950), Color::GREEN);
    }
}

} // namespace android

// TODO(b/129481165): remove the #pragma below and fix conversion issues