libgui: Add generation numbers to BufferQueue

This change allows producers to set a generation number on a
BufferQueue. This number will be embedded in any new GraphicBuffers
created in that BufferQueue, and attempts to attach buffers which have
a different generation number will fail.

It also plumbs the setGenerationNumber method through Surface, with the
additional effect that any buffers attached to the Surface after
setting a new generation number will automatically be updated with the
new number (as opposed to failing, as would happen on through IGBP).

Bug: 20923096
Change-Id: I32bf726b035f99c3e5834beaf76afb9f01adcbc2
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index e318484..73d4261 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -383,6 +383,7 @@
                 return NO_INIT;
             }
 
+            graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
             mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
         } // Autolock scope
     }
@@ -498,6 +499,13 @@
     Mutex::Autolock lock(mCore->mMutex);
     mCore->waitWhileAllocatingLocked();
 
+    if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
+        BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
+                "[queue %u]", buffer->getGenerationNumber(),
+                mCore->mGenerationNumber);
+        return BAD_VALUE;
+    }
+
     status_t returnFlags = NO_ERROR;
     int found;
     // TODO: Should we provide an async flag to attachBuffer? It seems
@@ -1072,6 +1080,15 @@
     return NO_ERROR;
 }
 
+status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
+    ATRACE_CALL();
+    BQ_LOGV("setGenerationNumber: %u", generationNumber);
+
+    Mutex::Autolock lock(mCore->mMutex);
+    mCore->mGenerationNumber = generationNumber;
+    return NO_ERROR;
+}
+
 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
     // If we're here, it means that a producer we were connected to died.
     // We're guaranteed that we are still connected to it because we remove