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

Commit ebb78143 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Automerger Merge Worker
Browse files

Merge "Place mirrored layers offscreen instead of at root." into sc-dev am:...

Merge "Place mirrored layers offscreen instead of at root." into sc-dev am: 707e8136 am: 14f50596

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15340011

Change-Id: If66465024095e278857157919599c80c65a5a7a6
parents ce4973ba 14f50596
Loading
Loading
Loading
Loading
+10 −10
Original line number Original line Diff line number Diff line
@@ -3357,7 +3357,7 @@ void SurfaceFlinger::invalidateHwcGeometry() {
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                                        const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                                        const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                                        const sp<IBinder>& parentHandle,
                                        const sp<IBinder>& parentHandle,
                                        const sp<Layer>& parentLayer, bool addToCurrentState,
                                        const sp<Layer>& parentLayer, bool addToRoot,
                                        uint32_t* outTransformHint) {
                                        uint32_t* outTransformHint) {
    if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) {
    if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) {
        ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
        ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
@@ -3369,7 +3369,7 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBind
    if (gbc != nullptr) {
    if (gbc != nullptr) {
        initialProducer = IInterface::asBinder(gbc);
        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.
    // Create a transaction includes the initial parent and producer.
    Vector<ComposerState> states;
    Vector<ComposerState> states;
@@ -3899,7 +3899,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(
    sp<Layer> layer = nullptr;
    sp<Layer> layer = nullptr;
    if (s.surface) {
    if (s.surface) {
        if (what & layer_state_t::eLayerCreated) {
        if (what & layer_state_t::eLayerCreated) {
            layer = handleLayerCreatedLocked(s.surface, privileged);
            layer = handleLayerCreatedLocked(s.surface);
            if (layer) {
            if (layer) {
                // put the created layer into mLayersByLocalBinderToken.
                // put the created layer into mLayersByLocalBinderToken.
                mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
                mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
@@ -4309,9 +4309,9 @@ status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& clie
        return result;
        return result;
    }
    }


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


void SurfaceFlinger::setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
void SurfaceFlinger::setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
                                          const wp<IBinder>& parent, const wp<Layer> parentLayer,
                                          const wp<IBinder>& parent, const wp<Layer> parentLayer,
                                          const wp<IBinder>& producer) {
                                          const wp<IBinder>& producer, bool addToRoot) {
    Mutex::Autolock lock(mCreatedLayersLock);
    Mutex::Autolock lock(mCreatedLayersLock);
    mCreatedLayers[handle->localBinder()] =
    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) {
auto SurfaceFlinger::getLayerCreatedState(const sp<IBinder>& handle) {
@@ -6860,7 +6860,7 @@ auto SurfaceFlinger::getLayerCreatedState(const sp<IBinder>& handle) {
    return state;
    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);
    const auto& state = getLayerCreatedState(handle);
    if (!state) {
    if (!state) {
        return nullptr;
        return nullptr;
@@ -6873,7 +6873,7 @@ sp<Layer> SurfaceFlinger::handleLayerCreatedLocked(const sp<IBinder>& handle, bo
    }
    }


    sp<Layer> parent;
    sp<Layer> parent;
    bool allowAddRoot = privileged;
    bool allowAddRoot = state->addToRoot;
    if (state->initialParent != nullptr) {
    if (state->initialParent != nullptr) {
        parent = fromHandleLocked(state->initialParent.promote()).promote();
        parent = fromHandleLocked(state->initialParent.promote()).promote();
        if (parent == nullptr) {
        if (parent == nullptr) {
+10 −6
Original line number Original line Diff line number Diff line
@@ -899,7 +899,7 @@ private:
    status_t addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
    status_t addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                            const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                            const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                            const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
                            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.
    // Traverse through all the layers and compute and cache its bounds.
    void computeLayerBounds();
    void computeLayerBounds();
@@ -1451,11 +1451,12 @@ private:
    mutable Mutex mCreatedLayersLock;
    mutable Mutex mCreatedLayersLock;
    struct LayerCreatedState {
    struct LayerCreatedState {
        LayerCreatedState(const wp<Layer>& layer, const wp<IBinder>& parent,
        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),
              : layer(layer),
                initialParent(parent),
                initialParent(parent),
                initialParentLayer(parentLayer),
                initialParentLayer(parentLayer),
                initialProducer(producer) {}
                initialProducer(producer),
                addToRoot(addToRoot) {}
        wp<Layer> layer;
        wp<Layer> layer;
        // Indicates the initial parent of the created layer, only used for creating layer in
        // 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.
        // SurfaceFlinger. If nullptr, it may add the created layer into the current root layers.
@@ -1464,6 +1465,10 @@ private:
        // Indicates the initial graphic buffer producer of the created layer, only used for
        // Indicates the initial graphic buffer producer of the created layer, only used for
        // creating layer in SurfaceFlinger.
        // creating layer in SurfaceFlinger.
        wp<IBinder> initialProducer;
        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
    // A temporay pool that store the created layers and will be added to current state in main
@@ -1471,10 +1476,9 @@ private:
    std::unordered_map<BBinder*, std::unique_ptr<LayerCreatedState>> mCreatedLayers;
    std::unordered_map<BBinder*, std::unique_ptr<LayerCreatedState>> mCreatedLayers;
    void setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
    void setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,
                              const wp<IBinder>& parent, const wp<Layer> parentLayer,
                              const wp<IBinder>& parent, const wp<Layer> parentLayer,
                              const wp<IBinder>& producer);
                              const wp<IBinder>& producer, bool addToRoot);
    auto getLayerCreatedState(const sp<IBinder>& handle);
    auto getLayerCreatedState(const sp<IBinder>& handle);
    sp<Layer> handleLayerCreatedLocked(const sp<IBinder>& handle, bool privileged)
    sp<Layer> handleLayerCreatedLocked(const sp<IBinder>& handle) REQUIRES(mStateLock);
            REQUIRES(mStateLock);


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


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


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


namespace android {
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
} // namespace android


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