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 Diff line number Diff line
@@ -3357,7 +3357,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(),
@@ -3369,7 +3369,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;
@@ -3899,7 +3899,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);
@@ -4309,9 +4309,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;
    }
@@ -6832,10 +6832,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) {
@@ -6860,7 +6860,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;
@@ -6873,7 +6873,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
@@ -899,7 +899,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();
@@ -1451,11 +1451,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.
@@ -1464,6 +1465,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
@@ -1471,10 +1476,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