Merge "Set mIsMinInfoReady and mCurrentOtasp before notifcations." into honeycomb
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 2df8ca3..5532052 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -233,7 +233,7 @@
* private stuff...
*/
void init();
- status_t validate() const;
+ status_t validate(bool inCancelBuffer = false) const;
sp<ISurface> getISurface() const;
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index aa0c2e8..e21bab7 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -466,7 +466,7 @@
return mInitCheck == NO_ERROR;
}
-status_t Surface::validate() const
+status_t Surface::validate(bool inCancelBuffer) const
{
// check that we initialized ourself properly
if (mInitCheck != NO_ERROR) {
@@ -476,15 +476,6 @@
// verify the identity of this surface
uint32_t identity = mSharedBufferClient->getIdentity();
-
- // this is a bit of a (temporary) special case, identity==0 means that
- // no operation are allowed from the client (eg: dequeue/queue), this
- // is used with PUSH_BUFFER surfaces for instance
- if (identity == 0) {
- LOGE("[Surface] invalid operation (identity=%u)", mIdentity);
- return INVALID_OPERATION;
- }
-
if (mIdentity != identity) {
LOGE("[Surface] using an invalid surface, "
"identity=%u should be %d",
@@ -492,17 +483,19 @@
CallStack stack;
stack.update();
stack.dump("Surface");
- return NO_INIT;
+ return BAD_INDEX;
}
// check the surface didn't become invalid
status_t err = mSharedBufferClient->getStatus();
if (err != NO_ERROR) {
- LOGE("surface (identity=%u) is invalid, err=%d (%s)",
- mIdentity, err, strerror(-err));
- CallStack stack;
- stack.update();
- stack.dump("Surface");
+ if (!inCancelBuffer) {
+ LOGE("surface (identity=%u) is invalid, err=%d (%s)",
+ mIdentity, err, strerror(-err));
+ CallStack stack;
+ stack.update();
+ stack.dump("Surface");
+ }
return err;
}
@@ -633,12 +626,12 @@
int Surface::cancelBuffer(android_native_buffer_t* buffer)
{
- status_t err = validate();
+ status_t err = validate(true);
switch (err) {
case NO_ERROR:
// no error, common case
break;
- case INVALID_OPERATION:
+ case BAD_INDEX:
// legitimate errors here
return err;
default:
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 77695d7..154b822 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1109,8 +1109,12 @@
status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
{
- // remove the layer from the main list (through a transaction).
+ // First add the layer to the purgatory list, which makes sure it won't
+ // go away, then remove it from the main list (through a transaction).
ssize_t err = removeLayer_l(layerBase);
+ if (err >= 0) {
+ mLayerPurgatory.add(layerBase);
+ }
layerBase->onRemoved();
@@ -1359,6 +1363,19 @@
* to use the purgatory.
*/
status_t err = flinger->removeLayer_l(l);
+ if (err == NAME_NOT_FOUND) {
+ // The surface wasn't in the current list, which means it was
+ // removed already, which means it is in the purgatory,
+ // and need to be removed from there.
+ // This needs to happen from the main thread since its dtor
+ // must run from there (b/c of OpenGL ES). Additionally, we
+ // can't really acquire our internal lock from
+ // destroySurface() -- see postMessage() below.
+ ssize_t idx = flinger->mLayerPurgatory.remove(l);
+ LOGE_IF(idx < 0,
+ "layer=%p is not in the purgatory list", l.get());
+ }
+
LOGE_IF(err<0 && err != NAME_NOT_FOUND,
"error removing layer=%p (%s)", l.get(), strerror(-err));
return true;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 2591123..eabdc64 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -375,6 +375,7 @@
volatile int32_t mTransactionFlags;
volatile int32_t mTransactionCount;
Condition mTransactionCV;
+ SortedVector< sp<LayerBase> > mLayerPurgatory;
bool mResizeTransationPending;
// protected by mStateLock (but we could use another lock)