Add sideband streams to BufferQueue and related classes

Sideband streams are essentially a device-specific buffer queue that
bypasses the BufferQueue system. They can be used for situations with
hard real-time requirements like high-quality TV and video playback
with A/V sync. A handle to the stream is provided by the source HAL,
and attached to a BufferQueue. The sink HAL can read buffers via the
stream handle rather than acquiring individual buffers from the
BufferQueue.

Change-Id: Ib3f262eddfc520f4bbe3d9b91753ed7dd09d3a9b
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 0f461e5..efbe878 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -18,9 +18,10 @@
 #include <sys/types.h>
 
 #include <utils/Errors.h>
+#include <utils/NativeHandle.h>
 #include <utils/RefBase.h>
-#include <utils/Vector.h>
 #include <utils/Timers.h>
+#include <utils/Vector.h>
 
 #include <binder/Parcel.h>
 #include <binder/IInterface.h>
@@ -39,6 +40,7 @@
     QUERY,
     CONNECT,
     DISCONNECT,
+    SET_SIDEBAND_STREAM,
 };
 
 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -169,6 +171,22 @@
         result = reply.readInt32();
         return result;
     }
+
+    virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
+        Parcel data, reply;
+        status_t result;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        if (stream.get()) {
+            data.writeInt32(true);
+            data.writeNativeHandle(stream->handle());
+        } else {
+            data.writeInt32(false);
+        }
+        if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
+            result = reply.readInt32();
+        }
+        return result;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
@@ -263,6 +281,16 @@
             reply->writeInt32(res);
             return NO_ERROR;
         } break;
+        case SET_SIDEBAND_STREAM: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            sp<NativeHandle> stream;
+            if (data.readInt32()) {
+                stream = NativeHandle::create(data.readNativeHandle());
+            }
+            status_t result = setSidebandStream(stream);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
     }
     return BBinder::onTransact(code, data, reply, flags);
 }