summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olv@google.com>2017-06-06 15:32:08 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-06-06 15:32:10 +0000
commit39cf8b4944bbbaeeabae357ef2122bfc4457f211 (patch)
treef8f8140fb9c63cf3755a2125be4820f6acb9448d
parenteed865e61b98aa3cae2b323cc95930b430ed1e8c (diff)
parente6b63e1ae12692327f7e46d5f10d6ade5a7bf192 (diff)
downloadnative-39cf8b4944bbbaeeabae357ef2122bfc4457f211.tar.gz
Merge "surfaceflinger: fix layer count" into oc-dev
-rw-r--r--services/surfaceflinger/Layer.cpp8
-rw-r--r--services/surfaceflinger/Layer.h1
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp18
3 files changed, 26 insertions, 1 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 6f430a386f..2ff14aa395 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2523,6 +2523,14 @@ bool Layer::getTransformToDisplayInverse() const {
return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
}
+size_t Layer::getChildrenCount() const {
+ size_t count = 0;
+ for (const sp<Layer>& child : mCurrentChildren) {
+ count += 1 + child->getChildrenCount();
+ }
+ return count;
+}
+
void Layer::addChild(const sp<Layer>& layer) {
mCurrentChildren.add(layer);
layer->setParent(this);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 05c367dfad..5335fff9ff 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -519,6 +519,7 @@ public:
const LayerVector::Visitor& visitor);
void traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor);
+ size_t getChildrenCount() const;
void addChild(const sp<Layer>& layer);
// Returns index if removed, or negative value otherwise
// for symmetry with Vector::remove
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 29a8292ff6..801e8ddf4d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2656,8 +2656,13 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
if (parent == nullptr) {
mCurrentState.layersSortedByZ.add(lbc);
} else {
+ if (mCurrentState.layersSortedByZ.indexOf(parent) < 0) {
+ ALOGE("addClientLayer called with a removed parent");
+ return NAME_NOT_FOUND;
+ }
parent->addChild(lbc);
}
+
mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
mLayersAdded = true;
mNumLayers++;
@@ -2676,6 +2681,17 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
mCurrentState.layersSortedByZ.remove(layer);
+ if (p != nullptr) {
+ sp<Layer> ancestor = p;
+ while (ancestor->getParent() != nullptr) {
+ ancestor = ancestor->getParent();
+ }
+ if (mCurrentState.layersSortedByZ.indexOf(ancestor) < 0) {
+ ALOGE("removeLayer called with a layer whose parent has been removed");
+ return NAME_NOT_FOUND;
+ }
+ }
+
// As a matter of normal operation, the LayerCleaner will produce a second
// attempt to remove the surface. The Layer will be kept alive in mDrawingState
// so we will succeed in promoting it, but it's already been removed
@@ -2692,7 +2708,7 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
mLayersPendingRemoval.add(layer);
mLayersRemoved = true;
- mNumLayers--;
+ mNumLayers -= 1 + layer->getChildrenCount();
setTransactionFlags(eTransactionNeeded);
return NO_ERROR;
}