Implement duplicate buffer

Allow BufferClient to generate a opaque token in hidl_handle (i.e.
native_handle_t) format that could be used for IBufferHub::import.

The service will keep a mapping from token to client. Token comparison
is handled in BufferHubService.cpp, as it's opaque to the users.

Test: BufferHubBuffer_test (passed)
Bug: 118614157
Change-Id: Ie2b0b650dba90fe2ed2f8091dd88acb9768f261f
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index b72b556..3bfd9cb 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -16,6 +16,7 @@
 
 #include <android/hardware_buffer.h>
 #include <bufferhub/BufferHubService.h>
+#include <cutils/native_handle.h>
 #include <log/log.h>
 
 namespace android {
@@ -41,7 +42,7 @@
         return Void();
     }
 
-    sp<BufferClient> client = new BufferClient(node);
+    sp<BufferClient> client = BufferClient::create(this, node);
     // Add it to list for bookkeeping and dumpsys.
     std::lock_guard<std::mutex> lock(mClientListMutex);
     mClientList.push_back(client);
@@ -57,6 +58,25 @@
     return Void();
 }
 
+hidl_handle BufferHubService::registerToken(const BufferClient* client) {
+    uint32_t token;
+    std::lock_guard<std::mutex> lock(mTokenMapMutex);
+    do {
+        token = mTokenEngine();
+    } while (mTokenMap.find(token) != mTokenMap.end());
+
+    // native_handle_t use int[], so here need one slots to fit in uint32_t
+    native_handle_t* handle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
+    handle->data[0] = token;
+
+    // returnToken owns the native_handle_t* thus doing lifecycle management
+    hidl_handle returnToken;
+    returnToken.setTo(handle, /*shoudOwn=*/true);
+
+    mTokenMap.emplace(token, client);
+    return returnToken;
+}
+
 } // namespace implementation
 } // namespace V1_0
 } // namespace bufferhub