Fix remote GraphicBuffer allocation in SurfaceFlinger.

This change fixes a horrible hack that I did to allow application
processes to create GraphicBuffer objects by making a binder call to
SurfaceFlinger.  This change introduces a new binder interface
specifically for doing this, and does it in such a way that
SurfaceFlinger will maintain a reference to the buffers until the app is
done with them.

Change-Id: Icb240397c6c206d7f69124c1497a829f051cb49b
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c982ea5..967ff1a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -144,6 +144,11 @@
     return bclient;
 }
 
+sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
+{
+    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
+    return gba;
+}
 
 const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
 {
@@ -2267,25 +2272,6 @@
 
 // ---------------------------------------------------------------------------
 
-sp<GraphicBuffer> SurfaceFlinger::createGraphicBuffer(uint32_t w, uint32_t h,
-        PixelFormat format, uint32_t usage) const {
-    // XXX: HACK HACK HACK!!!  This should NOT be static, but it is to fix a
-    // race between SurfaceFlinger unref'ing the buffer and the client ref'ing
-    // it.
-    static sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
-    status_t err = graphicBuffer->initCheck();
-    if (err != 0) {
-        LOGE("createGraphicBuffer: init check failed: %d", err);
-        return 0;
-    } else if (graphicBuffer->handle == 0) {
-        LOGE("createGraphicBuffer: unable to create GraphicBuffer");
-        return 0;
-    }
-    return graphicBuffer;
-}
-
-// ---------------------------------------------------------------------------
-
 Client::Client(const sp<SurfaceFlinger>& flinger)
     : mFlinger(flinger), mNameGenerator(1)
 {
@@ -2465,6 +2451,39 @@
 
 // ---------------------------------------------------------------------------
 
+GraphicBufferAlloc::GraphicBufferAlloc() {}
+
+GraphicBufferAlloc::~GraphicBufferAlloc() {}
+
+sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
+        PixelFormat format, uint32_t usage) {
+    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
+    status_t err = graphicBuffer->initCheck();
+    if (err != 0) {
+        LOGE("createGraphicBuffer: init check failed: %d", err);
+        return 0;
+    } else if (graphicBuffer->handle == 0) {
+        LOGE("createGraphicBuffer: unable to create GraphicBuffer");
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+    mBuffers.add(graphicBuffer);
+    return graphicBuffer;
+}
+
+void GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) {
+    Mutex::Autolock _l(mLock);
+    if (0 <= bufIdx && bufIdx < mBuffers.size()) {
+        sp<GraphicBuffer> b(mBuffers[bufIdx]);
+        mBuffers.clear();
+        mBuffers.add(b);
+    } else {
+        mBuffers.clear();
+    }
+}
+
+// ---------------------------------------------------------------------------
+
 GraphicPlane::GraphicPlane()
     : mHw(0)
 {