fuchsia: Replace FIDL C++ bindings with LLCPP.

Previously goldfish ICD uses FIDL C++ bindings which
has dependency on the default async dispatcher and
caused some binary dependency issues. This change
migrates all usages of C++ bindings to LLCPP to
eliminate that dependency.

Bug: fxbug.dev/56565
Bug: fxbug.dev/55650

TEST=gfx_unittests, escher_tests on Fuchsia

Change-Id: I0815e210b1630ce2ea9fd32222ddb4a32bbf8644
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index cdb34ee..e217606 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -46,8 +46,8 @@
 #ifdef VK_USE_PLATFORM_FUCHSIA
 
 #include <cutils/native_handle.h>
-#include <fuchsia/hardware/goldfish/cpp/fidl.h>
-#include <fuchsia/sysmem/cpp/fidl.h>
+#include <fuchsia/hardware/goldfish/llcpp/fidl.h>
+#include <fuchsia/sysmem/llcpp/fidl.h>
 #include <lib/zx/channel.h>
 #include <lib/zx/vmo.h>
 #include <zircon/process.h>
@@ -56,6 +56,9 @@
 
 #include "services/service_connector.h"
 
+#define GET_STATUS_SAFE(result, member) \
+    ((result).ok() ? ((result).Unwrap()->member) : ZX_OK)
+
 struct AHardwareBuffer;
 
 void AHardwareBuffer_release(AHardwareBuffer*) { }
@@ -811,13 +814,17 @@
                 ALOGE("failed to open control device");
                 abort();
             }
-            mControlDevice.Bind(std::move(channel));
+            mControlDevice = std::make_unique<
+                llcpp::fuchsia::hardware::goldfish::ControlDevice::SyncClient>(
+                std::move(channel));
 
             zx::channel sysmem_channel(GetConnectToServiceFunction()("/svc/fuchsia.sysmem.Allocator"));
             if (!sysmem_channel) {
                 ALOGE("failed to open sysmem connection");
             }
-            mSysmemAllocator.Bind(std::move(sysmem_channel));
+            mSysmemAllocator =
+                std::make_unique<llcpp::fuchsia::sysmem::Allocator::SyncClient>(
+                    std::move(sysmem_channel));
         }
 #endif
 
@@ -1676,24 +1683,47 @@
         const VkBufferCollectionCreateInfoFUCHSIA* pInfo,
         const VkAllocationCallbacks*,
         VkBufferCollectionFUCHSIA* pCollection) {
-        fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
+        zx::channel token_client;
+
         if (pInfo->collectionToken) {
-            token.Bind(zx::channel(pInfo->collectionToken));
+            token_client = zx::channel(pInfo->collectionToken);
         } else {
-            zx_status_t status = mSysmemAllocator->AllocateSharedCollection(token.NewRequest());
+            zx::channel token_server;
+            zx_status_t status =
+                zx::channel::create(0, &token_server, &token_client);
             if (status != ZX_OK) {
-                ALOGE("AllocateSharedCollection failed: %d", status);
+                ALOGE("zx_channel_create failed: %d", status);
+                return VK_ERROR_INITIALIZATION_FAILED;
+            }
+
+            auto result = mSysmemAllocator->AllocateSharedCollection(
+                std::move(token_server));
+            if (!result.ok()) {
+                ALOGE("AllocateSharedCollection failed: %d", result.status());
                 return VK_ERROR_INITIALIZATION_FAILED;
             }
         }
-        auto sysmem_collection = new fuchsia::sysmem::BufferCollectionSyncPtr;
-        zx_status_t status = mSysmemAllocator->BindSharedCollection(
-            std::move(token), sysmem_collection->NewRequest());
+
+        zx::channel collection_client, collection_server;
+        zx_status_t status =
+            zx::channel::create(0, &collection_client, &collection_server);
         if (status != ZX_OK) {
-            ALOGE("BindSharedCollection failed: %d", status);
+            ALOGE("zx_channel_create failed: %d", status);
             return VK_ERROR_INITIALIZATION_FAILED;
         }
+
+        auto result = mSysmemAllocator->BindSharedCollection(
+            std::move(token_client), std::move(collection_server));
+        if (!result.ok()) {
+            ALOGE("BindSharedCollection failed: %d", result.status());
+            return VK_ERROR_INITIALIZATION_FAILED;
+        }
+
+        auto sysmem_collection =
+            new llcpp::fuchsia::sysmem::BufferCollection::SyncClient(
+                std::move(collection_client));
         *pCollection = reinterpret_cast<VkBufferCollectionFUCHSIA>(sysmem_collection);
+
         return VK_SUCCESS;
     }
 
@@ -1701,20 +1731,21 @@
         void*, VkResult, VkDevice,
         VkBufferCollectionFUCHSIA collection,
         const VkAllocationCallbacks*) {
-        auto sysmem_collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
-        if (sysmem_collection->is_bound()) {
-            (*sysmem_collection)->Close();
+        auto sysmem_collection = reinterpret_cast<
+            llcpp::fuchsia::sysmem::BufferCollection::SyncClient*>(collection);
+        if (sysmem_collection) {
+            sysmem_collection->Close();
         }
         delete sysmem_collection;
     }
 
-    inline fuchsia::sysmem::BufferCollectionConstraints
+    inline llcpp::fuchsia::sysmem::BufferCollectionConstraints
     defaultBufferCollectionConstraints(size_t min_size_bytes,
                                        size_t buffer_count) {
-        fuchsia::sysmem::BufferCollectionConstraints constraints = {};
+        llcpp::fuchsia::sysmem::BufferCollectionConstraints constraints = {};
         constraints.min_buffer_count = buffer_count;
         constraints.has_buffer_memory_constraints = true;
-        fuchsia::sysmem::BufferMemoryConstraints& buffer_constraints =
+        llcpp::fuchsia::sysmem::BufferMemoryConstraints& buffer_constraints =
             constraints.buffer_memory_constraints;
 
         buffer_constraints.min_size_bytes = min_size_bytes;
@@ -1726,7 +1757,7 @@
         buffer_constraints.inaccessible_domain_supported = true;
         buffer_constraints.heap_permitted_count = 1;
         buffer_constraints.heap_permitted[0] =
-            fuchsia::sysmem::HeapType::GOLDFISH_DEVICE_LOCAL;
+            llcpp::fuchsia::sysmem::HeapType::GOLDFISH_DEVICE_LOCAL;
 
         return constraints;
     }
@@ -1736,9 +1767,9 @@
         uint32_t usage = 0u;
         VkImageUsageFlags imageUsage = pImageInfo->usage;
 
-#define SetUsageBit(USAGE)                                    \
-    if (imageUsage & VK_IMAGE_USAGE_##USAGE##_BIT) {          \
-        usage |= fuchsia::sysmem::VULKAN_IMAGE_USAGE_##USAGE; \
+#define SetUsageBit(USAGE)                                           \
+    if (imageUsage & VK_IMAGE_USAGE_##USAGE##_BIT) {                 \
+        usage |= llcpp::fuchsia::sysmem::VULKAN_IMAGE_USAGE_##USAGE; \
     }
 
         SetUsageBit(COLOR_ATTACHMENT);
@@ -1756,9 +1787,9 @@
         VkBufferUsageFlags bufferUsage =
             pBufferConstraintsInfo->pBufferCreateInfo->usage;
 
-#define SetUsageBit(USAGE)                                     \
-    if (bufferUsage & VK_BUFFER_USAGE_##USAGE##_BIT) {         \
-        usage |= fuchsia::sysmem::VULKAN_BUFFER_USAGE_##USAGE; \
+#define SetUsageBit(USAGE)                                            \
+    if (bufferUsage & VK_BUFFER_USAGE_##USAGE##_BIT) {                \
+        usage |= llcpp::fuchsia::sysmem::VULKAN_BUFFER_USAGE_##USAGE; \
     }
 
         SetUsageBit(TRANSFER_SRC);
@@ -1776,7 +1807,7 @@
     }
 
     VkResult setBufferCollectionConstraints(
-        fuchsia::sysmem::BufferCollectionSyncPtr* collection,
+        llcpp::fuchsia::sysmem::BufferCollection::SyncClient* collection,
         const VkImageCreateInfo* pImageInfo) {
         if (pImageInfo == nullptr) {
             ALOGE("setBufferCollectionConstraints: pImageInfo cannot be null.");
@@ -1785,7 +1816,7 @@
 
         // TODO(liyl): Currently the size only works for RGBA8 and BGRA8 images.
         // We should set the size based on its actual format.
-        fuchsia::sysmem::BufferCollectionConstraints constraints =
+        llcpp::fuchsia::sysmem::BufferCollectionConstraints constraints =
             defaultBufferCollectionConstraints(
                 /* min_size_bytes */ pImageInfo->extent.width *
                     pImageInfo->extent.height * 4,
@@ -1809,7 +1840,8 @@
             constraints.image_format_constraints_count = formats.size();
             uint32_t format_index = 0;
             for (VkFormat format : formats) {
-                fuchsia::sysmem::ImageFormatConstraints& image_constraints =
+                llcpp::fuchsia::sysmem::ImageFormatConstraints&
+                    image_constraints =
                         constraints.image_format_constraints[format_index++];
                 switch (format) {
                     case VK_FORMAT_B8G8R8A8_SINT:
@@ -1819,7 +1851,7 @@
                     case VK_FORMAT_B8G8R8A8_SSCALED:
                     case VK_FORMAT_B8G8R8A8_USCALED:
                         image_constraints.pixel_format.type =
-                                fuchsia::sysmem::PixelFormatType::BGRA32;
+                            llcpp::fuchsia::sysmem::PixelFormatType::BGRA32;
                         break;
                     case VK_FORMAT_R8G8B8A8_SINT:
                     case VK_FORMAT_R8G8B8A8_UNORM:
@@ -1828,14 +1860,14 @@
                     case VK_FORMAT_R8G8B8A8_SSCALED:
                     case VK_FORMAT_R8G8B8A8_USCALED:
                         image_constraints.pixel_format.type =
-                                fuchsia::sysmem::PixelFormatType::R8G8B8A8;
+                            llcpp::fuchsia::sysmem::PixelFormatType::R8G8B8A8;
                         break;
                     default:
                         return VK_ERROR_FORMAT_NOT_SUPPORTED;
                 }
                 image_constraints.color_spaces_count = 1;
                 image_constraints.color_space[0].type =
-                        fuchsia::sysmem::ColorSpaceType::SRGB;
+                    llcpp::fuchsia::sysmem::ColorSpaceType::SRGB;
                 image_constraints.min_coded_width = pImageInfo->extent.width;
                 image_constraints.max_coded_width = 0xfffffff;
                 image_constraints.min_coded_height = pImageInfo->extent.height;
@@ -1855,12 +1887,17 @@
             }
         }
 
-        (*collection)->SetConstraints(true, constraints);
+        auto result = collection->SetConstraints(true, std::move(constraints));
+        if (!result.ok()) {
+            ALOGE("setBufferCollectionConstraints: SetConstraints failed: %d",
+                  result.status());
+            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+        }
         return VK_SUCCESS;
     }
 
     VkResult setBufferCollectionBufferConstraints(
-        fuchsia::sysmem::BufferCollectionSyncPtr* collection,
+        llcpp::fuchsia::sysmem::BufferCollection::SyncClient* collection,
         const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
         if (pBufferConstraintsInfo == nullptr) {
             ALOGE(
@@ -1869,7 +1906,7 @@
             return VK_ERROR_OUT_OF_DEVICE_MEMORY;
         }
 
-        fuchsia::sysmem::BufferCollectionConstraints constraints =
+        llcpp::fuchsia::sysmem::BufferCollectionConstraints constraints =
             defaultBufferCollectionConstraints(
                 /* min_size_bytes */ pBufferConstraintsInfo->pBufferCreateInfo
                     ->size,
@@ -1878,7 +1915,12 @@
             getBufferCollectionConstraintsVulkanBufferUsage(
                 pBufferConstraintsInfo);
 
-        (*collection)->SetConstraints(true, constraints);
+        auto result = collection->SetConstraints(true, std::move(constraints));
+        if (!result.ok()) {
+            ALOGE("setBufferCollectionConstraints: SetConstraints failed: %d",
+                  result.status());
+            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+        }
         return VK_SUCCESS;
     }
 
@@ -1886,8 +1928,8 @@
         void*, VkResult, VkDevice,
         VkBufferCollectionFUCHSIA collection,
         const VkImageCreateInfo* pImageInfo) {
-        auto sysmem_collection =
-            reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
+        auto sysmem_collection = reinterpret_cast<
+            llcpp::fuchsia::sysmem::BufferCollection::SyncClient*>(collection);
         return setBufferCollectionConstraints(sysmem_collection, pImageInfo);
     }
 
@@ -1897,9 +1939,8 @@
         VkDevice,
         VkBufferCollectionFUCHSIA collection,
         const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
-        auto sysmem_collection =
-            reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
-                collection);
+        auto sysmem_collection = reinterpret_cast<
+            llcpp::fuchsia::sysmem::BufferCollection::SyncClient*>(collection);
         return setBufferCollectionBufferConstraints(sysmem_collection,
                                                     pBufferConstraintsInfo);
     }
@@ -1909,14 +1950,18 @@
         VkDevice device,
         VkBufferCollectionFUCHSIA collection,
         VkBufferCollectionPropertiesFUCHSIA* pProperties) {
-        auto sysmem_collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
-        fuchsia::sysmem::BufferCollectionInfo_2 info;
-        zx_status_t status2;
-        zx_status_t status = (*sysmem_collection)->WaitForBuffersAllocated(&status2, &info);
-        if (status != ZX_OK || status2 != ZX_OK) {
-            ALOGE("Failed wait for allocation: %d %d", status, status2);
+        auto sysmem_collection = reinterpret_cast<
+            llcpp::fuchsia::sysmem::BufferCollection::SyncClient*>(collection);
+
+        auto result = sysmem_collection->WaitForBuffersAllocated();
+        if (!result.ok() || result.Unwrap()->status != ZX_OK) {
+            ALOGE("Failed wait for allocation: %d %d", result.status(),
+                  GET_STATUS_SAFE(result, status));
             return VK_ERROR_INITIALIZATION_FAILED;
         }
+        llcpp::fuchsia::sysmem::BufferCollectionInfo_2 info =
+            std::move(result.Unwrap()->buffer_collection_info);
+
         if (!info.settings.has_image_format_constraints) {
             return VK_ERROR_INITIALIZATION_FAILED;
         }
@@ -2298,15 +2343,17 @@
         if (importBufferCollection) {
 
 #ifdef VK_USE_PLATFORM_FUCHSIA
-            auto collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
+            auto collection = reinterpret_cast<
+                llcpp::fuchsia::sysmem::BufferCollection::SyncClient*>(
                 importBufferCollectionInfoPtr->collection);
-            fuchsia::sysmem::BufferCollectionInfo_2 info;
-            zx_status_t status2;
-            zx_status_t status = (*collection)->WaitForBuffersAllocated(&status2, &info);
-            if (status != ZX_OK || status2 != ZX_OK) {
-                ALOGE("WaitForBuffersAllocated failed: %d %d", status);
+            auto result = collection->WaitForBuffersAllocated();
+            if (!result.ok() || result.Unwrap()->status != ZX_OK) {
+                ALOGE("WaitForBuffersAllocated failed: %d %d", result.status(),
+                      GET_STATUS_SAFE(result, status));
                 return VK_ERROR_INITIALIZATION_FAILED;
             }
+            llcpp::fuchsia::sysmem::BufferCollectionInfo_2& info =
+                result.Unwrap()->buffer_collection_info;
             uint32_t index = importBufferCollectionInfoPtr->index;
             if (info.buffer_count < index) {
                 ALOGE("Invalid buffer index: %d %d", index);
@@ -2381,22 +2428,44 @@
                     pBufferConstraintsInfo);
 
             if (hasDedicatedImage || hasDedicatedBuffer) {
-                fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
-                zx_status_t status = mSysmemAllocator->AllocateSharedCollection(
-                    token.NewRequest());
+                zx::channel token_server, token_client;
+                zx_status_t status =
+                    zx::channel::create(0, &token_server, &token_client);
                 if (status != ZX_OK) {
-                    ALOGE("AllocateSharedCollection failed: %d", status);
+                    ALOGE("zx_channel_create failed: %d", status);
                     abort();
                 }
 
-                fuchsia::sysmem::BufferCollectionSyncPtr collection;
-                status = mSysmemAllocator->BindSharedCollection(
-                    std::move(token), collection.NewRequest());
+                {
+                    auto result = mSysmemAllocator->AllocateSharedCollection(
+                        std::move(token_server));
+                    if (!result.ok()) {
+                        ALOGE("AllocateSharedCollection failed: %d",
+                              result.status());
+                        abort();
+                    }
+                }
+
+                zx::channel collection_server, collection_client;
+                status = zx::channel::create(0, &collection_server,
+                                             &collection_client);
                 if (status != ZX_OK) {
-                    ALOGE("BindSharedCollection failed: %d", status);
+                    ALOGE("zx_channel_create failed: %d", status);
                     abort();
                 }
 
+                {
+                    auto result = mSysmemAllocator->BindSharedCollection(
+                        std::move(token_client), std::move(collection_server));
+                    if (!result.ok()) {
+                        ALOGE("BindSharedCollection failed: %d",
+                              result.status());
+                        abort();
+                    }
+                }
+
+                llcpp::fuchsia::sysmem::BufferCollection::SyncClient collection(
+                    std::move(collection_client));
                 if (hasDedicatedImage) {
                     VkResult res = setBufferCollectionConstraints(
                         &collection, pImageCreateInfo);
@@ -2416,25 +2485,30 @@
                     }
                 }
 
-                fuchsia::sysmem::BufferCollectionInfo_2 info;
-                zx_status_t status2;
-                status = collection->WaitForBuffersAllocated(&status2, &info);
-                if (status == ZX_OK && status2 == ZX_OK) {
-                    if (!info.buffer_count) {
-                      ALOGE("WaitForBuffersAllocated returned invalid count: %d", status);
-                      abort();
+                {
+                    auto result = collection.WaitForBuffersAllocated();
+                    if (result.ok() && result.Unwrap()->status == ZX_OK) {
+                        llcpp::fuchsia::sysmem::BufferCollectionInfo_2& info =
+                            result.Unwrap()->buffer_collection_info;
+                        if (!info.buffer_count) {
+                            ALOGE(
+                                "WaitForBuffersAllocated returned "
+                                "invalid count: %d",
+                                info.buffer_count);
+                            abort();
+                        }
+                        vmo_handle = info.buffers[0].vmo.release();
+                    } else {
+                        ALOGE("WaitForBuffersAllocated failed: %d %d",
+                              result.status(), GET_STATUS_SAFE(result, status));
+                        abort();
                     }
-                    vmo_handle = info.buffers[0].vmo.release();
-                } else {
-                    ALOGE("WaitForBuffersAllocated failed: %d %d", status, status2);
-                    abort();
                 }
 
-                collection->Close();
+                collection.Close();
 
                 zx::vmo vmo_copy;
-                status = zx_handle_duplicate(vmo_handle,
-                                             ZX_RIGHT_SAME_RIGHTS,
+                status = zx_handle_duplicate(vmo_handle, ZX_RIGHT_SAME_RIGHTS,
                                              vmo_copy.reset_and_get_address());
                 if (status != ZX_OK) {
                     ALOGE("Failed to duplicate VMO: %d", status);
@@ -2442,7 +2516,8 @@
                 }
 
                 if (pImageCreateInfo) {
-                    fuchsia::hardware::goldfish::ColorBufferFormatType format;
+                    llcpp::fuchsia::hardware::goldfish::ColorBufferFormatType
+                        format;
                     switch (pImageCreateInfo->format) {
                         case VK_FORMAT_B8G8R8A8_SINT:
                         case VK_FORMAT_B8G8R8A8_UNORM:
@@ -2450,7 +2525,7 @@
                         case VK_FORMAT_B8G8R8A8_SNORM:
                         case VK_FORMAT_B8G8R8A8_SSCALED:
                         case VK_FORMAT_B8G8R8A8_USCALED:
-                            format = fuchsia::hardware::goldfish::
+                            format = llcpp::fuchsia::hardware::goldfish::
                                 ColorBufferFormatType::BGRA;
                             break;
                         case VK_FORMAT_R8G8B8A8_SINT:
@@ -2459,7 +2534,7 @@
                         case VK_FORMAT_R8G8B8A8_SNORM:
                         case VK_FORMAT_R8G8B8A8_SSCALED:
                         case VK_FORMAT_R8G8B8A8_USCALED:
-                            format = fuchsia::hardware::goldfish::
+                            format = llcpp::fuchsia::hardware::goldfish::
                                 ColorBufferFormatType::RGBA;
                             break;
                         default:
@@ -2468,23 +2543,23 @@
                             abort();
                     }
 
-                    status = mControlDevice->CreateColorBuffer(
+                    auto result = mControlDevice->CreateColorBuffer(
                         std::move(vmo_copy), pImageCreateInfo->extent.width,
-                        pImageCreateInfo->extent.height, format, &status2);
-                    if (status != ZX_OK || status2 != ZX_OK) {
-                        ALOGE("CreateColorBuffer failed: %d:%d", status,
-                              status2);
+                        pImageCreateInfo->extent.height, format);
+                    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+                        ALOGE("CreateColorBuffer failed: %d:%d",
+                              result.status(), GET_STATUS_SAFE(result, res));
                         abort();
                     }
                 }
 
                 if (pBufferConstraintsInfo) {
-                    status = mControlDevice->CreateBuffer(
+                    auto result = mControlDevice->CreateBuffer(
                         std::move(vmo_copy),
-                        pBufferConstraintsInfo->pBufferCreateInfo->size,
-                        &status2);
-                    if (status != ZX_OK || status2 != ZX_OK) {
-                        ALOGE("CreateBuffer failed: %d:%d", status, status2);
+                        pBufferConstraintsInfo->pBufferCreateInfo->size);
+                    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+                        ALOGE("CreateBuffer failed: %d:%d", result.status(),
+                              GET_STATUS_SAFE(result, res));
                         abort();
                     }
                 }
@@ -2502,23 +2577,23 @@
             }
             zx_status_t status2 = ZX_OK;
 
-            fuchsia::hardware::goldfish::BufferHandleType handle_type;
-            uint32_t buffer_handle;
-
-            status = mControlDevice->GetBufferHandle(std::move(vmo_copy),
-                                                     &status2, &buffer_handle,
-                                                     &handle_type);
-            if (status != ZX_OK || status2 != ZX_OK) {
-                ALOGE("GetBufferHandle failed: %d:%d", status, status2);
-            }
-
-            if (handle_type ==
-                fuchsia::hardware::goldfish::BufferHandleType::BUFFER) {
-                importBufferInfo.buffer = buffer_handle;
-                vk_append_struct(&structChainIter, &importBufferInfo);
+            auto result = mControlDevice->GetBufferHandle(std::move(vmo_copy));
+            if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+                ALOGE("GetBufferHandle failed: %d:%d", result.status(),
+                      GET_STATUS_SAFE(result, res));
             } else {
-                importCbInfo.colorBuffer = buffer_handle;
-                vk_append_struct(&structChainIter, &importCbInfo);
+                llcpp::fuchsia::hardware::goldfish::BufferHandleType
+                    handle_type = result.Unwrap()->type;
+                uint32_t buffer_handle = result.Unwrap()->id;
+
+                if (handle_type == llcpp::fuchsia::hardware::goldfish::
+                                       BufferHandleType::BUFFER) {
+                    importBufferInfo.buffer = buffer_handle;
+                    vk_append_struct(&structChainIter, &importBufferInfo);
+                } else {
+                    importCbInfo.colorBuffer = buffer_handle;
+                    vk_append_struct(&structChainIter, &importCbInfo);
+                }
             }
         }
 #endif
@@ -2901,34 +2976,39 @@
         }
 
         if (extBufferCollectionPtr) {
-            auto collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
+            auto collection = reinterpret_cast<
+                llcpp::fuchsia::sysmem::BufferCollection::SyncClient*>(
                 extBufferCollectionPtr->collection);
             uint32_t index = extBufferCollectionPtr->index;
             zx::vmo vmo;
 
-            fuchsia::sysmem::BufferCollectionInfo_2 info;
-            zx_status_t status2;
-            zx_status_t status = (*collection)->WaitForBuffersAllocated(&status2, &info);
-            if (status == ZX_OK && status2 == ZX_OK) {
+            llcpp::fuchsia::sysmem::BufferCollectionInfo_2 info;
+
+            auto result = collection->WaitForBuffersAllocated();
+            if (result.ok() && result.Unwrap()->status == ZX_OK) {
+                info = std::move(result.Unwrap()->buffer_collection_info);
                 if (index < info.buffer_count && info.settings.has_image_format_constraints) {
                     vmo = std::move(info.buffers[index].vmo);
                 }
             } else {
-                ALOGE("WaitForBuffersAllocated failed: %d %d", status, status2);
+                ALOGE("WaitForBuffersAllocated failed: %d %d", result.status(),
+                      GET_STATUS_SAFE(result, status));
             }
 
             if (vmo.is_valid()) {
-                zx_status_t status2 = ZX_OK;
-                status = mControlDevice->CreateColorBuffer(
+                auto result = mControlDevice->CreateColorBuffer(
                     std::move(vmo),
                     info.settings.image_format_constraints.min_coded_width,
                     info.settings.image_format_constraints.min_coded_height,
-                    info.settings.image_format_constraints.pixel_format.type == fuchsia::sysmem::PixelFormatType::R8G8B8A8
-                        ? fuchsia::hardware::goldfish::ColorBufferFormatType::RGBA
-                        : fuchsia::hardware::goldfish::ColorBufferFormatType::BGRA,
-                    &status2);
-                if (status != ZX_OK || (status2 != ZX_OK && status2 != ZX_ERR_ALREADY_EXISTS)) {
-                    ALOGE("CreateColorBuffer failed: %d:%d", status, status2);
+                    info.settings.image_format_constraints.pixel_format.type ==
+                            llcpp::fuchsia::sysmem::PixelFormatType::R8G8B8A8
+                        ? llcpp::fuchsia::hardware::goldfish::
+                              ColorBufferFormatType::RGBA
+                        : llcpp::fuchsia::hardware::goldfish::
+                              ColorBufferFormatType::BGRA);
+                if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+                    ALOGE("CreateColorBuffer failed: %d:%d", result.status(),
+                          GET_STATUS_SAFE(result, res));
                 }
             }
             isSysmemBackedMemory = true;
@@ -3753,32 +3833,31 @@
                         pCreateInfo);
 
         if (extBufferCollectionPtr) {
-            auto collection =
-                    reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
-                            extBufferCollectionPtr->collection);
+            auto collection = reinterpret_cast<
+                llcpp::fuchsia::sysmem::BufferCollection::SyncClient*>(
+                extBufferCollectionPtr->collection);
             uint32_t index = extBufferCollectionPtr->index;
 
-            fuchsia::sysmem::BufferCollectionInfo_2 info;
-            zx_status_t status2;
-            zx_status_t status =
-                    (*collection)->WaitForBuffersAllocated(&status2, &info);
-
-            if (status == ZX_OK && status2 == ZX_OK) {
+            auto result = collection->WaitForBuffersAllocated();
+            if (result.ok() && result.Unwrap()->status == ZX_OK) {
+                auto& info = result.Unwrap()->buffer_collection_info;
                 if (index < info.buffer_count) {
                     vmo = android::base::makeOptional(
                             std::move(info.buffers[index].vmo));
                 }
             } else {
-                ALOGE("WaitForBuffersAllocated failed: %d %d", status, status2);
+                ALOGE("WaitForBuffersAllocated failed: %d %d", result.status(),
+                      GET_STATUS_SAFE(result, status));
             }
 
             if (vmo && vmo->is_valid()) {
-                zx_status_t status2 = ZX_OK;
-                status = mControlDevice->CreateBuffer(
-                        std::move(*vmo), pCreateInfo->size, &status2);
-                if (status != ZX_OK ||
-                    (status2 != ZX_OK && status2 != ZX_ERR_ALREADY_EXISTS)) {
-                    ALOGE("CreateBuffer failed: %d:%d", status, status2);
+                auto result = mControlDevice->CreateBuffer(std::move(*vmo),
+                                                           pCreateInfo->size);
+                if (!result.ok() ||
+                    (result.Unwrap()->res != ZX_OK &&
+                     result.Unwrap()->res != ZX_ERR_ALREADY_EXISTS)) {
+                    ALOGE("CreateBuffer failed: %d:%d", result.status(),
+                          GET_STATUS_SAFE(result, res));
                 }
                 isSysmemBackedMemory = true;
             }
@@ -4919,8 +4998,11 @@
 #endif
 
 #ifdef VK_USE_PLATFORM_FUCHSIA
-    fuchsia::hardware::goldfish::ControlDeviceSyncPtr mControlDevice;
-    fuchsia::sysmem::AllocatorSyncPtr mSysmemAllocator;
+    std::unique_ptr<
+        llcpp::fuchsia::hardware::goldfish::ControlDevice::SyncClient>
+        mControlDevice;
+    std::unique_ptr<llcpp::fuchsia::sysmem::Allocator::SyncClient>
+        mSysmemAllocator;
 #endif
 
     WorkPool mWorkPool { 4 };