summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChavi Weingarten <chaviw@google.com>2021-07-20 21:51:15 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-07-20 21:51:15 +0000
commit707e8136ead8dedde02b14aa821a908166bc5876 (patch)
tree4d7ff46cb8bd5e04de3fc529842b4c958f5da595
parent5ede32f26da962bf50970e2827cb294fbd2b281a (diff)
parente0c7b82ad21471b0e07bc176eb9de021d297ff51 (diff)
downloadnative-707e8136ead8dedde02b14aa821a908166bc5876.tar.gz
Merge "Place mirrored layers offscreen instead of at root." into sc-dev
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp20
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h16
-rw-r--r--services/surfaceflinger/tests/MirrorLayer_test.cpp46
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