GraphicBuffer: add optional DetachedBufferHandle

Stores a BufferHub handle that can be used to reattach this
GraphicBuffer back into a BufferHub producer/consumer set. In terms of
GraphicBuffer's relationship with BufferHub, there are three different
modes:

1. Legacy mode: GraphicBuffer is not backed by BufferHub and
   mDetachedBufferHandle must be invalid.
2. Detached mode: GraphicBuffer is backed BufferHub, but not part of a
   producer/consumer set. In this mode, mDetachedBufferHandle must be valid.
3. Attached mode: GraphicBuffer is backed BufferHub and it's part of a
   producer/consumer set. In this mode, mDetachedBufferHandle must be
   invalid.

Note that the DetachedBufferHandle is used as a opaque handle for
GraphicBuffer and it's not exposed to VNDK.

Bug: 38137191
Bug: 69982239
Bug: 70046255
Bug: 70912269
Test: GraphicBuffer_test
Change-Id: I4c3a967cb498291aa175312fdadc84edd3b1a8be
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 4ed2aa4..254038b 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -22,6 +22,7 @@
 
 #include <grallocusage/GrallocUsageConversion.h>
 
+#include <ui/DetachedBufferHandle.h>
 #include <ui/Gralloc2.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/GraphicBufferMapper.h>
@@ -486,6 +487,24 @@
     return NO_ERROR;
 }
 
+bool GraphicBuffer::isDetachedBuffer() const {
+    return mDetachedBufferHandle && mDetachedBufferHandle->isValid();
+}
+
+status_t GraphicBuffer::setDetachedBufferHandle(std::unique_ptr<DetachedBufferHandle> channel) {
+    if (isDetachedBuffer()) {
+        ALOGW("setDetachedBuffer: there is already a BufferHub channel associated with this "
+              "GraphicBuffer. Replacing the old one.");
+    }
+
+    mDetachedBufferHandle = std::move(channel);
+    return NO_ERROR;
+}
+
+std::unique_ptr<DetachedBufferHandle> GraphicBuffer::takeDetachedBufferHandle() {
+    return std::move(mDetachedBufferHandle);
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android