Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0284463f authored by Ajinkya Chalke's avatar Ajinkya Chalke
Browse files

Move exclude layer to CaptureArgs.

Test: atest ScreenCaptureTest ScreenCaptureChildOnlyTest
Bug: 267324693
Change-Id: I6ab421e2f9e5bc0ab1422d88ddf2628776347a6f
parent 4642c41b
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -897,6 +897,11 @@ status_t CaptureArgs::writeToParcel(Parcel* output) const {
    SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(dataspace));
    SAFE_PARCEL(output->writeBool, allowProtected);
    SAFE_PARCEL(output->writeBool, grayscale);

    SAFE_PARCEL(output->writeInt32, excludeHandles.size());
    for (auto& excludeHandle : excludeHandles) {
        SAFE_PARCEL(output->writeStrongBinder, excludeHandle);
    }
    return NO_ERROR;
}

@@ -913,6 +918,15 @@ status_t CaptureArgs::readFromParcel(const Parcel* input) {
    dataspace = static_cast<ui::Dataspace>(value);
    SAFE_PARCEL(input->readBool, &allowProtected);
    SAFE_PARCEL(input->readBool, &grayscale);

    int32_t numExcludeHandles = 0;
    SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
    excludeHandles.reserve(numExcludeHandles);
    for (int i = 0; i < numExcludeHandles; i++) {
        sp<IBinder> binder;
        SAFE_PARCEL(input->readStrongBinder, &binder);
        excludeHandles.emplace(binder);
    }
    return NO_ERROR;
}

@@ -940,10 +954,6 @@ status_t LayerCaptureArgs::writeToParcel(Parcel* output) const {
    SAFE_PARCEL(CaptureArgs::writeToParcel, output);

    SAFE_PARCEL(output->writeStrongBinder, layerHandle);
    SAFE_PARCEL(output->writeInt32, excludeHandles.size());
    for (auto el : excludeHandles) {
        SAFE_PARCEL(output->writeStrongBinder, el);
    }
    SAFE_PARCEL(output->writeBool, childrenOnly);
    return NO_ERROR;
}
@@ -953,15 +963,6 @@ status_t LayerCaptureArgs::readFromParcel(const Parcel* input) {

    SAFE_PARCEL(input->readStrongBinder, &layerHandle);

    int32_t numExcludeHandles = 0;
    SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
    excludeHandles.reserve(numExcludeHandles);
    for (int i = 0; i < numExcludeHandles; i++) {
        sp<IBinder> binder;
        SAFE_PARCEL(input->readStrongBinder, &binder);
        excludeHandles.emplace(binder);
    }

    SAFE_PARCEL(input->readBool, &childrenOnly);
    return NO_ERROR;
}
+4 −0
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <gui/SpHash.h>
#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <unordered_set>

namespace android::gui {

@@ -55,6 +57,8 @@ struct CaptureArgs : public Parcelable {

    bool grayscale = false;

    std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;

    virtual status_t writeToParcel(Parcel* output) const;
    virtual status_t readFromParcel(const Parcel* input);
};
+0 −3
Original line number Diff line number Diff line
@@ -20,14 +20,11 @@
#include <sys/types.h>

#include <gui/DisplayCaptureArgs.h>
#include <gui/SpHash.h>
#include <unordered_set>

namespace android::gui {

struct LayerCaptureArgs : CaptureArgs {
    sp<IBinder> layerHandle;
    std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;
    bool childrenOnly{false};

    status_t writeToParcel(Parcel* output) const override;
+2 −1
Original line number Diff line number Diff line
@@ -347,7 +347,8 @@ void RegionSamplingThread::captureSample() {
                }
                visitor(layer);
            };
            mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor);
            mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, {},
                                                filterVisitor);
        };
        getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
    }
+66 −4
Original line number Diff line number Diff line
@@ -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);
        });
    }
@@ -8058,6 +8082,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,
Loading