Implement BufferHubProducer::attachBuffer

1/ Introduce new kOpProducerQueueInsertBuffer operation to insert a
   standalone ProducerChannel into a ProducerQueueChannel.
2/ Introduce some PDX security check against channel_id spoofing.

Bug: 69981968
Bug: 79224574
Test: buffer_hub_queue-test, libgui_test
Change-Id: I3c13e2897476c34e6e939756b079fe3440937236
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index e5a4adb..c20e8fc 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -787,10 +787,31 @@
 
     ASSERT_OK(mProducer->disconnect(TEST_API));
 
-    if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
-        // TODO(b/69981968): Implement BufferHubProducer::attachBuffer
-        ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
+    ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
+}
+
+TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) {
+    int slot = -1;
+    sp<Fence> fence;
+    sp<GraphicBuffer> buffer;
+
+    setupDequeueRequestBuffer(&slot, &fence, &buffer);
+    ASSERT_TRUE(buffer != nullptr);
+
+    ASSERT_OK(mProducer->detachBuffer(slot));
+    EXPECT_OK(buffer->initCheck());
+
+    if (GetParam() == USE_BUFFER_HUB_PRODUCER) {
+        // For a GraphicBuffer backed by BufferHub, once detached from an IGBP, it should have
+        // isDetachedBuffer() set. Note that this only applies to BufferHub.
+        EXPECT_TRUE(buffer->isDetachedBuffer());
+    } else {
+        EXPECT_FALSE(buffer->isDetachedBuffer());
     }
+
+    EXPECT_OK(mProducer->attachBuffer(&slot, buffer));
+    EXPECT_FALSE(buffer->isDetachedBuffer());
+    EXPECT_OK(buffer->initCheck());
 }
 
 #if USE_BUFFER_HUB_AS_BUFFER_QUEUE