Merge "Fix WPS to provides immediate feedback" 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/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 24cee24..0ed8be5 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -111,7 +111,7 @@
     LOGV("SurfaceTextureClient::cancelBuffer");
     Mutex::Autolock lock(mMutex);
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
-        if (mSlots[i].get() == buffer) {
+        if (mSlots[i]->handle == buffer->handle) {
             mSurfaceTexture->cancelBuffer(i);
             return OK;
         }
@@ -129,7 +129,7 @@
     LOGV("SurfaceTextureClient::queueBuffer");
     Mutex::Autolock lock(mMutex);
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
-        if (mSlots[i].get() == GraphicBuffer::getSelf(buffer)) {
+        if (mSlots[i]->handle == buffer->handle) {
             return mSurfaceTexture->queueBuffer(i);
         }
     }
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/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
index 9bfa8f6..2decfe9 100644
--- a/libs/ui/KeyCharacterMap.cpp
+++ b/libs/ui/KeyCharacterMap.cpp
@@ -185,9 +185,11 @@
     const Key* key;
     const Behavior* behavior;
     if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
-        outFallbackAction->keyCode = behavior->fallbackKeyCode;
-        outFallbackAction->metaState = metaState & ~behavior->metaState;
-        result = true;
+        if (behavior->fallbackKeyCode) {
+            outFallbackAction->keyCode = behavior->fallbackKeyCode;
+            outFallbackAction->metaState = metaState & ~behavior->metaState;
+            result = true;
+        }
     }
 #if DEBUG_MAPPING
     LOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 8a021cb..0c1fcf9 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -503,12 +503,18 @@
 
 void LayerBase::setBufferCrop(const Rect& crop) {
     if (!crop.isEmpty()) {
-        mBufferCrop = crop;
+        if (mBufferCrop != crop) {
+            mBufferCrop = crop;
+            mFlinger->invalidateHwcGeometry();
+        }
     }
 }
 
 void LayerBase::setBufferTransform(uint32_t transform) {
-    mBufferTransform = transform;
+    if (mBufferTransform != transform) {
+        mBufferTransform = transform;
+        mFlinger->invalidateHwcGeometry();
+    }
 }
 
 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 967ff1a..154b822 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -465,7 +465,7 @@
         handleTransactionLocked(transactionFlags, ditchedLayers);
         mLastTransactionTime = systemTime() - now;
         mDebugInTransaction = 0;
-        mHwWorkListDirty = true;
+        invalidateHwcGeometry();
         // here the transaction has been committed
     }
 
@@ -731,13 +731,18 @@
 
             mWormholeRegion = screenRegion.subtract(opaqueRegion);
             mVisibleRegionsDirty = false;
-            mHwWorkListDirty = true;
+            invalidateHwcGeometry();
         }
 
     unlockPageFlip(currentLayers);
     mDirtyRegion.andSelf(screenRegion);
 }
 
+void SurfaceFlinger::invalidateHwcGeometry()
+{
+    mHwWorkListDirty = true;
+}
+
 bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
 {
     bool recomputeVisibleRegions = false;
@@ -1104,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();
 
@@ -1354,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;
@@ -1591,7 +1613,7 @@
             case 1008:  // toggle use of hw composer
                 n = data.readInt32();
                 mDebugDisableHWC = n ? 1 : 0;
-                mHwWorkListDirty = true;
+                invalidateHwcGeometry();
                 // fall-through...
             case 1004:{ // repaint everything
                 Mutex::Autolock _l(mStateLock);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 2f2977a..eabdc64 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -225,6 +225,7 @@
     status_t removeLayer(const sp<LayerBase>& layer);
     status_t addLayer(const sp<LayerBase>& layer);
     status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
+    void invalidateHwcGeometry();
 
     sp<Layer> getLayer(const sp<ISurface>& sur) const;
 
@@ -374,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)