[version roller] Update dependencies

SDK version updated from 10.20221130.0.1 to 11.20230109.3.1

This also fixes the following breaking changes from in-tree:
- Uses fdf instead of driver as the driver framework namespace
- Drivers take in an fdf::UnownedSynchronizedDispatcher instead of a
  fdf::SynchronizedDispatcher
- Drivers use fuchsia_device_fs::Exporter::Export2 to export to devfs
- Drivers are now placed into 'driver/" in a package, the CML files are
  updated to reflect this.

Change-Id: Ie4b89935704eaf6802bf1a7424675fbf1ee2bade
Reviewed-on: https://fuchsia-review.googlesource.com/c/sdk-samples/drivers/+/786965
Commit-Queue: Bill Stevenson <billstevenson@google.com>
Reviewed-by: Wayne Piekarski <waynepie@google.com>
Reviewed-by: Renato Mangini Dias <mangini@google.com>
Reviewed-by: Dave Smith <smithdave@google.com>
diff --git a/src/acpi_multiply/controller/acpi_controller.cc b/src/acpi_multiply/controller/acpi_controller.cc
index c885601..032caca 100644
--- a/src/acpi_multiply/controller/acpi_controller.cc
+++ b/src/acpi_multiply/controller/acpi_controller.cc
@@ -21,13 +21,13 @@
 
   // Serve the fuchsia.hardware.acpi/Device protocol to clients through the
   // fuchsia.hardware.acpi/Service wrapper.
-  fuchsia_hardware_acpi::Service::InstanceHandler handler({
-    .device = [this](fidl::ServerEnd<fuchsia_hardware_acpi::Device> request) -> void {
+  fuchsia_hardware_acpi::Service::InstanceHandler handler(
+      {.device = [this](fidl::ServerEnd<fuchsia_hardware_acpi::Device> request) -> void {
         AcpiDeviceServer::BindDeviceClient(server_, dispatcher(), std::move(request));
-      }
-  });
+      }});
 
-  auto result = context().outgoing()->AddService<fuchsia_hardware_acpi::Service>(std::move(handler));
+  auto result =
+      context().outgoing()->AddService<fuchsia_hardware_acpi::Service>(std::move(handler));
   if (result.is_error()) {
     FDF_SLOG(ERROR, "Failed to add service.", KV("status", result.status_string()));
     return result.take_error();
@@ -87,14 +87,14 @@
   auto offers = child_->CreateOffers(arena);
   // Offer fuchsia.hardware.acpi.Service to the driver that binds to the node.
   auto service_offer =
-      driver::MakeOffer<fuchsia_hardware_acpi::Service>(arena, component::kDefaultInstance);
+      fdf::MakeOffer<fuchsia_hardware_acpi::Service>(arena, component::kDefaultInstance);
   offers.push_back(service_offer);
 
   // Set the properties of the node that a driver binds to.
   auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
-  properties[0] = driver::MakeProperty(arena, bind_fuchsia_hardware_acpi::SERVICE,
-                                       bind_fuchsia_hardware_acpi::SERVICE_ZIRCONTRANSPORT);
-  properties[1] = driver::MakeProperty(arena, bind_fuchsia_acpi::HID, "FDFS0001");
+  properties[0] = fdf::MakeProperty(arena, bind_fuchsia_hardware_acpi::SERVICE,
+                                    bind_fuchsia_hardware_acpi::SERVICE_ZIRCONTRANSPORT);
+  properties[1] = fdf::MakeProperty(arena, bind_fuchsia_acpi::HID, "FDFS0001");
 
   auto args = fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
                   .name(arena, "acpi-child")
@@ -128,4 +128,4 @@
 
 }  // namespace acpi_multiply
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<acpi_multiply::AcpiMultiplyController>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<acpi_multiply::AcpiMultiplyController>);
diff --git a/src/acpi_multiply/controller/acpi_controller.h b/src/acpi_multiply/controller/acpi_controller.h
index f6fe5da..60fef8d 100644
--- a/src/acpi_multiply/controller/acpi_controller.h
+++ b/src/acpi_multiply/controller/acpi_controller.h
@@ -19,12 +19,12 @@
 // for an interrupt.
 // 3. This driver performs the multiplication, writes the result (64-bit) to 0x08
 // and triggers an interrupt.
-class AcpiMultiplyController : public driver::DriverBase {
+class AcpiMultiplyController : public fdf::DriverBase {
  public:
-  AcpiMultiplyController(driver::DriverStartArgs start_args,
-                         fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("acpi-multiply-controller", std::move(start_args),
-                           std::move(driver_dispatcher)) {}
+  AcpiMultiplyController(fdf::DriverStartArgs start_args,
+                         fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("acpi-multiply-controller", std::move(start_args),
+                        std::move(driver_dispatcher)) {}
 
   virtual ~AcpiMultiplyController() = default;
 
diff --git a/src/acpi_multiply/controller/acpi_server.h b/src/acpi_multiply/controller/acpi_server.h
index 7594e91..7c9418d 100644
--- a/src/acpi_multiply/controller/acpi_server.h
+++ b/src/acpi_multiply/controller/acpi_server.h
@@ -14,7 +14,7 @@
 // FIDL server implementation for the `fuchsia.hardware.acpi/Device` protocol
 class AcpiDeviceServer : public fidl::WireServer<fuchsia_hardware_acpi::Device> {
  public:
-  AcpiDeviceServer(zx::interrupt irq, fdf::MmioBuffer buffer, driver::Logger* logger,
+  AcpiDeviceServer(zx::interrupt irq, fdf::MmioBuffer buffer, fdf::Logger* logger,
                    async_dispatcher_t* dispatcher)
       : irq_(std::move(irq)),
         buffer_(std::move(buffer)),
@@ -74,7 +74,7 @@
  private:
   zx::interrupt irq_;
   fdf::MmioBuffer buffer_;
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   async_dispatcher_t* dispatcher_;
 };
 
diff --git a/src/acpi_multiply/controller/meta/acpi_controller.cml b/src/acpi_multiply/controller/meta/acpi_controller.cml
index 72321f5..379bcff 100644
--- a/src/acpi_multiply/controller/meta/acpi_controller.cml
+++ b/src/acpi_multiply/controller/meta/acpi_controller.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libacpi_controller.so',
+        binary: 'driver/libacpi_controller.so',
         bind: 'meta/bind/acpi_controller.bindbc',
         // Identifies the device categories, for compatibility tests.
         device_categories: [
diff --git a/src/acpi_multiply/driver/acpi_multiply.cc b/src/acpi_multiply/driver/acpi_multiply.cc
index a7f263b..ca34d39 100644
--- a/src/acpi_multiply/driver/acpi_multiply.cc
+++ b/src/acpi_multiply/driver/acpi_multiply.cc
@@ -15,7 +15,7 @@
 zx::result<> AcpiMultiplyDriver::Start() {
   // Connect to the ACPI protocol exposed by the parent driver.
   auto client_endpoint =
-      driver::Connect<fuchsia_hardware_acpi::Service::Device>(*context().incoming());
+      fdf::Connect<fuchsia_hardware_acpi::Service::Device>(*context().incoming());
   if (client_endpoint.is_error()) {
     FDF_SLOG(ERROR, "Failed to connect to ACPI.", KV("status", client_endpoint.status_string()));
     return client_endpoint.take_error();
@@ -35,13 +35,11 @@
   // Serve the examples.acpi.multiply/Device protocol to clients through the
   // examples.acpi.multiply/Service wrapper.
   examples_acpi_multiply::Service::InstanceHandler handler({
-    .device = [this](fidl::ServerEnd<examples_acpi_multiply::Device> request) -> void {
-        AcpiMultiplyServer::BindDeviceClient(&logger(), dispatcher(), multiplier_,
-                                             std::move(request));
-      }
+      .device = fit::bind_member<&AcpiMultiplyDriver::Serve>(this),
   });
 
-  auto result = context().outgoing()->AddService<examples_acpi_multiply::Service>(std::move(handler));
+  auto result =
+      context().outgoing()->AddService<examples_acpi_multiply::Service>(std::move(handler));
   if (result.is_error()) {
     FDF_SLOG(ERROR, "Failed to add service.", KV("status", result.status_string()));
     return result.take_error();
@@ -55,7 +53,7 @@
   return zx::ok();
 }
 
-// Initialize the driver compat context and export `examples.acpi.multiply/Service` to
+// Initialize the driver compat context and export `fuchsia_acpi_multiply::Device` to
 // devfs.
 void AcpiMultiplyDriver::InitializeCompatService(
     zx::result<std::shared_ptr<compat::Context>> compat_result) {
@@ -67,18 +65,43 @@
   }
   compat_context_ = std::move(*compat_result);
 
-  auto service_path = std::string(examples_acpi_multiply::Service::Name) + "/" +
-                      component::kDefaultInstance + "/" +
-                      examples_acpi_multiply::Service::Device::Name;
-  auto status = compat_context_->devfs_exporter().ExportSync(
-      service_path, compat_context_->TopologicalPath(name()), fuchsia_device_fs::ExportOptions());
-  if (status != ZX_OK) {
-    FDF_SLOG(ERROR, "Failed to export to devfs.", KV("status", zx_status_get_string(status)));
+   // Export to devfs.
+  zx::result connection = this->context().incoming()->Connect<fuchsia_device_fs::Exporter>();
+  if (connection.is_error()) {
+    FDF_SLOG(ERROR, "Failed to connect to fuchsia_device_fs::Exporter",
+             KV("status", connection.status_string()));
+    node().reset();
+    return;
+  }
+  fidl::WireSyncClient devfs_exporter{std::move(connection.value())};
+
+  zx::result connector = devfs_connector_.Bind(dispatcher());
+  if (connector.is_error()) {
+    FDF_SLOG(ERROR, "Failed to bind devfs_connector: %s", KV("status", connector.status_string()));
+    node().reset();
+    return;
+  }
+  fidl::WireResult export_result = devfs_exporter->ExportV2(
+      std::move(connector.value()),
+      fidl::StringView::FromExternal(compat_context_->TopologicalPath(name())),
+      fidl::StringView(), fuchsia_device_fs::ExportOptions());
+  if (!export_result.ok()) {
+    FDF_SLOG(ERROR, "Failed to export to devfs: %s", KV("status", export_result.status_string()));
+    node().reset();
+    return;
+  }
+  if (export_result.value().is_error()) {
+    FDF_SLOG(ERROR, "Failed to export to devfs: %s",
+             KV("status", zx_status_get_string(export_result.value().error_value())));
     node().reset();
     return;
   }
 }
 
+void AcpiMultiplyDriver::Serve(fidl::ServerEnd<examples_acpi_multiply::Device> request) {
+  AcpiMultiplyServer::BindDeviceClient(&logger(), dispatcher(), multiplier_, std::move(request));
+}
+
 }  // namespace acpi_multiply
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<acpi_multiply::AcpiMultiplyDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<acpi_multiply::AcpiMultiplyDriver>);
diff --git a/src/acpi_multiply/driver/acpi_multiply.h b/src/acpi_multiply/driver/acpi_multiply.h
index d713823..ee22f90 100644
--- a/src/acpi_multiply/driver/acpi_multiply.h
+++ b/src/acpi_multiply/driver/acpi_multiply.h
@@ -9,16 +9,19 @@
 #include <lib/driver/compat/cpp/compat.h>
 #include <lib/driver/compat/cpp/context.h>
 #include <lib/driver/component/cpp/driver_cpp.h>
+#include <lib/driver/devfs/cpp/connector.h>
 
 #include "multiplier.h"
 
 namespace acpi_multiply {
 
 // Sample driver for a virtual "multiplier" device described using ACPI.
-class AcpiMultiplyDriver : public driver::DriverBase {
+class AcpiMultiplyDriver : public fdf::DriverBase {
  public:
-  AcpiMultiplyDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("acpi-multiply", std::move(start_args), std::move(driver_dispatcher)) {}
+  AcpiMultiplyDriver(fdf::DriverStartArgs start_args,
+                     fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : driver::DriverBase("acpi-multiply", std::move(start_args), std::move(driver_dispatcher)),
+        devfs_connector_(fit::bind_member<&AcpiMultiplyDriver::Serve>(this)) {}
 
   virtual ~AcpiMultiplyDriver() = default;
 
@@ -26,7 +29,9 @@
 
  private:
   void InitializeCompatService(zx::result<std::shared_ptr<compat::Context>> result);
+  void Serve(fidl::ServerEnd<examples_acpi_multiply::Device> request);
 
+  driver_devfs::Connector<examples_acpi_multiply::Device> devfs_connector_;
   std::shared_ptr<compat::Context> compat_context_;
   std::shared_ptr<AcpiMultiplier> multiplier_;
 };
diff --git a/src/acpi_multiply/driver/meta/acpi_multiply.cml b/src/acpi_multiply/driver/meta/acpi_multiply.cml
index 2fbf881..64d97e0 100644
--- a/src/acpi_multiply/driver/meta/acpi_multiply.cml
+++ b/src/acpi_multiply/driver/meta/acpi_multiply.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libacpi_multiply.so',
+        binary: 'driver/libacpi_multiply.so',
         bind: 'meta/bind/acpi_multiply.bindbc',
         // Identifies the device categories, for compatibility tests.
         device_categories: [
diff --git a/src/acpi_multiply/driver/multiplier.h b/src/acpi_multiply/driver/multiplier.h
index 113b8fa..75df668 100644
--- a/src/acpi_multiply/driver/multiplier.h
+++ b/src/acpi_multiply/driver/multiplier.h
@@ -18,7 +18,7 @@
 // Invokes ACPI methods using a fuchsia.hardware.acpi client.
 class AcpiMultiplier {
  public:
-  explicit AcpiMultiplier(driver::Logger* logger, async_dispatcher_t* dispatcher,
+  explicit AcpiMultiplier(fdf::Logger* logger, async_dispatcher_t* dispatcher,
                           fidl::WireSyncClient<fuchsia_hardware_acpi::Device> acpi)
       : logger_(logger), dispatcher_(dispatcher), acpi_(std::move(acpi)) {}
 
@@ -47,7 +47,7 @@
 
   void DoMultiply(Operation operation);
 
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   async_dispatcher_t* const dispatcher_;
 
   std::optional<fdf::MmioBuffer> mmio_;
diff --git a/src/acpi_multiply/driver/multiply_server.cc b/src/acpi_multiply/driver/multiply_server.cc
index 0c321e4..e188081 100644
--- a/src/acpi_multiply/driver/multiply_server.cc
+++ b/src/acpi_multiply/driver/multiply_server.cc
@@ -9,8 +9,7 @@
 // Static
 // Handle incoming connection requests from FIDL clients
 fidl::ServerBindingRef<examples_acpi_multiply::Device> AcpiMultiplyServer::BindDeviceClient(
-    driver::Logger* logger, async_dispatcher_t* dispatcher,
-    std::weak_ptr<AcpiMultiplier> multiplier,
+    fdf::Logger* logger, async_dispatcher_t* dispatcher, std::weak_ptr<AcpiMultiplier> multiplier,
     fidl::ServerEnd<examples_acpi_multiply::Device> request) {
   // Bind each connection request to a unique FIDL server instance
   auto server_impl = std::make_unique<AcpiMultiplyServer>(logger, multiplier);
diff --git a/src/acpi_multiply/driver/multiply_server.h b/src/acpi_multiply/driver/multiply_server.h
index c40eecf..4e6df01 100644
--- a/src/acpi_multiply/driver/multiply_server.h
+++ b/src/acpi_multiply/driver/multiply_server.h
@@ -15,12 +15,11 @@
 // FIDL server implementation for the `examples.acpi.multiply/Device` protocol
 class AcpiMultiplyServer : public fidl::WireServer<examples_acpi_multiply::Device> {
  public:
-  AcpiMultiplyServer(driver::Logger* logger, std::weak_ptr<AcpiMultiplier> multiplier)
+  AcpiMultiplyServer(fdf::Logger* logger, std::weak_ptr<AcpiMultiplier> multiplier)
       : logger_(logger), multiplier_(multiplier) {}
 
   static fidl::ServerBindingRef<examples_acpi_multiply::Device> BindDeviceClient(
-      driver::Logger* logger, async_dispatcher_t* dispatcher,
-      std::weak_ptr<AcpiMultiplier> multiplier,
+      fdf::Logger* logger, async_dispatcher_t* dispatcher, std::weak_ptr<AcpiMultiplier> multiplier,
       fidl::ServerEnd<examples_acpi_multiply::Device> request);
 
   void OnUnbound(fidl::UnbindInfo info, fidl::ServerEnd<examples_acpi_multiply::Device> server_end);
@@ -30,7 +29,7 @@
   void Multiply(MultiplyRequestView request, MultiplyCompleter::Sync& completer) override;
 
  private:
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   std::weak_ptr<AcpiMultiplier> multiplier_;
 };
 
diff --git a/src/bind_library/child/child-driver.cc b/src/bind_library/child/child-driver.cc
index fcfb2a6..3412515 100644
--- a/src/bind_library/child/child-driver.cc
+++ b/src/bind_library/child/child-driver.cc
@@ -10,7 +10,7 @@
 namespace child_driver {
 
 zx::result<> ChildDriver::Start() {
-  auto connect_result = driver::Connect<examples_gizmo::Service::Testing>(*context().incoming());
+  auto connect_result = fdf::Connect<examples_gizmo::Service::Testing>(*context().incoming());
   if (connect_result.is_error()) {
     FDF_SLOG(WARNING, "Failed to connect to gizmo service.",
              KV("status", connect_result.status_string()));
@@ -31,4 +31,4 @@
 
 }  // namespace child_driver
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<child_driver::ChildDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<child_driver::ChildDriver>);
diff --git a/src/bind_library/child/child-driver.h b/src/bind_library/child/child-driver.h
index 5698245..47a3094 100644
--- a/src/bind_library/child/child-driver.h
+++ b/src/bind_library/child/child-driver.h
@@ -9,10 +9,10 @@
 
 namespace child_driver {
 
-class ChildDriver : public driver::DriverBase {
+class ChildDriver : public fdf::DriverBase {
  public:
-  ChildDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("child-driver", std::move(start_args), std::move(driver_dispatcher)) {}
+  ChildDriver(fdf::DriverStartArgs start_args, fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("child-driver", std::move(start_args), std::move(driver_dispatcher)) {}
   virtual ~ChildDriver() = default;
 
   zx::result<> Start() override;
diff --git a/src/bind_library/child/meta/child-driver.cml b/src/bind_library/child/meta/child-driver.cml
index d24b126..9dd6ce3 100644
--- a/src/bind_library/child/meta/child-driver.cml
+++ b/src/bind_library/child/meta/child-driver.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libchild_driver.so',
+        binary: 'driver/libchild_driver.so',
         bind: 'meta/bind/child-driver.bindbc',
         // Identifies the device categories, for compatibility tests. This
         // example driver uses the 'misc' category; real drivers should
diff --git a/src/bind_library/parent/gizmo_server.h b/src/bind_library/parent/gizmo_server.h
index f1b1914..945f9eb 100644
--- a/src/bind_library/parent/gizmo_server.h
+++ b/src/bind_library/parent/gizmo_server.h
@@ -12,7 +12,7 @@
 
 class GizmoServer : public fidl::WireServer<examples_gizmo::TestingProtocol> {
  public:
-  GizmoServer(driver::Logger* logger) : logger_(logger) {}
+  GizmoServer(fdf::Logger* logger) : logger_(logger) {}
   virtual ~GizmoServer() = default;
 
   static fidl::ServerBindingRef<examples_gizmo::TestingProtocol> BindDeviceClient(
@@ -39,7 +39,7 @@
   }
 
  private:
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
 };
 
 }  // namespace parent_driver
diff --git a/src/bind_library/parent/meta/parent-driver.cml b/src/bind_library/parent/meta/parent-driver.cml
index 685e701..8d1866d 100644
--- a/src/bind_library/parent/meta/parent-driver.cml
+++ b/src/bind_library/parent/meta/parent-driver.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libparent_driver.so',
+        binary: 'driver/libparent_driver.so',
         bind: 'meta/bind/parent-driver.bindbc',
         // Identifies the device categories, for compatibility tests. This
         // example driver uses the 'misc' category; real drivers should
diff --git a/src/bind_library/parent/parent-driver.cc b/src/bind_library/parent/parent-driver.cc
index 01a59d7..4f883bb 100644
--- a/src/bind_library/parent/parent-driver.cc
+++ b/src/bind_library/parent/parent-driver.cc
@@ -18,11 +18,10 @@
 
   // Add gizmo examples_gizmo::Service to outgoing.
   {
-    examples_gizmo::Service::InstanceHandler handler({
-      .testing = [this](fidl::ServerEnd<examples_gizmo::TestingProtocol> server_end) -> void {
+    examples_gizmo::Service::InstanceHandler handler(
+        {.testing = [this](fidl::ServerEnd<examples_gizmo::TestingProtocol> server_end) -> void {
           GizmoServer::BindDeviceClient(gizmo_server_, dispatcher(), std::move(server_end));
-        }
-    });
+        }});
 
     auto result = context().outgoing()->AddService<examples_gizmo::Service>(std::move(handler));
     if (result.is_error()) {
@@ -44,26 +43,26 @@
 
   // Offer `examples.gizmo.Service` to the driver that binds to the node.
   auto offers = fidl::VectorView<fuchsia_component_decl::wire::Offer>(arena, 1);
-  offers[0] = driver::MakeOffer<examples_gizmo::Service>(arena, component::kDefaultInstance);
+  offers[0] = fdf::MakeOffer<examples_gizmo::Service>(arena, component::kDefaultInstance);
 
   // Set the properties of the node that the child will bind to based on the child-driver.bind
   auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 6);
   // [START add_bind_properties]
   properties[0] =
-      driver::MakeProperty(arena, 1 /* BIND_PROTOCOL */, bind_fuchsia_acpi::BIND_PROTOCOL_DEVICE);
-  properties[1] = driver::MakeProperty(arena, bind_fuchsia_acpi::HID, "GOOG");
-  properties[2] = driver::MakeProperty(arena, bind_examples_gizmo_bind::MODELNAME, "GIZMO3000");
-  properties[3] = driver::MakeProperty(arena, bind_examples_gizmo_bind::GIZMOTYPE,
-                                       bind_examples_gizmo_bind::GIZMOTYPE_MEM_64K);
+      fdf::MakeProperty(arena, 1 /* BIND_PROTOCOL */, bind_fuchsia_acpi::BIND_PROTOCOL_DEVICE);
+  properties[1] = fdf::MakeProperty(arena, bind_fuchsia_acpi::HID, "GOOG");
+  properties[2] = fdf::MakeProperty(arena, bind_examples_gizmo_bind::MODELNAME, "GIZMO3000");
+  properties[3] = fdf::MakeProperty(arena, bind_examples_gizmo_bind::GIZMOTYPE,
+                                    bind_examples_gizmo_bind::GIZMOTYPE_MEM_64K);
   // [END add_bind_properties]
 
   // We are not actually offering the Exporter protocol to the child, nor using it from the child.
   // This is just to demonstrate access to these values through the auto-generated bind library.
   // [START add_fidl_bind_properties]
-  properties[4] = driver::MakeProperty(arena, bind_fuchsia_device_fs::EXPORTER,
-                                       bind_fuchsia_device_fs::EXPORTER_ZIRCONTRANSPORT);
-  properties[5] = driver::MakeProperty(arena, bind_examples_gizmo::TESTINGPROTOCOL,
-                                       bind_examples_gizmo::TESTINGPROTOCOL_ZIRCONTRANSPORT);
+  properties[4] = fdf::MakeProperty(arena, bind_fuchsia_device_fs::EXPORTER,
+                                    bind_fuchsia_device_fs::EXPORTER_ZIRCONTRANSPORT);
+  properties[5] = fdf::MakeProperty(arena, bind_examples_gizmo::TESTINGPROTOCOL,
+                                    bind_examples_gizmo::TESTINGPROTOCOL_ZIRCONTRANSPORT);
   // [END add_fidl_bind_properties]
 
   auto args = fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
@@ -90,4 +89,4 @@
 
 }  // namespace parent_driver
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<parent_driver::ParentDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<parent_driver::ParentDriver>);
diff --git a/src/bind_library/parent/parent-driver.h b/src/bind_library/parent/parent-driver.h
index 1643ab5..cfa4673 100644
--- a/src/bind_library/parent/parent-driver.h
+++ b/src/bind_library/parent/parent-driver.h
@@ -11,10 +11,11 @@
 
 namespace parent_driver {
 
-class ParentDriver : public driver::DriverBase {
+class ParentDriver : public fdf::DriverBase {
  public:
-  ParentDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("parent-driver", std::move(start_args), std::move(driver_dispatcher)) {}
+  ParentDriver(fdf::DriverStartArgs start_args,
+               fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("parent-driver", std::move(start_args), std::move(driver_dispatcher)) {}
   virtual ~ParentDriver() = default;
 
   zx::result<> Start() override;
diff --git a/src/composite_sample/controller/controller.cc b/src/composite_sample/controller/controller.cc
index b35133e..b544143 100644
--- a/src/composite_sample/controller/controller.cc
+++ b/src/composite_sample/controller/controller.cc
@@ -45,7 +45,7 @@
   auto offers = compat.CreateOffers(arena);
 
   auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 1);
-  properties[0] = driver::MakeProperty(arena, bind_examples_driver_test::PROPERTY, name);
+  properties[0] = fdf::MakeProperty(arena, bind_examples_driver_test::PROPERTY, name);
 
   auto args = fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
                   .name(arena, name)
@@ -73,4 +73,4 @@
 
 }  // namespace controller_driver
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<controller_driver::ControllerDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<controller_driver::ControllerDriver>);
diff --git a/src/composite_sample/controller/controller.h b/src/composite_sample/controller/controller.h
index 9535df5..006a9fb 100644
--- a/src/composite_sample/controller/controller.h
+++ b/src/composite_sample/controller/controller.h
@@ -5,16 +5,16 @@
 #ifndef FUCHSIA_SDK_EXAMPLES_COMPOSITE_SAMPLE_CONTROLLER_CONTROLLER_H_
 #define FUCHSIA_SDK_EXAMPLES_COMPOSITE_SAMPLE_CONTROLLER_CONTROLLER_H_
 
-#include <lib/driver/component/cpp/driver_cpp.h>
 #include <lib/driver/compat/cpp/device_server.h>
+#include <lib/driver/component/cpp/driver_cpp.h>
 
 namespace controller_driver {
 
-class ControllerDriver : public driver::DriverBase {
+class ControllerDriver : public fdf::DriverBase {
  public:
-  ControllerDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("controller_driver", std::move(start_args),
-                           std::move(driver_dispatcher)) {}
+  ControllerDriver(fdf::DriverStartArgs start_args,
+                   fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("controller_driver", std::move(start_args), std::move(driver_dispatcher)) {}
   virtual ~ControllerDriver() = default;
 
   zx::result<> Start() override;
diff --git a/src/composite_sample/controller/meta/controller-driver.cml b/src/composite_sample/controller/meta/controller-driver.cml
index b22829b..cb64fb6 100644
--- a/src/composite_sample/controller/meta/controller-driver.cml
+++ b/src/composite_sample/controller/meta/controller-driver.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libcontroller_driver.so',
+        binary: 'driver/libcontroller_driver.so',
         bind: 'meta/bind/controller-driver.bindbc',
         // Identifies the device categories, for compatibility tests. This
         // example driver uses the 'misc' category; real drivers should
diff --git a/src/composite_sample/driver/composite_sample.cc b/src/composite_sample/driver/composite_sample.cc
index 46639ba..7677ff1 100644
--- a/src/composite_sample/driver/composite_sample.cc
+++ b/src/composite_sample/driver/composite_sample.cc
@@ -30,8 +30,7 @@
 // Print the topological path for a given parent device node.
 zx::result<> CompositeSampleDriver::PrintTopologicalPath(std::string_view name) {
   // Connect to the parent device node.
-  auto parent =
-      driver::Connect<fuchsia_driver_compat::Service::Device>(*context().incoming(), name);
+  auto parent = fdf::Connect<fuchsia_driver_compat::Service::Device>(*context().incoming(), name);
   if (parent.is_error()) {
     FDF_SLOG(ERROR, "Failed to open compat service device", KV("status", parent.status_string()));
     return parent.take_error();
@@ -54,4 +53,4 @@
 
 }  // namespace composite_sample
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<composite_sample::CompositeSampleDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<composite_sample::CompositeSampleDriver>);
diff --git a/src/composite_sample/driver/composite_sample.h b/src/composite_sample/driver/composite_sample.h
index b155870..d366889 100644
--- a/src/composite_sample/driver/composite_sample.h
+++ b/src/composite_sample/driver/composite_sample.h
@@ -9,12 +9,11 @@
 
 namespace composite_sample {
 
-class CompositeSampleDriver : public driver::DriverBase {
+class CompositeSampleDriver : public fdf::DriverBase {
  public:
-  CompositeSampleDriver(driver::DriverStartArgs start_args,
-                        fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("composite-sample", std::move(start_args),
-                           std::move(driver_dispatcher)) {}
+  CompositeSampleDriver(fdf::DriverStartArgs start_args,
+                        fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("composite-sample", std::move(start_args), std::move(driver_dispatcher)) {}
 
   virtual ~CompositeSampleDriver() = default;
 
diff --git a/src/composite_sample/driver/meta/composite_sample.cml b/src/composite_sample/driver/meta/composite_sample.cml
index 162532e..fade8a1 100644
--- a/src/composite_sample/driver/meta/composite_sample.cml
+++ b/src/composite_sample/driver/meta/composite_sample.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libcomposite_sample.so',
+        binary: 'driver/libcomposite_sample.so',
         bind: 'meta/bind/composite_sample.bindbc',
         // Identifies the device categories, for compatibility tests. This
         // example driver uses the 'misc' category; real drivers should
diff --git a/src/example_driver/example_driver.cc b/src/example_driver/example_driver.cc
index d89f6ce..0f87bc6 100644
--- a/src/example_driver/example_driver.cc
+++ b/src/example_driver/example_driver.cc
@@ -35,4 +35,4 @@
 
 }  // namespace example_driver
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<example_driver::ExampleDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<example_driver::ExampleDriver>);
diff --git a/src/example_driver/example_driver.h b/src/example_driver/example_driver.h
index 528684a..f11e72f 100644
--- a/src/example_driver/example_driver.h
+++ b/src/example_driver/example_driver.h
@@ -11,10 +11,11 @@
 
 namespace example_driver {
 
-class ExampleDriver : public driver::DriverBase {
+class ExampleDriver : public fdf::DriverBase {
  public:
-  ExampleDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("example-driver", std::move(start_args), std::move(driver_dispatcher)) {}
+  ExampleDriver(fdf::DriverStartArgs start_args,
+                fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("example-driver", std::move(start_args), std::move(driver_dispatcher)) {}
   virtual ~ExampleDriver() = default;
 
   zx::result<> Start() override;
diff --git a/src/example_driver/example_driver_unittest.cc b/src/example_driver/example_driver_unittest.cc
index 1024b65..f12d67b 100644
--- a/src/example_driver/example_driver_unittest.cc
+++ b/src/example_driver/example_driver_unittest.cc
@@ -9,5 +9,5 @@
 TEST(ExampleDriverTest, GreetingTest) {
   std::string name = "example-driver";
   std::string expected = "Hello from example-driver";
-  EXPECT_EQ(example_driver::greeting(name), expected);
+  EXPECT_EQ(example_fdf::greeting(name), expected);
 }
diff --git a/src/example_driver/meta/example_driver.cml b/src/example_driver/meta/example_driver.cml
index 3d7d19d..ed4e8c4 100644
--- a/src/example_driver/meta/example_driver.cml
+++ b/src/example_driver/meta/example_driver.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libexample_driver.so',
+        binary: 'driver/libexample_driver.so',
         bind: 'meta/bind/example_driver.bindbc',
         // Identifies the device categories, for compatibility tests. This
         // example driver uses the 'misc' category; real drivers should
diff --git a/src/i2c_temperature/controller/i2c_controller.cc b/src/i2c_temperature/controller/i2c_controller.cc
index e97a959..d9dc3eb 100644
--- a/src/i2c_temperature/controller/i2c_controller.cc
+++ b/src/i2c_temperature/controller/i2c_controller.cc
@@ -16,11 +16,10 @@
 
   // Serve the fuchsia.hardware.i2c/Device protocol to clients through the
   // fuchsia.hardware.i2c/Service wrapper.
-  fuchsia_hardware_i2c::Service::InstanceHandler handler({
-    .device = [this](fidl::ServerEnd<fuchsia_hardware_i2c::Device> request) -> void {
+  fuchsia_hardware_i2c::Service::InstanceHandler handler(
+      {.device = [this](fidl::ServerEnd<fuchsia_hardware_i2c::Device> request) -> void {
         I2cDeviceServer::BindDeviceClient(i2c_server_, dispatcher(), std::move(request));
-      }
-  });
+      }});
   auto result = context().outgoing()->AddService<fuchsia_hardware_i2c::Service>(std::move(handler));
   if (result.is_error()) {
     FDF_SLOG(ERROR, "Failed to add service", KV("status", result.status_string()));
@@ -55,16 +54,16 @@
   // [START add_child_offer]
   // Offer `fuchsia.hardware.i2c.Device` to drivers that bind to the node.
   auto service_offer =
-      driver::MakeOffer<fuchsia_hardware_i2c::Service>(arena, component::kDefaultInstance);
+      fdf::MakeOffer<fuchsia_hardware_i2c::Service>(arena, component::kDefaultInstance);
   // [END add_child_offer]
   offers.push_back(service_offer);
 
   // [START add_child_properties]
   // Set the properties of the node for drivers to target.
   auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
-  properties[0] = driver::MakeProperty(arena, bind_fuchsia_hardware_i2c::SERVICE,
-                                       bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT);
-  properties[1] = driver::MakeProperty(arena, 0x0A02 /* BIND_I2C_ADDRESS */, 0xff);
+  properties[0] = fdf::MakeProperty(arena, bind_fuchsia_hardware_i2c::SERVICE,
+                                    bind_fuchsia_hardware_i2c::SERVICE_ZIRCONTRANSPORT);
+  properties[1] = fdf::MakeProperty(arena, 0x0A02 /* BIND_I2C_ADDRESS */, 0xff);
   // [END add_child_properties]
 
   // [START add_child_node]
@@ -95,4 +94,4 @@
 
 }  // namespace i2c_temperature
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<i2c_temperature::I2cTemperatureController>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<i2c_temperature::I2cTemperatureController>);
diff --git a/src/i2c_temperature/controller/i2c_controller.h b/src/i2c_temperature/controller/i2c_controller.h
index 883f31d..a305743 100644
--- a/src/i2c_temperature/controller/i2c_controller.h
+++ b/src/i2c_temperature/controller/i2c_controller.h
@@ -14,12 +14,12 @@
 
 // Sample driver that implements a `fuchsia.hardware.i2c` bus controller and emulates the
 // behavior of a temperature sensor device to interact with the i2c temperature driver.
-class I2cTemperatureController : public driver::DriverBase {
+class I2cTemperatureController : public fdf::DriverBase {
  public:
-  I2cTemperatureController(driver::DriverStartArgs start_args,
-                           fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("i2c-temperature-controller", std::move(start_args),
-                           std::move(driver_dispatcher)) {}
+  I2cTemperatureController(fdf::DriverStartArgs start_args,
+                           fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("i2c-temperature-controller", std::move(start_args),
+                        std::move(driver_dispatcher)) {}
 
   virtual ~I2cTemperatureController() = default;
 
diff --git a/src/i2c_temperature/controller/i2c_server.cc b/src/i2c_temperature/controller/i2c_server.cc
index 780ff7a..4fba8f1 100644
--- a/src/i2c_temperature/controller/i2c_server.cc
+++ b/src/i2c_temperature/controller/i2c_server.cc
@@ -86,6 +86,10 @@
   completer.ReplySuccess(read_results);
 }
 
+void I2cDeviceServer::GetName(GetNameCompleter::Sync& completer) {
+  completer.ReplySuccess("test-i2c-server");
+}
+
 // Process data transfer WRITE requests. Parse the command from the driver and update:
 //   - kSoftResetCommand: Reset internal temperature to initial value
 //   - kStartMeasurementCommand: Increment internal temperature value
diff --git a/src/i2c_temperature/controller/i2c_server.h b/src/i2c_temperature/controller/i2c_server.h
index 5472e17..5d5282a 100644
--- a/src/i2c_temperature/controller/i2c_server.h
+++ b/src/i2c_temperature/controller/i2c_server.h
@@ -16,7 +16,7 @@
   static constexpr uint32_t kTempIncrement = 5;
 
  public:
-  I2cDeviceServer(driver::Logger* logger) : logger_(logger), temperature_(kStartingTemp) {}
+  explicit I2cDeviceServer(fdf::Logger* logger) : logger_(logger), temperature_(kStartingTemp) {}
 
   static fidl::ServerBindingRef<fuchsia_hardware_i2c::Device> BindDeviceClient(
       std::shared_ptr<I2cDeviceServer> server_impl, async_dispatcher_t* dispatcher,
@@ -26,11 +26,12 @@
   // fidl::WireServer<fuchsia_hardware_i2c::Device>
 
   void Transfer(TransferRequestView request, TransferCompleter::Sync& completer) override;
+  void GetName(GetNameCompleter::Sync& completer) override;
 
  private:
   void HandleWrite(const fidl::VectorView<uint8_t> write_data);
 
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   uint32_t temperature_;
 };
 
diff --git a/src/i2c_temperature/controller/meta/i2c_controller.cml b/src/i2c_temperature/controller/meta/i2c_controller.cml
index 1d61d7c..117bf11 100644
--- a/src/i2c_temperature/controller/meta/i2c_controller.cml
+++ b/src/i2c_temperature/controller/meta/i2c_controller.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libi2c_controller.so',
+        binary: 'driver/libi2c_controller.so',
         bind: 'meta/bind/i2c_controller.bindbc',
         // Identifies the device categories, for compatibility tests.
         device_categories: [
diff --git a/src/i2c_temperature/driver/i2c_temperature.cc b/src/i2c_temperature/driver/i2c_temperature.cc
index e2f1f6b..9320d26 100644
--- a/src/i2c_temperature/driver/i2c_temperature.cc
+++ b/src/i2c_temperature/driver/i2c_temperature.cc
@@ -4,7 +4,6 @@
 
 #include "i2c_temperature.h"
 
-#include <fidl/examples.i2c.temperature/cpp/wire.h>
 #include <lib/driver/component/cpp/service_client.h>
 
 #include "constants.h"
@@ -22,13 +21,11 @@
   // Serve the examples.i2c.temperature/Device protocol to clients through the
   // examples.i2c.temperature/Service wrapper.
   examples_i2c_temperature::Service::InstanceHandler handler({
-    .device = [this](fidl::ServerEnd<examples_i2c_temperature::Device> request) -> void {
-        I2cTemperatureServer::BindDeviceClient(dispatcher(), &logger(), i2c_channel_,
-                                               std::move(request));
-      }
+      .device = fit::bind_member<&I2cTemperatureDriver::Serve>(this),
   });
 
-  auto result = context().outgoing()->AddService<examples_i2c_temperature::Service>(std::move(handler));
+  auto result =
+      context().outgoing()->AddService<examples_i2c_temperature::Service>(std::move(handler));
   if (result.is_error()) {
     FDF_SLOG(ERROR, "Failed to add service", KV("status", result.status_string()));
     return result.take_error();
@@ -51,8 +48,7 @@
 
 // Connect to the `fuchsia.hardware.i2c/Device` protocol offered by the parent device node.
 zx::result<> I2cTemperatureDriver::SetupI2cChannel() {
-  auto client_endpoint =
-      driver::Connect<fuchsia_hardware_i2c::Service::Device>(*context().incoming());
+  auto client_endpoint = fdf::Connect<fuchsia_hardware_i2c::Service::Device>(*context().incoming());
   if (client_endpoint.status_value() != ZX_OK) {
     FDF_SLOG(ERROR, "Failed to setup I2cChannel", KV("status", client_endpoint.status_string()));
     return client_endpoint.take_error();
@@ -75,18 +71,42 @@
   }
   compat_context_ = std::move(*compat_result);
 
-  auto service_path = std::string(examples_i2c_temperature::Service::Name) + "/" +
-                      component::kDefaultInstance + "/" +
-                      examples_i2c_temperature::Service::Device::Name;
-  auto status = compat_context_->devfs_exporter().ExportSync(
-      service_path, compat_context_->TopologicalPath(name()), fuchsia_device_fs::ExportOptions());
-  if (status != ZX_OK) {
-    FDF_SLOG(ERROR, "Failed to export to devfs.", KV("status", zx_status_get_string(status)));
+  zx::result connection = this->context().incoming()->Connect<fuchsia_device_fs::Exporter>();
+  if (connection.is_error()) {
+    FDF_SLOG(ERROR, "Failed to connect to fuchsia_device_fs::Exporter",
+             KV("status", connection.status_string()));
+    node().reset();
+    return;
+  }
+  fidl::WireSyncClient devfs_exporter{std::move(connection.value())};
+
+  zx::result connector = devfs_connector_.Bind(dispatcher());
+  if (connector.is_error()) {
+    FDF_SLOG(ERROR, "Failed to bind devfs_connector: %s", KV("status", connector.status_string()));
+    node().reset();
+    return;
+  }
+  fidl::WireResult export_result = devfs_exporter->ExportV2(
+      std::move(connector.value()),
+      fidl::StringView::FromExternal(compat_context_->TopologicalPath(name())),
+      fidl::StringView(), fuchsia_device_fs::ExportOptions());
+  if (!export_result.ok()) {
+    FDF_SLOG(ERROR, "Failed to export to devfs: %s", KV("status", export_result.status_string()));
+    node().reset();
+    return;
+  }
+  if (export_result.value().is_error()) {
+    FDF_SLOG(ERROR, "Failed to export to devfs: %s",
+             KV("status", zx_status_get_string(export_result.value().error_value())));
     node().reset();
     return;
   }
 }
 
+void I2cTemperatureDriver::Serve(fidl::ServerEnd<examples_i2c_temperature::Device> request) {
+  I2cTemperatureServer::BindDeviceClient(dispatcher(), &logger(), i2c_channel_, std::move(request));
+}
+
 }  // namespace i2c_temperature
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<i2c_temperature::I2cTemperatureDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<i2c_temperature::I2cTemperatureDriver>);
diff --git a/src/i2c_temperature/driver/i2c_temperature.h b/src/i2c_temperature/driver/i2c_temperature.h
index ec49b1e..4a958a3 100644
--- a/src/i2c_temperature/driver/i2c_temperature.h
+++ b/src/i2c_temperature/driver/i2c_temperature.h
@@ -8,17 +8,20 @@
 #include <lib/driver/compat/cpp/compat.h>
 #include <lib/driver/compat/cpp/context.h>
 #include <lib/driver/component/cpp/driver_cpp.h>
+#include <lib/driver/devfs/cpp/connector.h>
+#include <fidl/examples.i2c.temperature/cpp/wire.h>
 
 #include "i2c_channel.h"
 
 namespace i2c_temperature {
 
 // Sample driver for a virtual temperature sensor device connected to an I2C bus controller.
-class I2cTemperatureDriver : public driver::DriverBase {
+class I2cTemperatureDriver : public fdf::DriverBase {
  public:
-  I2cTemperatureDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("i2c-temperature", std::move(start_args), std::move(driver_dispatcher)) {
-  }
+  I2cTemperatureDriver(fdf::DriverStartArgs start_args,
+                       fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("i2c-temperature", std::move(start_args), std::move(driver_dispatcher)),
+        devfs_connector_(fit::bind_member<&I2cTemperatureDriver::Serve>(this)) {}
 
   virtual ~I2cTemperatureDriver() = default;
 
@@ -27,7 +30,9 @@
  private:
   zx::result<> SetupI2cChannel();
   void InitializeCompatService(zx::result<std::shared_ptr<compat::Context>> result);
+  void Serve(fidl::ServerEnd<examples_i2c_temperature::Device> request);
 
+  driver_devfs::Connector<examples_i2c_temperature::Device> devfs_connector_;
   std::shared_ptr<compat::Context> compat_context_;
   std::shared_ptr<I2cChannel> i2c_channel_;
 };
diff --git a/src/i2c_temperature/driver/meta/i2c_temperature.cml b/src/i2c_temperature/driver/meta/i2c_temperature.cml
index fb0db09..b25e22a 100644
--- a/src/i2c_temperature/driver/meta/i2c_temperature.cml
+++ b/src/i2c_temperature/driver/meta/i2c_temperature.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libi2c_temperature.so',
+        binary: 'driver/libi2c_temperature.so',
         bind: 'meta/bind/i2c_temperature.bindbc',
         // Identifies the device categories, for compatibility tests.
         device_categories: [
diff --git a/src/i2c_temperature/driver/temperature_server.cc b/src/i2c_temperature/driver/temperature_server.cc
index 68f90e2..5cc6f9e 100644
--- a/src/i2c_temperature/driver/temperature_server.cc
+++ b/src/i2c_temperature/driver/temperature_server.cc
@@ -14,7 +14,7 @@
 // Static
 // Handle incoming connection requests from FIDL clients
 fidl::ServerBindingRef<examples_i2c_temperature::Device> I2cTemperatureServer::BindDeviceClient(
-    async_dispatcher_t* dispatcher, driver::Logger* logger, std::weak_ptr<I2cChannel> i2c_channel,
+    async_dispatcher_t* dispatcher, fdf::Logger* logger, std::weak_ptr<I2cChannel> i2c_channel,
     fidl::ServerEnd<examples_i2c_temperature::Device> request) {
   // Bind each connection request to the shared instance.
   auto server_impl = std::make_unique<I2cTemperatureServer>(logger, i2c_channel);
diff --git a/src/i2c_temperature/driver/temperature_server.h b/src/i2c_temperature/driver/temperature_server.h
index 5cd6fa7..6f2d8dc 100644
--- a/src/i2c_temperature/driver/temperature_server.h
+++ b/src/i2c_temperature/driver/temperature_server.h
@@ -15,11 +15,11 @@
 // FIDL server implementation for the `examples.i2c.temperature/Device` protocol
 class I2cTemperatureServer : public fidl::WireServer<examples_i2c_temperature::Device> {
  public:
-  I2cTemperatureServer(driver::Logger* logger, std::weak_ptr<I2cChannel> i2c_channel)
+  I2cTemperatureServer(fdf::Logger* logger, std::weak_ptr<I2cChannel> i2c_channel)
       : logger_(logger), i2c_channel_(i2c_channel) {}
 
   static fidl::ServerBindingRef<examples_i2c_temperature::Device> BindDeviceClient(
-      async_dispatcher_t* dispatcher, driver::Logger* logger, std::weak_ptr<I2cChannel> i2c_channel,
+      async_dispatcher_t* dispatcher, fdf::Logger* logger, std::weak_ptr<I2cChannel> i2c_channel,
       fidl::ServerEnd<examples_i2c_temperature::Device> request);
 
   void OnUnbound(fidl::UnbindInfo info,
@@ -32,7 +32,7 @@
   void ResetSensor(ResetSensorCompleter::Sync& completer) override;
 
  private:
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   std::weak_ptr<I2cChannel> i2c_channel_;
 };
 
diff --git a/src/input_sample/input_sample.cc b/src/input_sample/input_sample.cc
index b1a9ef6..46e7f96 100644
--- a/src/input_sample/input_sample.cc
+++ b/src/input_sample/input_sample.cc
@@ -15,18 +15,6 @@
       std::make_shared<input_report_reader::InputReportReaderManager<SampleInputReport>>();
   SendFakeReport();
 
-  // Add the fuchsia.input.report/InputDevice protocol to be served as "/svc/input-sample"
-  auto result = context().outgoing()->component().AddUnmanagedProtocol<fuchsia_input_report::InputDevice>(
-      [this](fidl::ServerEnd<fuchsia_input_report::InputDevice> request) {
-        InputSampleServer::BindDeviceClient(&logger(), dispatcher(), input_report_readers_,
-                                            std::move(request));
-      },
-      name());
-  if (result.is_error()) {
-    FDF_SLOG(ERROR, "Failed to add protocol.", KV("status", result.status_string()));
-    return result.take_error();
-  }
-
   // Initialize the driver compat service context.
   compat::Context::ConnectAndCreate(
       &context(), dispatcher(),
@@ -45,13 +33,35 @@
     return;
   }
   compat_context_ = std::move(*compat_result);
-  child_ = compat::DeviceServer(std::string(name()), 0, compat_context_->TopologicalPath(name()));
 
-  auto status = compat_context_->devfs_exporter().ExportSync(name(), child_->topological_path(),
-                                                             fuchsia_device_fs::ExportOptions(),
-                                                             /* INPUT_REPORT */ 26);
-  if (status != ZX_OK) {
-    FDF_SLOG(ERROR, "Failed to export to devfs.", KV("status", zx_status_get_string(status)));
+   // Export to devfs.
+  zx::result connection = this->context().incoming()->Connect<fuchsia_device_fs::Exporter>();
+  if (connection.is_error()) {
+    FDF_SLOG(ERROR, "Failed to connect to fuchsia_device_fs::Exporter",
+             KV("status", connection.status_string()));
+    node().reset();
+    return;
+  }
+  fidl::WireSyncClient devfs_exporter{std::move(connection.value())};
+
+  zx::result connector = devfs_connector_.Bind(dispatcher());
+  if (connector.is_error()) {
+    FDF_SLOG(ERROR, "Failed to bind devfs_connector: %s", KV("status", connector.status_string()));
+    node().reset();
+    return;
+  }
+  fidl::WireResult export_result = devfs_exporter->ExportV2(
+      std::move(connector.value()),
+      fidl::StringView::FromExternal(compat_context_->TopologicalPath(name())), "input-report",
+      fuchsia_device_fs::ExportOptions());
+  if (!export_result.ok()) {
+    FDF_SLOG(ERROR, "Failed to export to devfs: %s", KV("status", export_result.status_string()));
+    node().reset();
+    return;
+  }
+  if (export_result.value().is_error()) {
+    FDF_SLOG(ERROR, "Failed to export to devfs: %s",
+             KV("status", zx_status_get_string(export_result.value().error_value())));
     node().reset();
     return;
   }
@@ -73,6 +83,11 @@
       dispatcher(), [this]() mutable { SendFakeReport(); }, zx::sec(1));
 }
 
+void InputSampleDriver::Serve(fidl::ServerEnd<fuchsia_input_report::InputDevice> request) {
+  InputSampleServer::BindDeviceClient(&logger(), dispatcher(), input_report_readers_,
+                                      std::move(request));
+}
+
 }  // namespace input_sample
 
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<input_sample::InputSampleDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<input_sample::InputSampleDriver>);
diff --git a/src/input_sample/input_sample.h b/src/input_sample/input_sample.h
index 1e8834a..e8227dd 100644
--- a/src/input_sample/input_sample.h
+++ b/src/input_sample/input_sample.h
@@ -8,16 +8,20 @@
 #include <lib/driver/compat/cpp/compat.h>
 #include <lib/driver/compat/cpp/context.h>
 #include <lib/driver/component/cpp/driver_cpp.h>
+#include <lib/driver/devfs/cpp/connector.h>
 
 #include "input_server.h"
 
 namespace input_sample {
 
 // Sample driver for a virtual input device that generates input reports.
-class InputSampleDriver : public driver::DriverBase {
+class InputSampleDriver : public fdf::DriverBase {
  public:
-  InputSampleDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("input-sample", std::move(start_args), std::move(driver_dispatcher)) {}
+  InputSampleDriver(fdf::DriverStartArgs start_args,
+                    fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("input-sample", std::move(start_args), std::move(driver_dispatcher)),
+        devfs_connector_(fit::bind_member<&InputSampleDriver::Serve>(this)) {}
+
   virtual ~InputSampleDriver() = default;
 
   zx::result<> Start() override;
@@ -25,8 +29,9 @@
  private:
   void SendFakeReport();
   void InitializeCompatService(zx::result<std::shared_ptr<compat::Context>> result);
+  void Serve(fidl::ServerEnd<fuchsia_input_report::InputDevice> request);
 
-  std::optional<compat::DeviceServer> child_;
+  driver_devfs::Connector<fuchsia_input_report::InputDevice> devfs_connector_;
   std::shared_ptr<compat::Context> compat_context_;
   std::shared_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
       input_report_readers_;
diff --git a/src/input_sample/input_server.cc b/src/input_sample/input_server.cc
index 07f7767..bb403e6 100644
--- a/src/input_sample/input_server.cc
+++ b/src/input_sample/input_server.cc
@@ -34,7 +34,7 @@
 // Static
 // Handle incoming connection requests from FIDL clients
 fidl::ServerBindingRef<fuchsia_input_report::InputDevice> InputSampleServer::BindDeviceClient(
-    driver::Logger* logger, async_dispatcher_t* dispatcher,
+    fdf::Logger* logger, async_dispatcher_t* dispatcher,
     std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
         input_report_readers,
     fidl::ServerEnd<fuchsia_input_report::InputDevice> request) {
diff --git a/src/input_sample/input_server.h b/src/input_sample/input_server.h
index ac2a4ef..0131a63 100644
--- a/src/input_sample/input_server.h
+++ b/src/input_sample/input_server.h
@@ -28,13 +28,13 @@
 // FIDL server implementation for the `fuchsia.input.report/InputDevice` protocol
 class InputSampleServer : public fidl::WireServer<fuchsia_input_report::InputDevice> {
  public:
-  InputSampleServer(driver::Logger* logger, async_dispatcher_t* dispatcher,
+  InputSampleServer(fdf::Logger* logger, async_dispatcher_t* dispatcher,
                     std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
                         input_report_readers)
       : logger_(logger), dispatcher_(dispatcher), input_report_readers_(input_report_readers) {}
 
   static fidl::ServerBindingRef<fuchsia_input_report::InputDevice> BindDeviceClient(
-      driver::Logger* logger, async_dispatcher_t* dispatcher,
+      fdf::Logger* logger, async_dispatcher_t* dispatcher,
       std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
           input_report_readers,
       fidl::ServerEnd<fuchsia_input_report::InputDevice> request);
@@ -66,7 +66,7 @@
   }
 
  private:
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   async_dispatcher_t* const dispatcher_;
   std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
       input_report_readers_;
diff --git a/src/input_sample/meta/input_sample.cml b/src/input_sample/meta/input_sample.cml
index 45c2fa2..36a31a0 100644
--- a/src/input_sample/meta/input_sample.cml
+++ b/src/input_sample/meta/input_sample.cml
@@ -7,7 +7,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libinput_sample.so',
+        binary: 'driver/libinput_sample.so',
         bind: 'meta/bind/input_sample.bindbc',
         // Identifies the device categories, for compatibility tests.
         device_categories: [
diff --git a/src/qemu_edu/drivers/BUILD.bazel b/src/qemu_edu/drivers/BUILD.bazel
index d02e286..9227fb6 100644
--- a/src/qemu_edu/drivers/BUILD.bazel
+++ b/src/qemu_edu/drivers/BUILD.bazel
@@ -39,6 +39,7 @@
         "//src/qemu_edu/fidl:examples.qemuedu_cc",
         "@fuchsia_sdk//fidl/fuchsia.hardware.pci:fuchsia.hardware.pci_llcpp_cc",
         "@fuchsia_sdk//pkg/driver_compat",
+        "@fuchsia_sdk//pkg/driver_devfs_cpp",
         "@fuchsia_sdk//pkg/driver_component_cpp",
         "@fuchsia_sdk//pkg/hwreg",
         "@fuchsia_sdk//pkg/mmio",
diff --git a/src/qemu_edu/drivers/edu_device.h b/src/qemu_edu/drivers/edu_device.h
index f20c721..559ad2c 100644
--- a/src/qemu_edu/drivers/edu_device.h
+++ b/src/qemu_edu/drivers/edu_device.h
@@ -59,7 +59,7 @@
   // [END class_header]
   // [START public_main]
  public:
-  explicit QemuEduDevice(driver::Logger* logger, async_dispatcher_t* dispatcher,
+  explicit QemuEduDevice(fdf::Logger* logger, async_dispatcher_t* dispatcher,
                          fidl::ClientEnd<fuchsia_hardware_pci::Device> pci)
       : dispatcher_(dispatcher), logger_(logger), pci_(std::move(pci)) {}
 
@@ -81,7 +81,7 @@
 
   async_dispatcher_t* const dispatcher_;
 
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   fidl::WireSyncClient<fuchsia_hardware_pci::Device> pci_;
   std::optional<fdf::MmioBuffer> mmio_;
   zx::interrupt irq_;
diff --git a/src/qemu_edu/drivers/edu_server.h b/src/qemu_edu/drivers/edu_server.h
index 4e47c4e..1ca83cd 100644
--- a/src/qemu_edu/drivers/edu_server.h
+++ b/src/qemu_edu/drivers/edu_server.h
@@ -20,11 +20,11 @@
 // FIDL server implementation for the `examples.qemuedu/Device` protocol.
 class QemuEduServer : public fidl::WireServer<examples_qemuedu::Device> {
  public:
-  explicit QemuEduServer(driver::Logger* logger, std::weak_ptr<edu_device::QemuEduDevice> device)
+  explicit QemuEduServer(fdf::Logger* logger, std::weak_ptr<edu_device::QemuEduDevice> device)
       : logger_(logger), device_(std::move(device)) {}
 
   static fidl::ServerBindingRef<examples_qemuedu::Device> BindDeviceClient(
-      driver::Logger* logger, async_dispatcher_t* dispatcher,
+      fdf::Logger* logger, async_dispatcher_t* dispatcher,
       std::weak_ptr<edu_device::QemuEduDevice> device,
       fidl::ServerEnd<examples_qemuedu::Device> request) {
     // Bind each connection request to a unique FIDL server instance
@@ -49,7 +49,7 @@
   void LivenessCheck(LivenessCheckCompleter::Sync& completer) override;
 
  private:
-  driver::Logger* logger_;
+  fdf::Logger* logger_;
   std::weak_ptr<edu_device::QemuEduDevice> device_;
 };
 // [END fidl_server]
diff --git a/src/qemu_edu/drivers/meta/qemu_edu.cml b/src/qemu_edu/drivers/meta/qemu_edu.cml
index fb32c56..40ac95e 100644
--- a/src/qemu_edu/drivers/meta/qemu_edu.cml
+++ b/src/qemu_edu/drivers/meta/qemu_edu.cml
@@ -8,7 +8,7 @@
     ],
     program: {
         runner: 'driver',
-        binary: 'lib/libqemu_edu.so',
+        binary: 'driver/libqemu_edu.so',
         bind: 'meta/bind/qemu_edu.bindbc',
         // Identifies the device categories, for compatibility tests. This
         // example driver uses the 'misc' category; real drivers should
diff --git a/src/qemu_edu/drivers/qemu_edu.cc b/src/qemu_edu/drivers/qemu_edu.cc
index fe1209b..aa11d7d 100644
--- a/src/qemu_edu/drivers/qemu_edu.cc
+++ b/src/qemu_edu/drivers/qemu_edu.cc
@@ -24,8 +24,7 @@
   // [END start_method_start]
   // [START connect_device]
   // Connect to the parent device node.
-  auto compat_parent =
-      driver::Connect<fuchsia_driver_compat::Service::Device>(*context().incoming());
+  auto compat_parent = fdf::Connect<fuchsia_driver_compat::Service::Device>(*context().incoming());
   if (compat_parent.is_error()) {
     FDF_SLOG(ERROR, "Failed to connect to compat", KV("status", compat_parent.status_string()));
     return compat_parent.take_error();
@@ -68,9 +67,7 @@
   // [START serve_outgoing]
   // Serve the examples.qemuedu/Service capability.
   examples_qemuedu::Service::InstanceHandler handler({
-    .device = [this](fidl::ServerEnd<examples_qemuedu::Device> request) -> void {
-        QemuEduServer::BindDeviceClient(&logger(), dispatcher(), device_, std::move(request));
-      }
+      .device = fit::bind_member<&QemuEduDriver::Serve>(this),
   });
 
   auto result = context().outgoing()->AddService<examples_qemuedu::Service>(std::move(handler));
@@ -92,26 +89,44 @@
           return;
         }
         compat_context_ = std::move(result.value());
-
         // Construct a devfs path that matches the device nodes topological path
-        auto devfs_path = compat_context_->TopologicalPath(name());
-        auto service_path = std::string(examples_qemuedu::Service::Name) + "/" +
-                            component::kDefaultInstance + "/" +
-                            examples_qemuedu::Service::Device::Name;
+        std::string devfs_path = compat_context_->TopologicalPath(name());
 
-        // Export an entry to devfs for examples.qemuedu as a generic device
-        auto status = compat_context_->devfs_exporter().ExportSync(
-            service_path, devfs_path, fuchsia_device_fs::ExportOptions(), 0);
-        if (status != ZX_OK) {
+        // Export to devfs.
+        zx::result connection = this->context().incoming()->Connect<fuchsia_device_fs::Exporter>();
+        if (connection.is_error()) {
+          FDF_SLOG(ERROR, "Failed to connect to fuchsia_device_fs::Exporter",
+                   KV("status", connection.status_string()));
+          node().reset();
+          return;
+        }
+        fidl::WireSyncClient devfs_exporter{std::move(connection.value())};
+
+        zx::result connector = devfs_connector_.Bind(dispatcher());
+        if (connector.is_error()) {
+          FDF_SLOG(ERROR, "Failed to bind devfs_connector: %s",
+                   KV("status", connector.status_string()));
+          node().reset();
+          return;
+        }
+        fidl::WireResult export_result = devfs_exporter->ExportV2(
+            std::move(connector.value()),
+            fidl::StringView::FromExternal(devfs_path),
+            fidl::StringView(), fuchsia_device_fs::ExportOptions());
+        if (!export_result.ok()) {
           FDF_SLOG(ERROR, "Failed to export to devfs: %s",
-                   KV("status", zx_status_get_string(status)));
-          // Reset the node to signal unbind to the driver framework.
+                   KV("status", export_result.status_string()));
+          node().reset();
+          return;
+        }
+        if (export_result.value().is_error()) {
+          FDF_SLOG(ERROR, "Failed to export to devfs: %s",
+                   KV("status", zx_status_get_string(export_result.value().error_value())));
           node().reset();
           return;
         }
 
-        FDF_SLOG(INFO, "Exported", KV("service_path", service_path.c_str()),
-                 KV("devfs_path", devfs_path.c_str()));
+        FDF_SLOG(INFO, "Exported", KV("devfs_path", devfs_path.c_str()));
       });
   // [END devfs_export]
 
@@ -120,11 +135,15 @@
 }
 // [END start_method_end]
 
+void QemuEduDriver::Serve(fidl::ServerEnd<examples_qemuedu::Device> request) {
+  QemuEduServer::BindDeviceClient(&logger(), dispatcher(), device_, std::move(request));
+}
+
 // [START namespace_end]
 }  // namespace qemu_edu
 // [END namespace_end]
 
 // [START driver_hook]
 // Register driver hooks with the framework
-FUCHSIA_DRIVER_RECORD_CPP_V2(driver::Record<qemu_edu::QemuEduDriver>);
+FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<qemu_edu::QemuEduDriver>);
 // [END driver_hook]
diff --git a/src/qemu_edu/drivers/qemu_edu.h b/src/qemu_edu/drivers/qemu_edu.h
index ff8f1a4..4a26f86 100644
--- a/src/qemu_edu/drivers/qemu_edu.h
+++ b/src/qemu_edu/drivers/qemu_edu.h
@@ -6,8 +6,10 @@
 #define FUCHSIA_SDK_EXAMPLES_QEMU_EDU_DRIVERS_QEMU_EDU_H_
 
 // [START imports]
-#include <lib/driver/component/cpp/driver_cpp.h>
 #include <lib/driver/compat/cpp/context.h>
+#include <lib/driver/component/cpp/driver_cpp.h>
+#include <lib/driver/devfs/cpp/connector.h>
+#include <fidl/examples.qemuedu/cpp/wire.h>
 // [END imports]
 
 // [START hw_imports]
@@ -19,12 +21,14 @@
 // [END namespace_start]
 
 // [START class_header]
-class QemuEduDriver : public driver::DriverBase {
+class QemuEduDriver : public fdf::DriverBase {
   // [END class_header]
   // [START public_main]
  public:
-  QemuEduDriver(driver::DriverStartArgs start_args, fdf::UnownedDispatcher driver_dispatcher)
-      : driver::DriverBase("qemu-edu", std::move(start_args), std::move(driver_dispatcher)) {}
+  QemuEduDriver(fdf::DriverStartArgs start_args,
+                fdf::UnownedSynchronizedDispatcher driver_dispatcher)
+      : fdf::DriverBase("qemu-edu", std::move(start_args), std::move(driver_dispatcher)),
+        devfs_connector_(fit::bind_member<&QemuEduDriver::Serve>(this)) {}
 
   virtual ~QemuEduDriver() = default;
 
@@ -34,6 +38,9 @@
 
   // [START private_main]
  private:
+  void Serve(fidl::ServerEnd<examples_qemuedu::Device> request);
+
+  driver_devfs::Connector<examples_qemuedu::Device> devfs_connector_;
   std::unique_ptr<compat::Context> compat_context_;
   // [END private_main]
 
diff --git a/third_party/sdk-integration b/third_party/sdk-integration
index a43e2e0..90f105d 160000
--- a/third_party/sdk-integration
+++ b/third_party/sdk-integration
@@ -1 +1 @@
-Subproject commit a43e2e0504a5c57446c5d86d7668ffb0682f1edf
+Subproject commit 90f105d158c93262b18d11e1861b4f3b440311ea