Implement allocateBuffer for BufferHubService

Return ALLOCATION_FAILED when failed to create BufferNode, NO_ERROR on
success.

Allocation and memory management logics are in BufferNode, and enforced
via the shared_ptr and clientList. Memcpy is used to convert between
AHardwareBuffer_Desc and HardwareBufferDescription (i.e. hidl_vec).

Test: BufferHubBuffer_test (passed)
Change-Id: I5e17aa7330c5f94656e62dc4bea8ab6c705ab7a4
Fix: 118614333
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index 86598e0..b72b556 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
+#include <android/hardware_buffer.h>
 #include <bufferhub/BufferHubService.h>
+#include <log/log.h>
 
 namespace android {
 namespace frameworks {
@@ -24,11 +26,27 @@
 
 using hardware::Void;
 
-Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& /*description*/,
-                                              const uint32_t /*userMetadataSize*/,
+Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& description,
+                                              const uint32_t userMetadataSize,
                                               allocateBuffer_cb _hidl_cb) {
-    // TODO(b/118614333): implement buffer allocation
-    _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::NO_ERROR);
+    AHardwareBuffer_Desc desc;
+    memcpy(&desc, &description, sizeof(AHardwareBuffer_Desc));
+
+    std::shared_ptr<BufferNode> node =
+            std::make_shared<BufferNode>(desc.width, desc.height, desc.layers, desc.format,
+                                         desc.usage, userMetadataSize);
+    if (node == nullptr || !node->IsValid()) {
+        ALOGE("%s: creating BufferNode failed.", __FUNCTION__);
+        _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::ALLOCATION_FAILED);
+        return Void();
+    }
+
+    sp<BufferClient> client = new BufferClient(node);
+    // Add it to list for bookkeeping and dumpsys.
+    std::lock_guard<std::mutex> lock(mClientListMutex);
+    mClientList.push_back(client);
+
+    _hidl_cb(/*bufferClient=*/client, /*status=*/BufferHubStatus::NO_ERROR);
     return Void();
 }