bufferhubd: Implement more DetachedBuffer logic

1/ Separate DetachedBuffer related logic into a dedicated subclass of
   BufferHubRPC. This actually is the right thing to do as it utilizes
   the PDX's client/service programming pattern better.
2/ Add IsValid() check for the DetachedBufferChannel object.
3/ Add BufferHubClient to handle general PDX operations.
4/ Add DetachedBuffer which composites a BufferHubClient.
5/ Fully functional logic of allocating a DetachedBuffer, converting it
   to a BufferHub-backed GraphicBuffer, then converting it back to a
   DetachedBuffer.

Bug: 38137191
Bug: 70046255
Bug: 70912269
Test: buffer_hub-test
Change-Id: I81bf9259cbbaeb29a6df2769363b5a03464e7864
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index c38c12b..a753168 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -377,11 +377,17 @@
     return ErrorStatus(-ret);
   };
 
-  auto channel = std::make_shared<DetachedBufferChannel>(
-      service(), buffer_id(), channel_id, std::move(buffer_),
-      std::move(metadata_buffer_), user_metadata_size_);
+  std::unique_ptr<DetachedBufferChannel> channel =
+      DetachedBufferChannel::Create(
+          service(), buffer_id(), channel_id, std::move(buffer_),
+          std::move(metadata_buffer_), user_metadata_size_);
+  if (!channel) {
+    ALOGE("ProducerChannel::OnProducerDetach: Invalid buffer.");
+    return ErrorStatus(EINVAL);
+  }
 
-  const auto channel_status = service()->SetChannel(channel_id, channel);
+  const auto channel_status =
+      service()->SetChannel(channel_id, std::move(channel));
   if (!channel_status) {
     // Technically, this should never fail, as we just pushed the channel. Note
     // that LOG_FATAL will be stripped out in non-debug build.