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

Commit 4aa22af2 authored by Chavi Weingarten's avatar Chavi Weingarten
Browse files

Ensure sub-hierarchy screenshots inherit secure from parent.

If a sub-hierarchy is screenshot that doesn't include the parent layer
that had the secure flag, the screenshot request would not respect the
secure flag. This is incorrect because we want to ensure secure flag
remains on all children regardless of where in the hierarchy the
screenshot is taken.

Test: CaptureChildRespectsParentSecureFlag
Test: CaptureOffscreenChildRespectsParentSecureFlag
Test: LayerSnapshotTest#setSecureRootSnapshot
Bug: 308662081
Change-Id: I13f19a7fa4b9e51da0aa097314f015fe1340fc54
parent d1a34bff
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -433,4 +433,15 @@ void LayerLifecycleManager::updateDisplayMirrorLayers(RequestedLayerState& rootL
    }
}

bool LayerLifecycleManager::isLayerSecure(uint32_t layerId) const {
    if (layerId == UNASSIGNED_LAYER_ID) {
        return false;
    }

    if (getLayerFromId(layerId)->flags & layer_state_t::eLayerSecure) {
        return true;
    }
    return isLayerSecure(getLayerFromId(layerId)->parentId);
}

} // namespace android::surfaceflinger::frontend
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ public:
    const std::vector<RequestedLayerState*>& getChangedLayers() const;
    const ftl::Flags<RequestedLayerState::Changes> getGlobalChanges() const;
    const RequestedLayerState* getLayerFromId(uint32_t) const;
    bool isLayerSecure(uint32_t) const;

private:
    friend class LayerLifecycleManagerTest;
+9 −9
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ LayerSnapshot LayerSnapshotBuilder::getRootSnapshot() {
    return snapshot;
}

LayerSnapshotBuilder::LayerSnapshotBuilder() : mRootSnapshot(getRootSnapshot()) {}
LayerSnapshotBuilder::LayerSnapshotBuilder() {}

LayerSnapshotBuilder::LayerSnapshotBuilder(Args args) : LayerSnapshotBuilder() {
    args.forceUpdate = ForceUpdateFlags::ALL;
@@ -417,19 +417,20 @@ bool LayerSnapshotBuilder::tryFastUpdate(const Args& args) {

void LayerSnapshotBuilder::updateSnapshots(const Args& args) {
    ATRACE_NAME("UpdateSnapshots");
    LayerSnapshot rootSnapshot = args.rootSnapshot;
    if (args.parentCrop) {
        mRootSnapshot.geomLayerBounds = *args.parentCrop;
        rootSnapshot.geomLayerBounds = *args.parentCrop;
    } else if (args.forceUpdate == ForceUpdateFlags::ALL || args.displayChanges) {
        mRootSnapshot.geomLayerBounds = getMaxDisplayBounds(args.displays);
        rootSnapshot.geomLayerBounds = getMaxDisplayBounds(args.displays);
    }
    if (args.displayChanges) {
        mRootSnapshot.changes = RequestedLayerState::Changes::AffectsChildren |
        rootSnapshot.changes = RequestedLayerState::Changes::AffectsChildren |
                RequestedLayerState::Changes::Geometry;
    }
    if (args.forceUpdate == ForceUpdateFlags::HIERARCHY) {
        mRootSnapshot.changes |=
        rootSnapshot.changes |=
                RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Visibility;
        mRootSnapshot.clientChanges |= layer_state_t::eReparent;
        rootSnapshot.clientChanges |= layer_state_t::eReparent;
    }

    for (auto& snapshot : mSnapshots) {
@@ -444,13 +445,13 @@ void LayerSnapshotBuilder::updateSnapshots(const Args& args) {
        // multiple children.
        LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root, args.root.getLayer()->id,
                                                                LayerHierarchy::Variant::Attached);
        updateSnapshotsInHierarchy(args, args.root, root, mRootSnapshot, /*depth=*/0);
        updateSnapshotsInHierarchy(args, args.root, root, rootSnapshot, /*depth=*/0);
    } else {
        for (auto& [childHierarchy, variant] : args.root.mChildren) {
            LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root,
                                                                    childHierarchy->getLayer()->id,
                                                                    variant);
            updateSnapshotsInHierarchy(args, *childHierarchy, root, mRootSnapshot, /*depth=*/0);
            updateSnapshotsInHierarchy(args, *childHierarchy, root, rootSnapshot, /*depth=*/0);
        }
    }

@@ -459,7 +460,6 @@ void LayerSnapshotBuilder::updateSnapshots(const Args& args) {
    updateTouchableRegionCrop(args);

    const bool hasUnreachableSnapshots = sortSnapshotsByZ(args);
    clearChanges(mRootSnapshot);

    // Destroy unreachable snapshots for clone layers. And destroy snapshots for non-clone
    // layers if the layer have been destroyed.
+4 −2
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@ namespace android::surfaceflinger::frontend {
// The builder also uses a fast path to update
// snapshots when there are only buffer updates.
class LayerSnapshotBuilder {
private:
    static LayerSnapshot getRootSnapshot();

public:
    enum class ForceUpdateFlags {
        NONE,
@@ -55,6 +58,7 @@ public:
        const std::unordered_map<std::string, bool>& supportedLayerGenericMetadata;
        const std::unordered_map<std::string, uint32_t>& genericLayerMetadataKeyMap;
        bool skipRoundCornersWhenProtected = false;
        LayerSnapshot rootSnapshot = getRootSnapshot();
    };
    LayerSnapshotBuilder();

@@ -87,7 +91,6 @@ public:

private:
    friend class LayerSnapshotTest;
    static LayerSnapshot getRootSnapshot();

    // return true if we were able to successfully update the snapshots via
    // the fast path.
@@ -130,7 +133,6 @@ private:
    std::unordered_set<LayerHierarchy::TraversalPath, LayerHierarchy::TraversalPathHash>
            mNeedsTouchableRegionCrop;
    std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
    LayerSnapshot mRootSnapshot;
    bool mResortSnapshots = false;
    int mNumInterestingSnapshots = 0;
};
+1 −0
Original line number Diff line number Diff line
@@ -8958,6 +8958,7 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t u
                     .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap(),
                     .skipRoundCornersWhenProtected =
                             !getRenderEngine().supportsProtectedContent()};
        args.rootSnapshot.isSecure = mLayerLifecycleManager.isLayerSecure(rootLayerId);
        mLayerSnapshotBuilder.update(args);

        auto getLayerSnapshotsFn =
Loading