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/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 4f87824..cf0043d 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -177,4 +177,37 @@
     ASSERT_EQ(TEST_DATASPACE, dataSpace);
 }
 
+TEST_F(SurfaceTest, SettingGenerationNumber) {
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
+    sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
+    sp<Surface> surface = new Surface(producer);
+    sp<ANativeWindow> window(surface);
+
+    // Allocate a buffer with a generation number of 0
+    ANativeWindowBuffer* buffer;
+    int fenceFd;
+    ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fenceFd));
+    ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fenceFd));
+
+    // Detach the buffer and check its generation number
+    sp<GraphicBuffer> graphicBuffer;
+    sp<Fence> fence;
+    ASSERT_EQ(NO_ERROR, surface->detachNextBuffer(&graphicBuffer, &fence));
+    ASSERT_EQ(0U, graphicBuffer->getGenerationNumber());
+
+    ASSERT_EQ(NO_ERROR, surface->setGenerationNumber(1));
+    buffer = static_cast<ANativeWindowBuffer*>(graphicBuffer.get());
+
+    // This should change the generation number of the GraphicBuffer
+    ASSERT_EQ(NO_ERROR, surface->attachBuffer(buffer));
+
+    // Check that the new generation number sticks with the buffer
+    ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, -1));
+    ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fenceFd));
+    graphicBuffer = static_cast<GraphicBuffer*>(buffer);
+    ASSERT_EQ(1U, graphicBuffer->getGenerationNumber());
+}
+
 }