BufferQueue: Add producer buffer-released callback

Add a callback to the producer side, onBufferReleased, which will be
called every time the consumer releases a buffer back to the
BufferQueue. This will enable a buffer stream splitter to work
autonomously without having to block on dequeueBuffer.

The binder object used for the callback replaces the generic IBinder
token that was passed into IGraphicBufferProducer::connect to detect
the death of the producer. If a producer does not wish to listen for
buffer release events, it can pass in an instance of the
DummyProducerListener class defined in IProducerListener.h, if it even
cares about death events (BufferQueue doesn't enforce the token being
non-NULL, though perhaps we should).

Change-Id: I23935760673524abeafea2b58dccc3583b368710
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
new file mode 100644
index 0000000..efe4069
--- /dev/null
+++ b/libs/gui/IProducerListener.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/Parcel.h>
+
+#include <gui/IProducerListener.h>
+
+namespace android {
+
+enum {
+    ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+class BpProducerListener : public BpInterface<IProducerListener>
+{
+public:
+    BpProducerListener(const sp<IBinder>& impl)
+        : BpInterface<IProducerListener>(impl) {}
+
+    virtual void onBufferReleased() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
+        remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener")
+
+status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,
+        Parcel* reply, uint32_t flags) {
+    switch (code) {
+        case ON_BUFFER_RELEASED:
+            CHECK_INTERFACE(IProducerListener, data, reply);
+            onBufferReleased();
+            return NO_ERROR;
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+} // namespace android