SF: Avoid promoting parent layer in binder thread
Some components in SF extend the life cycle of layer objects
causing them to be destroyed without the state lock held. If a binder
thread promotes a layer, there is a chance it will be left holding the
last reference. This will cause the layer to be destroyed in the binder
thread, resulting in invalid accesses and crashes.
Fix this by tracking root layers with a variable to avoid promoting
parent layer in binder thread.
Test: presubmit, manually test refresh rate overlay
Test: go/wm-smoke
Fixes: 186412934
Change-Id: Icd9f4e851bbd92c887e113e52505ce4d8eb3ea0c
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2650fa0..7270016 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4181,6 +4181,7 @@
: nullptr;
if (layer->reparent(parentHandle)) {
if (!hadParent) {
+ layer->setIsAtRoot(false);
mCurrentState.layersSortedByZ.remove(layer);
}
flags |= eTransactionNeeded | eTraversalNeeded;
@@ -4447,7 +4448,8 @@
// with the idea that the parent holds a reference and will eventually
// be cleaned up. However no one cleans up the top-level so we do so
// here.
- if (layer->getParent() == nullptr) {
+ if (layer->isAtRoot()) {
+ layer->setIsAtRoot(false);
mCurrentState.layersSortedByZ.remove(layer);
}
markLayerPendingRemovalLocked(layer);
@@ -6924,6 +6926,7 @@
}
if (parent == nullptr && allowAddRoot) {
+ layer->setIsAtRoot(true);
mCurrentState.layersSortedByZ.add(layer);
} else if (parent == nullptr) {
layer->onRemovedFromCurrentState();