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/BUILD.gn b/BUILD.gn
index f3c7db1..ef82879 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -137,9 +137,9 @@
     libs = [ "zircon" ]
 
     deps = [
-      "//sdk/fidl/fuchsia.hardware.goldfish",
+      "//sdk/fidl/fuchsia.hardware.goldfish:fuchsia.hardware.goldfish_llcpp",
       "//sdk/fidl/fuchsia.logger:fuchsia.logger_llcpp",
-      "//sdk/fidl/fuchsia.sysmem",
+      "//sdk/fidl/fuchsia.sysmem:fuchsia.sysmem_llcpp",
       "//zircon/public/lib/zx",
       "//zircon/system/ulib/syslog:syslog-static",
       "//zircon/system/ulib/trace:trace-with-static-engine",
diff --git a/shared/GoldfishAddressSpace/include/goldfish_address_space.h b/shared/GoldfishAddressSpace/include/goldfish_address_space.h
index ad5e3cb..1d2e14b 100644
--- a/shared/GoldfishAddressSpace/include/goldfish_address_space.h
+++ b/shared/GoldfishAddressSpace/include/goldfish_address_space.h
@@ -19,7 +19,7 @@
 #include <stddef.h>
 
 #ifdef __Fuchsia__
-#include <fuchsia/hardware/goldfish/cpp/fidl.h>
+#include <fuchsia/hardware/goldfish/llcpp/fidl.h>
 #endif
 
 class GoldfishAddressSpaceBlock;
@@ -67,8 +67,12 @@
     static void closeHandle(address_space_handle_t handle);
 
 #ifdef __Fuchsia__
-    fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr m_device;
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr m_child_driver;
+    std::unique_ptr<
+        llcpp::fuchsia::hardware::goldfish::AddressSpaceDevice::SyncClient>
+        m_device;
+    std::unique_ptr<
+        llcpp::fuchsia::hardware::goldfish::AddressSpaceChildDriver::SyncClient>
+        m_child_driver;
 #else // __Fuchsia__
     address_space_handle_t m_handle;
 #endif // !__Fuchsia__
@@ -100,7 +104,8 @@
     GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &);
 
 #ifdef __Fuchsia__
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* m_driver;
+    llcpp::fuchsia::hardware::goldfish::AddressSpaceChildDriver::SyncClient*
+        m_driver;
     uint32_t  m_vmo;
 #else // __Fuchsia__
     address_space_handle_t m_handle;
diff --git a/shared/GoldfishAddressSpace/include/goldfish_address_space_fuchsia.impl b/shared/GoldfishAddressSpace/include/goldfish_address_space_fuchsia.impl
index 9c4f3fa..d484347 100644
--- a/shared/GoldfishAddressSpace/include/goldfish_address_space_fuchsia.impl
+++ b/shared/GoldfishAddressSpace/include/goldfish_address_space_fuchsia.impl
@@ -32,13 +32,16 @@
 
 #include <unordered_map>
 
+#define GET_STATUS_SAFE(result, member) \
+    ((result).ok() ? ((result).Unwrap()->member) : ZX_OK)
+
 using android::base::guest::AutoLock;
 using android::base::guest::Lock;
 
-using fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr;
-using fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr;
-using fuchsia::hardware::goldfish::AddressSpaceChildDriverType;
-using fuchsia::hardware::goldfish::AddressSpaceChildDriverPingMessage;
+using llcpp::fuchsia::hardware::goldfish::AddressSpaceChildDriver;
+using llcpp::fuchsia::hardware::goldfish::AddressSpaceDevice;
+using llcpp::fuchsia::hardware::goldfish::AddressSpaceChildDriverType;
+using llcpp::fuchsia::hardware::goldfish::AddressSpaceChildDriverPingMessage;
 
 GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice) {
 
@@ -53,17 +56,24 @@
               __FUNCTION__);
         return;
     }
-    m_device.Bind(std::move(channel));
+    m_device = std::make_unique<AddressSpaceDevice::SyncClient>(std::move(channel));
 
-    zx_status_t status = (*m_device).OpenChildDriver(
-        static_cast<fuchsia::hardware::goldfish::AddressSpaceChildDriverType>(0 /* graphics */),
-        m_child_driver.NewRequest());
-
+    zx::channel child_driver_server, child_driver_client;
+    zx_status_t status = zx::channel::create(0, &child_driver_server, &child_driver_client);
     if (status != ZX_OK) {
-        ALOGE("%s: failed to open child driver: %d",
-              __FUNCTION__, status);
+        ALOGE("%s: zx_channel_create failed: %d", __FUNCTION__, status);
         return;
     }
+
+    auto result = m_device->OpenChildDriver(
+        static_cast<AddressSpaceChildDriverType>(0 /* graphics */),
+        std::move(child_driver_server));
+    if (!result.ok()) {
+        ALOGE("%s: failed to open child driver: %d",
+              __FUNCTION__, result.status());
+        return;
+    }
+    m_child_driver = std::make_unique<AddressSpaceChildDriver::SyncClient>(std::move(child_driver_client));
 }
 
 GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
@@ -72,7 +82,7 @@
 
 bool GoldfishAddressSpaceBlockProvider::is_opened() const
 {
-    return m_device.is_bound();
+    return !!m_device;
 }
 
 // void GoldfishAddressSpaceBlockProvider::close() - not implemented
@@ -116,18 +126,17 @@
         return false;
     }
 
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* driver = &provider->m_child_driver;
+    AddressSpaceChildDriver::SyncClient* driver = provider->m_child_driver.get();
 
-    int32_t res = ZX_OK;
-    zx::vmo vmo;
-    zx_status_t status = (*driver)->AllocateBlock(size, &res, &m_phys_addr, &vmo);
-    if (status != ZX_OK || res != ZX_OK) {
-        ALOGE("%s: allocate block failed: %d:%d", __func__, status, res);
+    auto result = driver->AllocateBlock(size);
+    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+        ALOGE("%s: allocate block failed: %d:%d", __func__, result.status(), GET_STATUS_SAFE(result, res));
         return false;
     }
+    m_phys_addr = result.Unwrap()->paddr;
+    m_vmo = result.Unwrap()->vmo.release();
 
     m_size = size;
-    m_vmo = vmo.release();
     m_offset = 0;
     m_is_shared_mapping = false;
 
@@ -180,11 +189,11 @@
               (unsigned long long)m_size,
               (unsigned long long)m_offset, status);
         return NULL;
-    } else {
-        m_mmaped_ptr = (void*)ptr;
-        m_host_addr = host_addr;
-        return guestPtr();
     }
+
+    m_mmaped_ptr = (void*)ptr;
+    m_host_addr = host_addr;
+    return guestPtr();
 }
 
 void *GoldfishAddressSpaceBlock::guestPtr() const
@@ -209,15 +218,16 @@
             ALOGE("%s: unsupported: GoldfishAddressSpaceBlock destroy() for shared regions\n", __func__);
             abort();
             // int32_t res = ZX_OK;
-            // zx_status_t status = (*m_driver)->UnclaimShared(m_offset, &res);
-            // if (status != ZX_OK || res != ZX_OK) {
-            //     ALOGE("%s: unclaim shared block failed: %d:%d", __func__, status, res);
+            // auto result = m_driver->UnclaimShared(m_offset);
+            // if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+            //     ALOGE("%s: unclaim shared block failed: %d:%d", __func__,
+            //           result.status(), GET_STATUS_SAFE(result, res));
             // }
         } else {
-            int32_t res = ZX_OK;
-            zx_status_t status = (*m_driver)->DeallocateBlock(m_phys_addr, &res);
-            if (status != ZX_OK || res != ZX_OK) {
-                ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res);
+            auto result = m_driver->DeallocateBlock(m_phys_addr);
+            if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+                ALOGE("%s: deallocate block failed: %d:%d", __func__,
+                      result.status(), GET_STATUS_SAFE(result, res));
             }
         }
         m_driver = NULL;
@@ -291,16 +301,15 @@
               __FUNCTION__);
         return 0;
     }
-    fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr*
-        deviceSync = new fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr;
-    deviceSync->Bind(std::move(channel));
+    AddressSpaceDevice::SyncClient*
+        deviceSync = new AddressSpaceDevice::SyncClient(std::move(channel));
     return (address_space_handle_t)deviceSync;
 }
 
 void goldfish_address_space_close(address_space_handle_t handle) {
-    fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr* deviceSync =
+    AddressSpaceDevice::SyncClient* deviceSync =
         reinterpret_cast<
-            fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr*>(handle);
+            AddressSpaceDevice::SyncClient*>(handle);
     delete deviceSync;
 }
 
@@ -308,16 +317,23 @@
     address_space_handle_t handle, GoldfishAddressSpaceSubdeviceType type,
     address_space_handle_t* handle_out) {
 
-    fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr* deviceSync =
+    AddressSpaceDevice::SyncClient* deviceSync =
         reinterpret_cast<
-            fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr*>(handle);
+            AddressSpaceDevice::SyncClient*>(handle);
 
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*
-        childSync = new fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr;
+    zx::channel child_driver_server, child_driver_client;
+    zx_status_t status = zx::channel::create(0, &child_driver_server, &child_driver_client);    
+    if (status != ZX_OK) {
+        ALOGE("%s: zx_channel_create failed: %d", __FUNCTION__, status);
+        return false;
+    }
 
-    zx_status_t res = (*(*deviceSync)).OpenChildDriver(
-        static_cast<fuchsia::hardware::goldfish::AddressSpaceChildDriverType>(type),
-        (*childSync).NewRequest());
+    deviceSync->OpenChildDriver(
+        static_cast<AddressSpaceChildDriverType>(type),
+        std::move(child_driver_server));
+
+    AddressSpaceChildDriver::SyncClient*
+        childSync = new AddressSpaceChildDriver::SyncClient(std::move(child_driver_client));
 
     // On creating a subdevice, in our use cases we wont be needing the
     // original device sync anymore, so get rid of it.
@@ -331,17 +347,18 @@
 bool goldfish_address_space_allocate(
     address_space_handle_t handle,
     size_t size, uint64_t* phys_addr, uint64_t* offset) {
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+    AddressSpaceChildDriver::SyncClient* deviceSync =
         reinterpret_cast<
-            fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
+            AddressSpaceChildDriver::SyncClient*>(handle);
 
-    int32_t res = ZX_OK;
     zx::vmo vmo;
-    zx_status_t status = (*(*deviceSync)).AllocateBlock(size, &res, phys_addr, &vmo);
-    if (status != ZX_OK || res != ZX_OK) {
-        ALOGE("%s: allocate block failed: %d:%d", __func__, status, res);
+    auto result = deviceSync->AllocateBlock(size);
+    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+        ALOGE("%s: allocate block failed: %d:%d", __func__, result.status(), GET_STATUS_SAFE(result, res));
         return false;
     }
+    *phys_addr = result.Unwrap()->paddr;
+    vmo = std::move(result.Unwrap()->vmo);
 
     *offset = 0;
 
@@ -360,14 +377,13 @@
     if (info.vmo == ZX_HANDLE_INVALID) return false;
     zx_handle_close(info.vmo);
 
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+    AddressSpaceChildDriver::SyncClient* deviceSync =
         reinterpret_cast<
-            fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
+            AddressSpaceChildDriver::SyncClient*>(handle);
 
-    int32_t res = ZX_OK;
-    zx_status_t status = (*(*deviceSync)).DeallocateBlock(info.phys_addr, &res);
-    if (status != ZX_OK || res != ZX_OK) {
-        ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res);
+    auto result = deviceSync->DeallocateBlock(info.phys_addr);
+    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+        ALOGE("%s: deallocate block failed: %d:%d", __func__, result.status(), GET_STATUS_SAFE(result, res));
         return false;
     }
 
@@ -377,12 +393,17 @@
 bool goldfish_address_space_claim_shared(
     address_space_handle_t handle, uint64_t offset, uint64_t size) {
 
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+    AddressSpaceChildDriver::SyncClient* deviceSync =
         reinterpret_cast<
-            fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
+            AddressSpaceChildDriver::SyncClient*>(handle);
+
     zx::vmo vmo;
-    zx_status_t res;
-    zx_status_t status = (*(*deviceSync)).ClaimSharedBlock(offset, size, &res, &vmo);
+    auto result = deviceSync->ClaimSharedBlock(offset, size);
+    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+        ALOGE("%s: claim shared failed: %d:%d", __func__, result.status(), GET_STATUS_SAFE(result, res));
+        return false;
+    }
+    vmo = std::move(result.Unwrap()->vmo);
 
     VmoStore::Info info = {
         vmo.release(),
@@ -390,21 +411,20 @@
 
     getVmoStore()->add(offset, info);
 
-    if (status != ZX_OK) return false;
-
     return true;
 }
 
 bool goldfish_address_space_unclaim_shared(
     address_space_handle_t handle, uint64_t offset) {
-    fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+    AddressSpaceChildDriver::SyncClient* deviceSync =
         reinterpret_cast<
-            fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
-    zx::vmo vmo;
-    zx_status_t res;
-    zx_status_t status = (*(*deviceSync)).UnclaimSharedBlock(offset, &res);
+            AddressSpaceChildDriver::SyncClient*>(handle);
 
-    if (status != ZX_OK) return false;
+    auto result = deviceSync->UnclaimSharedBlock(offset);
+    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+        ALOGE("%s: unclaim shared failed: %d:%d", __func__, result.status(), GET_STATUS_SAFE(result, res));
+        return false;
+    }
 
     getVmoStore()->remove(offset);
     return true;
@@ -442,17 +462,16 @@
     AddressSpaceChildDriverPingMessage fuchsiaPing =
         *(AddressSpaceChildDriverPingMessage*)ping;
 
-    AddressSpaceChildDriverSyncPtr* deviceSync =
+    AddressSpaceChildDriver::SyncClient* deviceSync =
         reinterpret_cast<
-            AddressSpaceChildDriverSyncPtr*>(handle);
+            AddressSpaceChildDriver::SyncClient*>(handle);
 
     AddressSpaceChildDriverPingMessage res;
-    zx_status_t pingStatus;
-    zx_status_t status = (*(*deviceSync)).Ping(fuchsiaPing, &pingStatus, &res);
-
-    if (pingStatus != ZX_OK) {
+    auto result = deviceSync->Ping(fuchsiaPing);
+    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
         return false;
     }
+    res = std::move(result.Unwrap()->ping);
 
     *ping = *(struct address_space_ping*)(&res);
     return true;
diff --git a/system/OpenglSystemCommon/ProcessPipe.cpp b/system/OpenglSystemCommon/ProcessPipe.cpp
index 0d74789..64ba1d9 100644
--- a/system/OpenglSystemCommon/ProcessPipe.cpp
+++ b/system/OpenglSystemCommon/ProcessPipe.cpp
@@ -28,11 +28,14 @@
 #include <errno.h>
 
 #ifdef __Fuchsia__
-#include <fuchsia/hardware/goldfish/cpp/fidl.h>
+#include <fuchsia/hardware/goldfish/llcpp/fidl.h>
 #include <lib/zx/vmo.h>
 
 #include "services/service_connector.h"
 
+#define GET_STATUS_SAFE(result, member) \
+    ((result).ok() ? ((result).Unwrap()->member) : ZX_OK)
+
 static QEMU_PIPE_HANDLE   sProcDevice = 0;
 #else // __Fuchsia__
 
@@ -64,32 +67,45 @@
         return;
     }
 
-    fuchsia::hardware::goldfish::PipeDeviceSyncPtr device;
-    device.Bind(std::move(channel));
+    llcpp::fuchsia::hardware::goldfish::PipeDevice::SyncClient device(
+        std::move(channel));
 
-    fuchsia::hardware::goldfish::PipeSyncPtr pipe;
-    device->OpenPipe(pipe.NewRequest());
-
-    zx_status_t status, status2 = ZX_OK;
-    zx::vmo vmo;
-    status = pipe->GetBuffer(&status2, &vmo);
-    if (status != ZX_OK || status2 != ZX_OK) {
-        ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__, status, status2);
+    zx::channel pipe_server, pipe_client;
+    zx_status_t status = zx::channel::create(0, &pipe_server, &pipe_client);
+    if (status != ZX_OK) {
+        ALOGE("%s: zx_channel_create failed: %d", __FUNCTION__, status);
         return;
     }
 
+    llcpp::fuchsia::hardware::goldfish::Pipe::SyncClient pipe(
+        std::move(pipe_client));
+    device.OpenPipe(std::move(pipe_server));
+
+    zx::vmo vmo;
+    {
+        auto result = pipe.GetBuffer();
+        if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+            ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__,
+                  result.status(), GET_STATUS_SAFE(result, res));
+            return;
+        }
+        vmo = std::move(result.Unwrap()->vmo);
+    }
+
     size_t len = strlen("pipe:GLProcessPipe");
     status = vmo.write("pipe:GLProcessPipe", 0, len + 1);
     if (status != ZX_OK) {
         ALOGE("%s: failed write pipe name", __FUNCTION__);
         return;
     }
-    uint64_t actual;
-    status = pipe->Write(len + 1, 0, &status2, &actual);
-    if (status != ZX_OK || status2 != ZX_OK) {
-        ALOGD("%s: connecting to pipe service failed: %d:%d", __FUNCTION__,
-              status, status2);
-        return;
+
+    {
+        auto result = pipe.Write(len + 1, 0);
+        if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+            ALOGD("%s: connecting to pipe service failed: %d:%d", __FUNCTION__,
+                  result.status(), GET_STATUS_SAFE(result, res));
+            return;
+        }
     }
 
     // Send a confirmation int to the host and get per-process unique ID back
@@ -99,19 +115,23 @@
         ALOGE("%s: failed write confirm int", __FUNCTION__);
         return;
     }
-    status = pipe->DoCall(sizeof(confirmInt), 0, sizeof(sProcUID), 0, &status2, &actual);
-    if (status != ZX_OK || status2 != ZX_OK) {
-        ALOGD("%s: failed to get per-process ID: %d:%d", __FUNCTION__,
-              status, status2);
-        return;
+
+    {
+        auto result = pipe.DoCall(sizeof(confirmInt), 0, sizeof(sProcUID), 0);
+        if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+            ALOGD("%s: failed to get per-process ID: %d:%d", __FUNCTION__,
+                  result.status(), GET_STATUS_SAFE(result, res));
+            return;
+        }
     }
+
     status = vmo.read(&sProcUID, 0, sizeof(sProcUID));
     if (status != ZX_OK) {
         ALOGE("%s: failed read per-process ID: %d", __FUNCTION__, status);
         return;
     }
-    sProcDevice = device.Unbind().TakeChannel().release();
-    sProcPipe = pipe.Unbind().TakeChannel().release();
+    sProcDevice = device.mutable_channel()->release();
+    sProcPipe = pipe.mutable_channel()->release();
 }
 #else // __Fuchsia__
 
diff --git a/system/OpenglSystemCommon/QemuPipeStream.h b/system/OpenglSystemCommon/QemuPipeStream.h
index 4e779eb..312eaf9 100644
--- a/system/OpenglSystemCommon/QemuPipeStream.h
+++ b/system/OpenglSystemCommon/QemuPipeStream.h
@@ -21,12 +21,13 @@
  * <hardware/qemu_pipe.h> for more details.
  */
 #include <stdlib.h>
+#include <memory>
 #include "IOStream.h"
 
 #include <qemu_pipe_bp.h>
 
 #ifdef __Fuchsia__
-#include <fuchsia/hardware/goldfish/cpp/fidl.h>
+#include <fuchsia/hardware/goldfish/llcpp/fidl.h>
 #include <lib/zx/event.h>
 #include <lib/zx/vmo.h>
 #endif
@@ -58,8 +59,10 @@
     size_t m_read;
     size_t m_readLeft;
 #ifdef __Fuchsia__
-    fuchsia::hardware::goldfish::PipeDeviceSyncPtr m_device;
-    fuchsia::hardware::goldfish::PipeSyncPtr m_pipe;
+    std::unique_ptr<llcpp::fuchsia::hardware::goldfish::PipeDevice::SyncClient>
+        m_device;
+    std::unique_ptr<llcpp::fuchsia::hardware::goldfish::Pipe::SyncClient>
+        m_pipe;
     zx::event m_event;
     zx::vmo m_vmo;
 #endif
diff --git a/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
index 5472f30..83c81ac 100644
--- a/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
+++ b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
@@ -28,6 +28,9 @@
 
 #include "services/service_connector.h"
 
+#define GET_STATUS_SAFE(result, member) \
+    ((result).ok() ? ((result).Unwrap()->member) : ZX_OK)
+
 constexpr size_t kReadSize = 512 * 1024;
 constexpr size_t kWriteOffset = kReadSize;
 
@@ -53,7 +56,7 @@
 
 QemuPipeStream::~QemuPipeStream()
 {
-    if (m_device.is_bound()) {
+    if (m_device) {
         flush();
     }
     if (m_buf) {
@@ -76,11 +79,23 @@
         return -1;
     }
 
-    m_device.Bind(std::move(channel));
-    m_device->OpenPipe(m_pipe.NewRequest());
+    m_device = std::make_unique<
+        llcpp::fuchsia::hardware::goldfish::PipeDevice::SyncClient>(
+        std::move(channel));
+
+    zx::channel pipe_client, pipe_server;
+    zx_status_t status = zx::channel::create(0, &pipe_server, &pipe_client);
+    if (status != ZX_OK) {
+        ALOGE("zx::channel::create failed: %d", status);
+        return ZX_HANDLE_INVALID;
+    }
+    m_device->OpenPipe(std::move(pipe_server));
+    m_pipe =
+        std::make_unique<llcpp::fuchsia::hardware::goldfish::Pipe::SyncClient>(
+            std::move(pipe_client));
 
     zx::event event;
-    zx_status_t status = zx::event::create(0, &event);
+    status = zx::event::create(0, &event);
     if (status != ZX_OK) {
         ALOGE("%s: failed to create event: %d", __FUNCTION__, status);
         return -1;
@@ -92,10 +107,13 @@
         return -1;
     }
 
-    status = m_pipe->SetEvent(std::move(event_copy));
-    if (status != ZX_OK) {
-        ALOGE("%s: failed to set event: %d:%d", __FUNCTION__, status);
-        return -1;
+    {
+        auto result = m_pipe->SetEvent(std::move(event_copy));
+        if (!result.ok()) {
+            ALOGE("%s: failed to set event: %d:%d", __FUNCTION__,
+                  result.status());
+            return -1;
+        }
     }
 
     if (!allocBuffer(m_bufsize)) {
@@ -110,13 +128,13 @@
         return -1;
     }
 
-    uint64_t actual;
-    zx_status_t status2 = ZX_OK;
-    status = m_pipe->Write(len + 1, 0, &status2, &actual);
-    if (status != ZX_OK || status2 != ZX_OK) {
-        ALOGD("%s: connecting to pipe service failed: %d:%d", __FUNCTION__,
-              status, status2);
-        return -1;
+    {
+        result = m_pipe->Write(len + 1, 0);
+        if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+            ALOGD("%s: connecting to pipe service failed: %d:%d", __FUNCTION__,
+                  result.status(), GET_STATUS_SAFE(result, res));
+            return -1;
+        }
     }
 
     m_event = std::move(event);
@@ -145,26 +163,32 @@
 
     size_t allocSize = m_bufsize < minSize ? minSize : m_bufsize;
 
-    zx_status_t status2 = ZX_OK;
-    status = m_pipe->SetBufferSize(allocSize, &status2);
-    if (status != ZX_OK || status2 != ZX_OK) {
-        ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__, status, status2);
-        return nullptr;
+    {
+        auto result = m_pipe->SetBufferSize(allocSize);
+        if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+            ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__,
+                  result.status(), GET_STATUS_SAFE(result, res));
+            return nullptr;
+        }
     }
 
     zx::vmo vmo;
-    status = m_pipe->GetBuffer(&status2, &vmo);
-    if (status != ZX_OK || status2 != ZX_OK) {
-        ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__, status, status2);
-        return nullptr;
+    {
+        auto result = m_pipe->GetBuffer();
+        if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+            ALOGE("%s: failed to get buffer: %d:%d", __FUNCTION__,
+                  result.status(), GET_STATUS_SAFE(result, res));
+            return nullptr;
+        }
+        vmo = std::move(result.Unwrap()->vmo);
     }
 
     zx_vaddr_t mapped_addr;
-    status = zx_vmar_map(zx_vmar_root_self(),
-                         ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
-                         0, vmo.get(), 0, allocSize, &mapped_addr);
+    status =
+        zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0,
+                    vmo.get(), 0, allocSize, &mapped_addr);
     if (status != ZX_OK) {
-        ALOGE("%s: failed to map buffer: %d:%d", __FUNCTION__, status);
+        ALOGE("%s: failed to map buffer: %d", __FUNCTION__, status);
         return nullptr;
     }
 
@@ -178,11 +202,10 @@
 {
     if (size == 0) return 0;
 
-    uint64_t actual = 0;
-    zx_status_t status2 = ZX_OK;
-    zx_status_t status = m_pipe->DoCall(size, kWriteOffset, 0, 0, &status2, &actual);
-    if (status != ZX_OK || status2 != ZX_OK) {
-        ALOGD("%s: Pipe call failed: %d:%d", __FUNCTION__, status, status2);
+    auto result = m_pipe->DoCall(size, kWriteOffset, 0, 0);
+    if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+        ALOGD("%s: Pipe call failed: %d:%d", __FUNCTION__, result.status(),
+              GET_STATUS_SAFE(result, res));
         return -1;
     }
 
@@ -207,7 +230,8 @@
 
 const unsigned char *QemuPipeStream::commitBufferAndReadFully(size_t size, void *buf, size_t len)
 {
-    if (!m_device.is_bound()) return nullptr;
+    if (!m_device)
+        return nullptr;
 
     if (!buf) {
         if (len > 0) {
@@ -236,17 +260,16 @@
 
     // Read up to kReadSize bytes if all buffered read has been consumed.
     size_t maxRead = (m_readLeft || !remaining) ? 0 : kReadSize;
-    uint64_t actual = 0;
-    zx_status_t status2 = ZX_OK;
-    zx_status_t status = m_pipe->DoCall(size, kWriteOffset, maxRead, 0, &status2, &actual);
-    if (status != ZX_OK) {
-        ALOGD("%s: Pipe call failed: %d", __FUNCTION__, status);
+
+    auto result = m_pipe->DoCall(size, kWriteOffset, maxRead, 0);
+    if (!result.ok()) {
+        ALOGD("%s: Pipe call failed: %d", __FUNCTION__, result.status());
         return nullptr;
     }
 
     // Updated buffered read size.
-    if (actual) {
-        m_read = m_readLeft = actual;
+    if (result.Unwrap()->actual) {
+        m_read = m_readLeft = result.Unwrap()->actual;
     }
 
     // Consume buffered read and read more if neccessary.
@@ -261,31 +284,33 @@
             continue;
         }
 
-        status2 = ZX_OK;
-        actual = 0;
-        status = m_pipe->Read(kReadSize, 0, &status2, &actual);
-        if (status != ZX_OK) {
-            ALOGD("%s: Failed reading from pipe: %d", __FUNCTION__, status);
+        auto result = m_pipe->Read(kReadSize, 0);
+        if (!result.ok()) {
+            ALOGD("%s: Failed reading from pipe: %d:%d", __FUNCTION__,
+                  result.status());
             return nullptr;
         }
-        if (actual) {
-            m_read = m_readLeft = actual;
+
+        if (result.Unwrap()->actual) {
+            m_read = m_readLeft = result.Unwrap()->actual;
             continue;
         }
-        if (status2 != ZX_ERR_SHOULD_WAIT) {
-            ALOGD("%s: Error reading from pipe: %d", __FUNCTION__, status2);
+        if (result.Unwrap()->res != ZX_ERR_SHOULD_WAIT) {
+            ALOGD("%s: Error reading from pipe: %d", __FUNCTION__,
+                  result.Unwrap()->res);
             return nullptr;
         }
+
         zx_signals_t observed = ZX_SIGNAL_NONE;
-        status = m_event.wait_one(
-            fuchsia::hardware::goldfish::SIGNAL_READABLE |
-            fuchsia::hardware::goldfish::SIGNAL_HANGUP,
+        zx_status_t status = m_event.wait_one(
+            llcpp::fuchsia::hardware::goldfish::SIGNAL_READABLE |
+                llcpp::fuchsia::hardware::goldfish::SIGNAL_HANGUP,
             zx::time::infinite(), &observed);
         if (status != ZX_OK) {
             ALOGD("%s: wait_one failed: %d", __FUNCTION__, status);
             return nullptr;
         }
-        if (observed & fuchsia::hardware::goldfish::SIGNAL_HANGUP) {
+        if (observed & llcpp::fuchsia::hardware::goldfish::SIGNAL_HANGUP) {
             ALOGD("%s: Remote end hungup", __FUNCTION__);
             return nullptr;
         }
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 };