diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 076c6839c6..791b42512c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -6888,6 +6888,7 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, 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 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, 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 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, 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 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, /*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::State::traverseInReverseZOrder(const LayerVector::Visitor& } 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 @@ void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const 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 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots( } 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, |