libgui: Add dequeue/attach timeout

Adds the ability to specify the timeout when dequeueBuffer or
attachBuffer block due to the lack of a free buffer/slot. By default,
these will block indefinitely (which is signified by a timeout of -1).

When a timeout (other than -1) is specified, non-blocking mode is
disabled and the given timeout will be used instead.

Bug: 25196773
Change-Id: I17fdbeebccb7c8d878703d758ac1209608258e61
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index 5fe5ce0..835593f 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -174,7 +174,10 @@
     virtual uint64_t getNextFrameNumber() const override;
 
     // See IGraphicBufferProducer::setSingleBufferMode
-    virtual status_t setSingleBufferMode(bool singleBufferMode);
+    virtual status_t setSingleBufferMode(bool singleBufferMode) override;
+
+    // See IGraphicBufferProducer::setDequeueTimeout
+    virtual status_t setDequeueTimeout(nsecs_t timeout) override;
 
 private:
     // This is required by the IBinder::DeathRecipient interface
@@ -216,6 +219,10 @@
     int mCurrentCallbackTicket; // Protected by mCallbackMutex
     Condition mCallbackCondition;
 
+    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
+    // slot is not yet available.
+    nsecs_t mDequeueTimeout;
+
 }; // class BufferQueueProducer
 
 } // namespace android
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index d6daca7..8646981 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -177,6 +177,8 @@
     // * WOULD_BLOCK - no buffer is currently available, and blocking is disabled
     //                 since both the producer/consumer are controlled by app
     // * NO_MEMORY - out of memory, cannot allocate the graphics buffer.
+    // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while
+    //               waiting for a buffer to become available.
     //
     // All other negative values are an unknown error returned downstream
     // from the graphics allocator (typically errno).
@@ -248,6 +250,8 @@
     // * WOULD_BLOCK - no buffer slot is currently available, and blocking is
     //                 disabled since both the producer/consumer are
     //                 controlled by the app.
+    // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while
+    //               waiting for a slot to become available.
     virtual status_t attachBuffer(int* outSlot,
             const sp<GraphicBuffer>& buffer) = 0;
 
@@ -518,6 +522,19 @@
     // and returned to all calls to dequeueBuffer and acquireBuffer. This allows
     // the producer and consumer to simultaneously access the same buffer.
     virtual status_t setSingleBufferMode(bool singleBufferMode) = 0;
+
+    // Sets how long dequeueBuffer will wait for a buffer to become available
+    // before returning an error (TIMED_OUT).
+    //
+    // This timeout also affects the attachBuffer call, which will block if
+    // there is not a free slot available into which the attached buffer can be
+    // placed.
+    //
+    // By default, the BufferQueue will wait forever, which is indicated by a
+    // timeout of -1. If set (to a value other than -1), this will disable
+    // non-blocking mode and its corresponding spare buffer (which is used to
+    // ensure a buffer is always available).
+    virtual status_t setDequeueTimeout(nsecs_t timeout) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index bcc3fff..f79210b 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -117,6 +117,9 @@
      * in <system/window.h>. */
     int setScalingMode(int mode);
 
+    // See IGraphicBufferProducer::setDequeueTimeout
+    status_t setDequeueTimeout(nsecs_t timeout);
+
 protected:
     virtual ~Surface();