diff options
author | Chavi Weingarten <chaviw@google.com> | 2021-07-20 21:51:15 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-07-20 21:51:15 +0000 |
commit | 707e8136ead8dedde02b14aa821a908166bc5876 (patch) | |
tree | 4d7ff46cb8bd5e04de3fc529842b4c958f5da595 | |
parent | 5ede32f26da962bf50970e2827cb294fbd2b281a (diff) | |
parent | e0c7b82ad21471b0e07bc176eb9de021d297ff51 (diff) | |
download | native-707e8136ead8dedde02b14aa821a908166bc5876.tar.gz |
Merge "Place mirrored layers offscreen instead of at root." into sc-dev
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 20 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 16 | ||||
-rw-r--r-- | services/surfaceflinger/tests/MirrorLayer_test.cpp | 46 |
3 files changed, 66 insertions, 16 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0b369a5d17..2cc810986f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -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) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index b1fd208725..4fd86af24f 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -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; diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp index ccf434d63a..d02786504e 100644 --- a/services/surfaceflinger/tests/MirrorLayer_test.cpp +++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp @@ -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 |