Support GraphicBuffer::flatten and GraphicBuffer::unflatten with BufferHub

flatten() calls duplicate on BufferHubBuffer object and flattens the
token obtained from duplicate().
unflatten() reconstruct the token, import a BufferHubBuffer object and
reinitialize the GraphicBuffer object using the imported
BufferHubBuffer.

Bug: 73550905
Test: GraphicBuffer_test
Test: cts-tradefed run singleCommand cts -m CtsNativeHardwareTestCases \
--skip-preconditions --skip-device-info

Change-Id: I511dde8902893e593829b81e4d838dc3561fb009
diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp
index c767ce0..a7c248c 100644
--- a/libs/ui/tests/GraphicBuffer_test.cpp
+++ b/libs/ui/tests/GraphicBuffer_test.cpp
@@ -74,4 +74,49 @@
     EXPECT_EQ(gb->getBufferId(), b1_id);
 }
 
+TEST_F(GraphicBufferTest, flattenAndUnflatten) {
+    std::unique_ptr<BufferHubBuffer> b1 =
+            BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
+                                    kTestUsage, /*userMetadataSize=*/0);
+    ASSERT_NE(b1, nullptr);
+    sp<GraphicBuffer> gb1(new GraphicBuffer(std::move(b1)));
+    gb1->setGenerationNumber(42);
+
+    size_t flattenedSize = gb1->getFlattenedSize();
+    EXPECT_EQ(flattenedSize, 48);
+    size_t fdCount = gb1->getFdCount();
+    EXPECT_EQ(fdCount, 0);
+
+    int data[flattenedSize];
+    int fds[0];
+
+    // Make copies of needed items since flatten modifies them.
+    size_t flattenedSizeCopy = flattenedSize;
+    size_t fdCountCopy = fdCount;
+    void* dataStart = data;
+    int* fdsStart = fds;
+    status_t err = gb1->flatten(dataStart, flattenedSizeCopy, fdsStart, fdCountCopy);
+    ASSERT_EQ(err, NO_ERROR);
+    EXPECT_EQ(flattenedSizeCopy, 0);
+    EXPECT_EQ(fdCountCopy, 0);
+
+    size_t unflattenSize = flattenedSize;
+    size_t unflattenFdCount = fdCount;
+    const void* unflattenData = static_cast<const void*>(dataStart);
+    const int* unflattenFdData = static_cast<const int*>(fdsStart);
+
+    GraphicBuffer* gb2 = new GraphicBuffer();
+    err = gb2->unflatten(unflattenData, unflattenSize, unflattenFdData, unflattenFdCount);
+    ASSERT_EQ(err, NO_ERROR);
+    EXPECT_TRUE(gb2->isBufferHubBuffer());
+
+    EXPECT_EQ(gb2->getWidth(), kTestWidth);
+    EXPECT_EQ(gb2->getHeight(), kTestHeight);
+    EXPECT_EQ(static_cast<uint32_t>(gb2->getPixelFormat()), kTestFormat);
+    EXPECT_EQ(gb2->getUsage(), kTestUsage);
+    EXPECT_EQ(gb2->getLayerCount(), kTestLayerCount);
+    EXPECT_EQ(gb1->getBufferId(), gb2->getBufferId());
+    EXPECT_EQ(gb2->getGenerationNumber(), 42);
+}
+
 } // namespace android