Merge "Fix issue 2416481: Support Voice Dialer over BT SCO."
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
index 8330f8e..141f69b 100644
--- a/cmds/keystore/keystore_get.h
+++ b/cmds/keystore/keystore_get.h
@@ -32,9 +32,11 @@
 #endif
 
 /* This function is provided for native components to get values from keystore.
- * Users are required to link against libcutils. The lengths of keys and values
- * are limited to KEYSTORE_MESSAGE_SIZE. This function returns the length of
- * the requested value or -1 if something goes wrong. */
+ * Users are required to link against libcutils. Keys are values are 8-bit safe.
+ * The first two arguments are the key and its length. The third argument
+ * specifies the buffer to store the retrieved value, which must be an array of
+ * KEYSTORE_MESSAGE_SIZE bytes. This function returns the length of the value or
+ * -1 if an error happens. */
 static int keystore_get(const char *key, int length, char *value)
 {
     uint8_t bytes[2] = {length >> 8, length};
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 7ca7875..4dc4a15 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -465,44 +465,61 @@
         // for composition later in the loop
         return;
     }
-    
+
+    // ouch, this really should never happen
+    if (uint32_t(buf)>=NUM_BUFFERS) {
+        LOGE("retireAndLock() buffer index (%d) out of range", buf);
+        mPostedDirtyRegion.clear();
+        return;
+    }
+
     // we retired a buffer, which becomes the new front buffer
     mFrontBufferIndex = buf;
 
     // get the dirty region
     sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
-    const Region dirty(lcblk->getDirtyRegion(buf));
-    mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
+    if (newFrontBuffer != NULL) {
+        // compute the posted region
+        const Region dirty(lcblk->getDirtyRegion(buf));
+        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
 
-    const Layer::State& front(drawingState());
-    if (newFrontBuffer->getWidth()  == front.requested_w &&
-        newFrontBuffer->getHeight() == front.requested_h)
-    {
-        if ((front.w != front.requested_w) ||
-            (front.h != front.requested_h))
+        // update the layer size and release freeze-lock
+        const Layer::State& front(drawingState());
+        if (newFrontBuffer->getWidth()  == front.requested_w &&
+            newFrontBuffer->getHeight() == front.requested_h)
         {
-            // Here we pretend the transaction happened by updating the
-            // current and drawing states. Drawing state is only accessed
-            // in this thread, no need to have it locked
-            Layer::State& editDraw(mDrawingState);
-            editDraw.w = editDraw.requested_w;
-            editDraw.h = editDraw.requested_h;
+            if ((front.w != front.requested_w) ||
+                (front.h != front.requested_h))
+            {
+                // Here we pretend the transaction happened by updating the
+                // current and drawing states. Drawing state is only accessed
+                // in this thread, no need to have it locked
+                Layer::State& editDraw(mDrawingState);
+                editDraw.w = editDraw.requested_w;
+                editDraw.h = editDraw.requested_h;
 
-            // We also need to update the current state so that we don't
-            // end-up doing too much work during the next transaction.
-            // NOTE: We actually don't need hold the transaction lock here
-            // because State::w and State::h are only accessed from
-            // this thread
-            Layer::State& editTemp(currentState());
-            editTemp.w = editDraw.w;
-            editTemp.h = editDraw.h;
+                // We also need to update the current state so that we don't
+                // end-up doing too much work during the next transaction.
+                // NOTE: We actually don't need hold the transaction lock here
+                // because State::w and State::h are only accessed from
+                // this thread
+                Layer::State& editTemp(currentState());
+                editTemp.w = editDraw.w;
+                editTemp.h = editDraw.h;
 
-            // recompute visible region
-            recomputeVisibleRegions = true;
+                // recompute visible region
+                recomputeVisibleRegions = true;
+            }
+
+            // we now have the correct size, unfreeze the screen
+            mFreezeLock.clear();
         }
-
-        // we now have the correct size, unfreeze the screen
-        mFreezeLock.clear();
+    } else {
+        // this should not happen unless we ran out of memory while
+        // allocating the buffer. we're hoping that things will get back
+        // to normal the next time the app tries to draw into this buffer.
+        // meanwhile, pretend the screen didn't update.
+        mPostedDirtyRegion.clear();
     }
 
     if (lcblk->getQueuedCount()) {
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 140f10c..efbc77a 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -214,7 +214,6 @@
     if ((front.w != temp.w) || (front.h != temp.h)) {
         // invalidate and recompute the visible regions if needed
         flags |= Layer::eVisibleRegion;
-        this->contentDirty = true;
     }
 
     if (temp.sequence != front.sequence) {
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index a6e5644..62ec839 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -157,11 +157,11 @@
     
     /**
      * setCoveredRegion - called when the covered region changes. The covered
-     * region correspond to any area of the surface that is covered 
+     * region corresponds to any area of the surface that is covered
      * (transparently or not) by another surface.
      */
     virtual void setCoveredRegion(const Region& coveredRegion);
-    
+
     /**
      * validateVisibility - cache a bunch of things
      */
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 26ee285..0722fda 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -674,6 +674,8 @@
 {
     const GraphicPlane& plane(graphicPlane(0));
     const Transform& planeTransform(plane.transform());
+    const DisplayHardware& hw(plane.displayHardware());
+    const Region screenRegion(hw.bounds());
 
     Region aboveOpaqueLayers;
     Region aboveCoveredLayers;
@@ -689,31 +691,56 @@
         // start with the whole surface at its current location
         const Layer::State& s(layer->drawingState());
 
-        // handle hidden surfaces by setting the visible region to empty
+        /*
+         * opaqueRegion: area of a surface that is fully opaque.
+         */
         Region opaqueRegion;
+
+        /*
+         * visibleRegion: area of a surface that is visible on screen
+         * and not fully transparent. This is essentially the layer's
+         * footprint minus the opaque regions above it.
+         * Areas covered by a translucent surface are considered visible.
+         */
         Region visibleRegion;
+
+        /*
+         * coveredRegion: area of a surface that is covered by all
+         * visible regions above it (which includes the translucent areas).
+         */
         Region coveredRegion;
+
+
+        // handle hidden surfaces by setting the visible region to empty
         if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
             const bool translucent = layer->needsBlending();
             const Rect bounds(layer->visibleBounds());
             visibleRegion.set(bounds);
-            coveredRegion = visibleRegion;
+            visibleRegion.andSelf(screenRegion);
+            if (!visibleRegion.isEmpty()) {
+                // Remove the transparent area from the visible region
+                if (translucent) {
+                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
+                }
 
-            // Remove the transparent area from the visible region
-            if (translucent) {
-                visibleRegion.subtractSelf(layer->transparentRegionScreen);
-            }
-
-            // compute the opaque region
-            if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
-                // the opaque region is the visible region
-                opaqueRegion = visibleRegion;
+                // compute the opaque region
+                const int32_t layerOrientation = layer->getOrientation();
+                if (s.alpha==255 && !translucent &&
+                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
+                    // the opaque region is the layer's footprint
+                    opaqueRegion = visibleRegion;
+                }
             }
         }
 
+        // Clip the covered region to the visible region
+        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
+
+        // Update aboveCoveredLayers for next (lower) layer
+        aboveCoveredLayers.orSelf(visibleRegion);
+
         // subtract the opaque region covered by the layers above us
         visibleRegion.subtractSelf(aboveOpaqueLayers);
-        coveredRegion.andSelf(aboveCoveredLayers);
 
         // compute this layer's dirty region
         if (layer->contentDirty) {
@@ -724,19 +751,30 @@
             layer->contentDirty = false;
         } else {
             /* compute the exposed region:
-             *    exposed = what's VISIBLE and NOT COVERED now 
-             *    but was COVERED before
+             *   the exposed region consists of two components:
+             *   1) what's VISIBLE now and was COVERED before
+             *   2) what's EXPOSED now less what was EXPOSED before
+             *
+             * note that (1) is conservative, we start with the whole
+             * visible region but only keep what used to be covered by
+             * something -- which mean it may have been exposed.
+             *
+             * (2) handles areas that were not covered by anything but got
+             * exposed because of a resize.
              */
-            dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen;
+            const Region newExposed = visibleRegion - coveredRegion;
+            const Region oldVisibleRegion = layer->visibleRegionScreen;
+            const Region oldCoveredRegion = layer->coveredRegionScreen;
+            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
+            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
         }
         dirty.subtractSelf(aboveOpaqueLayers);
 
         // accumulate to the screen dirty region
         dirtyRegion.orSelf(dirty);
 
-        // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
+        // Update aboveOpaqueLayers for next (lower) layer
         aboveOpaqueLayers.orSelf(opaqueRegion);
-        aboveCoveredLayers.orSelf(visibleRegion);
         
         // Store the visible region is screen space
         layer->setVisibleRegion(visibleRegion);
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 145e25e..89b3e1f 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -650,6 +650,7 @@
     if (dp->refs > 0) {
         if (major != NULL) *major = VERSION_MAJOR;
         if (minor != NULL) *minor = VERSION_MINOR;
+        dp->refs++;
         return EGL_TRUE;
     }
     
@@ -755,8 +756,10 @@
     }
 
     // this is specific to Android, display termination is ref-counted.
-    if (dp->refs > 1)
+    if (dp->refs > 1) {
+        dp->refs--;
         return EGL_TRUE;
+    }
 
     EGLBoolean res = EGL_FALSE;
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {