libgui: Allow an IGBProducer to disable allocation

Adds a new method IGBP::allowAllocation, which controls whether
dequeueBuffer is permitted to allocate a new buffer. If allocation is
disallowed, dequeueBuffer will block or return an error as it
normally would (as controlled by *ControlledByApp).

If there are free buffers, but they are not of the correct dimensions,
format, or usage, they may be freed if a more suitable buffer is not
found first.

Bug: 19801715
Change-Id: I0d604958b78b2fd775c2547690301423f9a52165
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index b7982a9..7093ffa 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -46,6 +46,7 @@
     DISCONNECT,
     SET_SIDEBAND_STREAM,
     ALLOCATE_BUFFERS,
+    ALLOW_ALLOCATION,
 };
 
 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -271,6 +272,18 @@
             ALOGE("allocateBuffers failed to transact: %d", result);
         }
     }
+
+    virtual status_t allowAllocation(bool allow) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeInt32(static_cast<int32_t>(allow));
+        status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.readInt32();
+        return result;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -418,7 +431,7 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
-        case ALLOCATE_BUFFERS:
+        case ALLOCATE_BUFFERS: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             bool async = static_cast<bool>(data.readInt32());
             uint32_t width = data.readUint32();
@@ -427,6 +440,14 @@
             uint32_t usage = data.readUint32();
             allocateBuffers(async, width, height, format, usage);
             return NO_ERROR;
+        }
+        case ALLOW_ALLOCATION: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            bool allow = static_cast<bool>(data.readInt32());
+            status_t result = allowAllocation(allow);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }