diff options
author | 2024-06-04 02:59:13 +0000 | |
---|---|---|
committer | 2024-06-04 02:59:13 +0000 | |
commit | b51f44c4c2afad7dcac8b880ffc43fcb03905e02 (patch) | |
tree | 7196026a29097f82fbda967f9f2ace4e23cef1e2 | |
parent | 498a5782c8bdf17bc70ac851e25a0929ff4993c8 (diff) | |
parent | f12a678ffe5e640bee4b8595a2784feea3d991f3 (diff) |
Merge "Fix unsafe layer hierarchy access" into main
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerHierarchy.cpp | 41 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerHierarchy.h | 1 |
2 files changed, 26 insertions, 16 deletions
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp index 2b20de38d7..39a6b777bb 100644 --- a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp +++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp @@ -260,27 +260,36 @@ void LayerHierarchyBuilder::detachFromRelativeParent(LayerHierarchy* hierarchy) hierarchy->mParent->updateChild(hierarchy, LayerHierarchy::Variant::Attached); } -void LayerHierarchyBuilder::attachHierarchyToRelativeParent(LayerHierarchy* root) { - if (root->mLayer) { - attachToRelativeParent(root); - } - for (auto& [child, childVariant] : root->mChildren) { - if (childVariant == LayerHierarchy::Variant::Detached || - childVariant == LayerHierarchy::Variant::Attached) { - attachHierarchyToRelativeParent(child); +std::vector<LayerHierarchy*> LayerHierarchyBuilder::getDescendants(LayerHierarchy* root) { + std::vector<LayerHierarchy*> hierarchies; + hierarchies.push_back(root); + std::vector<LayerHierarchy*> descendants; + for (size_t i = 0; i < hierarchies.size(); i++) { + LayerHierarchy* hierarchy = hierarchies[i]; + if (hierarchy->mLayer) { + descendants.push_back(hierarchy); + } + for (auto& [child, childVariant] : hierarchy->mChildren) { + if (childVariant == LayerHierarchy::Variant::Detached || + childVariant == LayerHierarchy::Variant::Attached) { + hierarchies.push_back(child); + } } } + return descendants; } -void LayerHierarchyBuilder::detachHierarchyFromRelativeParent(LayerHierarchy* root) { - if (root->mLayer) { - detachFromRelativeParent(root); +void LayerHierarchyBuilder::attachHierarchyToRelativeParent(LayerHierarchy* root) { + std::vector<LayerHierarchy*> hierarchiesToAttach = getDescendants(root); + for (LayerHierarchy* hierarchy : hierarchiesToAttach) { + attachToRelativeParent(hierarchy); } - for (auto& [child, childVariant] : root->mChildren) { - if (childVariant == LayerHierarchy::Variant::Detached || - childVariant == LayerHierarchy::Variant::Attached) { - detachHierarchyFromRelativeParent(child); - } +} + +void LayerHierarchyBuilder::detachHierarchyFromRelativeParent(LayerHierarchy* root) { + std::vector<LayerHierarchy*> hierarchiesToDetach = getDescendants(root); + for (LayerHierarchy* hierarchy : hierarchiesToDetach) { + detachFromRelativeParent(hierarchy); } } diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h index 69710be8df..d023f9e9f5 100644 --- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h +++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h @@ -218,6 +218,7 @@ private: void detachFromParent(LayerHierarchy*); void attachToRelativeParent(LayerHierarchy*); void detachFromRelativeParent(LayerHierarchy*); + std::vector<LayerHierarchy*> getDescendants(LayerHierarchy*); void attachHierarchyToRelativeParent(LayerHierarchy*); void detachHierarchyFromRelativeParent(LayerHierarchy*); void init(const std::vector<std::unique_ptr<RequestedLayerState>>&); |