Move exclude layer to CaptureArgs.
Test: atest ScreenCaptureTest ScreenCaptureChildOnlyTest
Bug: 267324693
Change-Id: I6ab421e2f9e5bc0ab1422d88ddf2628776347a6f
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 327ca3f..531d277 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -347,7 +347,8 @@
}
visitor(layer);
};
- mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor);
+ mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, {},
+ filterVisitor);
};
getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 076c683..791b425 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -6888,6 +6888,7 @@
wp<const DisplayDevice> displayWeak;
ui::LayerStack layerStack;
ui::Size reqSize(args.width, args.height);
+ std::unordered_set<uint32_t> excludeLayerIds;
ui::Dataspace dataspace;
{
Mutex::Autolock lock(mStateLock);
@@ -6901,6 +6902,16 @@
reqSize = display->getLayerStackSpaceRect().getSize();
}
+ for (const auto& handle : args.excludeHandles) {
+ uint32_t excludeLayer = LayerHandle::getLayerId(handle);
+ if (excludeLayer != UNASSIGNED_LAYER_ID) {
+ excludeLayerIds.emplace(excludeLayer);
+ } else {
+ ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay");
+ return NAME_NOT_FOUND;
+ }
+ }
+
// Allow the caller to specify a dataspace regardless of the display's color mode, e.g. if
// it wants sRGB regardless of the display's wide color mode.
dataspace = args.dataspace == ui::Dataspace::UNKNOWN
@@ -6916,10 +6927,11 @@
GetLayerSnapshotsFunction getLayerSnapshots;
if (mLayerLifecycleManagerEnabled) {
getLayerSnapshots =
- getLayerSnapshotsForScreenshots(layerStack, args.uid, /*snapshotFilterFn=*/nullptr);
+ getLayerSnapshotsForScreenshots(layerStack, args.uid, std::move(excludeLayerIds));
} else {
- auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) {
- traverseLayersInLayerStack(layerStack, args.uid, visitor);
+ auto traverseLayers = [this, args, excludeLayerIds,
+ layerStack](const LayerVector::Visitor& visitor) {
+ traverseLayersInLayerStack(layerStack, args.uid, std::move(excludeLayerIds), visitor);
};
getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
}
@@ -6962,7 +6974,7 @@
/*snapshotFilterFn=*/nullptr);
} else {
auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) {
- traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
+ traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, {}, visitor);
};
getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
}
@@ -7386,6 +7398,7 @@
}
void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const int32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds,
const LayerVector::Visitor& visitor) {
// We loop through the first level of layers without traversing,
// as we need to determine which layers belong to the requested display.
@@ -7404,6 +7417,17 @@
if (uid != CaptureArgs::UNSET_UID && layer->getOwnerUid() != uid) {
return;
}
+
+ if (!excludeLayerIds.empty()) {
+ auto p = sp<Layer>::fromExisting(layer);
+ while (p != nullptr) {
+ if (excludeLayerIds.count(p->sequence) != 0) {
+ return;
+ }
+ p = p->getParent();
+ }
+ }
+
visitor(layer);
});
}
@@ -8059,6 +8083,44 @@
}
std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
+SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,
+ uint32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds) {
+ return [&, layerStack, uid, excludeLayerIds = std::move(excludeLayerIds)]() {
+ if (excludeLayerIds.empty()) {
+ auto getLayerSnapshotsFn =
+ getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
+ std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
+ return layers;
+ }
+
+ frontend::LayerSnapshotBuilder::Args
+ args{.root = mLayerHierarchyBuilder.getHierarchy(),
+ .layerLifecycleManager = mLayerLifecycleManager,
+ .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY,
+ .displays = mFrontEndDisplayInfos,
+ .displayChanges = true,
+ .globalShadowSettings = mDrawingState.globalShadowSettings,
+ .supportsBlur = mSupportsBlur,
+ .forceFullDamage = mForceFullDamage,
+ .excludeLayerIds = std::move(excludeLayerIds),
+ .supportedLayerGenericMetadata =
+ getHwComposer().getSupportedLayerGenericMetadata(),
+ .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap()};
+ mLayerSnapshotBuilder.update(args);
+
+ auto getLayerSnapshotsFn =
+ getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
+ std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
+
+ args.excludeLayerIds.clear();
+ mLayerSnapshotBuilder.update(args);
+
+ return layers;
+ };
+}
+
+std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid,
std::unordered_set<uint32_t> excludeLayerIds,
bool childrenOnly,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 74d00dd..4484788 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -826,7 +826,9 @@
// If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
// matching ownerUid
- void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid, const LayerVector::Visitor&);
+ void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds,
+ const LayerVector::Visitor&);
void readPersistentProperties();
@@ -1381,6 +1383,9 @@
std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)>
snapshotFilterFn);
std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
+ std::optional<ui::LayerStack> layerStack, uint32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds);
+ std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
uint32_t rootLayerId, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds,
bool childrenOnly, const std::optional<FloatRect>& optionalParentCrop);
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index 976ee35..013694f 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -222,6 +222,14 @@
mCapture->checkPixel(0, 0, 200, 200, 200);
}
+TEST_F(ScreenCaptureTest, CaptureLayerExcludeThroughDisplayArgs) {
+ mCaptureArgs.excludeHandles = {mFGSurfaceControl->getHandle()};
+ ScreenCapture::captureDisplay(&mCapture, mCaptureArgs);
+ mCapture->expectBGColor(0, 0);
+ // Doesn't capture FG layer which is at 64, 64
+ mCapture->expectBGColor(64, 64);
+}
+
// Like the last test but verifies that children are also exclude.
TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
auto fgHandle = mFGSurfaceControl->getHandle();
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 19a93e1..f596061 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -204,7 +204,7 @@
auto traverseLayers = [this](const LayerVector::Visitor& visitor) {
return mFlinger.traverseLayersInLayerStack(mDisplay->getLayerStack(),
- CaptureArgs::UNSET_UID, visitor);
+ CaptureArgs::UNSET_UID, {}, visitor);
};
auto getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index fc9e653..89a190e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -446,8 +446,10 @@
}
auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds,
const LayerVector::Visitor& visitor) {
- return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid, visitor);
+ return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid,
+ excludeLayerIds, visitor);
}
auto getDisplayNativePrimaries(const sp<IBinder>& displayToken,