[bt][host] Migrate ControllerTest to pw_async

Bug: 100594
Test: fx test //src/connectivity/bluetooth/core/bt-host
Change-Id: Iae9e972a754eb91307f75fe46287eff91245a0eb
diff --git a/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property.h b/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property.h
index c57c157..55f042d 100644
--- a/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property.h
+++ b/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property.h
@@ -5,14 +5,9 @@
 #ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_WINDOWED_INSPECT_NUMERIC_PROPERTY_H_
 #define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_WINDOWED_INSPECT_NUMERIC_PROPERTY_H_
 
-#include <lib/async/cpp/time.h>
-
 #include <optional>
 #include <queue>
 
-#include <pw_async_fuchsia/util.h>
-
-#include "lib/zx/time.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/assert.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/inspect.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/smart_task.h"
@@ -33,9 +28,10 @@
   // |min_resolution| is the smallest duration between changes such that they are reversed
   // independently. Changes closer to this interval may be batched together for expiry, biased
   // towards earlier expiry than |expiry_duration|. May be 0 (default) to disable batching.
-  explicit WindowedInspectNumericProperty(pw::async::Dispatcher& pw_dispatcher,
-                                          zx::duration expiry_duration = zx::min(10),
-                                          zx::duration min_resolution = zx::duration())
+  explicit WindowedInspectNumericProperty(
+      pw::async::Dispatcher& pw_dispatcher,
+      pw::chrono::SystemClock::duration expiry_duration = std::chrono::minutes(10),
+      pw::chrono::SystemClock::duration min_resolution = pw::chrono::SystemClock::duration())
       : expiry_duration_(expiry_duration),
         min_resolution_(min_resolution),
         expiry_task_(pw_dispatcher,
@@ -80,7 +76,7 @@
   // Add the given value to the value of this numeric metric.
   void Add(ValueT value) {
     property_.Add(value);
-    zx::time now = pw_async_fuchsia::TimepointToZxTime(pw_dispatcher_.now());
+    pw::chrono::SystemClock::time_point now = pw_dispatcher_.now();
     if (!values_.empty()) {
       // If the most recent change's age is less than |min_resolution_|, merge this change to it
       if (now < values_.back().first + min_resolution_) {
@@ -102,17 +98,17 @@
     }
 
     auto oldest_value = values_.front();
-    zx::time oldest_value_time = oldest_value.first;
-    zx::time expiry_time = expiry_duration_ + oldest_value_time;
-    expiry_task_.PostAt(pw_async_fuchsia::ZxTimeToTimepoint(expiry_time));
+    pw::chrono::SystemClock::time_point oldest_value_time = oldest_value.first;
+    pw::chrono::SystemClock::time_point expiry_time = expiry_duration_ + oldest_value_time;
+    expiry_task_.PostAt(expiry_time);
   }
 
   // This is not very space efficient, requiring a node for every value during the expiry_duration_.
-  std::queue<std::pair<zx::time, ValueT>> values_;
+  std::queue<std::pair<pw::chrono::SystemClock::time_point, ValueT>> values_;
 
   NumericPropertyT property_;
-  zx::duration expiry_duration_;
-  zx::duration min_resolution_;
+  pw::chrono::SystemClock::duration expiry_duration_;
+  pw::chrono::SystemClock::duration min_resolution_;
 
   using SelfT = WindowedInspectNumericProperty<NumericPropertyT, ValueT>;
   SmartTask expiry_task_;
diff --git a/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property_unittest.cc b/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property_unittest.cc
index 4f0a68f..1595562 100644
--- a/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/common/windowed_inspect_numeric_property_unittest.cc
@@ -2,16 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "pw_async/fake_dispatcher_fixture.h"
 #ifndef NINSPECT
 
-#include "windowed_inspect_numeric_property.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
 #include <pw_async_fuchsia/dispatcher.h>
 
 #include "src/connectivity/bluetooth/core/bt-host/testing/inspect.h"
 #include "src/lib/testing/loop_fixture/test_loop_fixture.h"
+#include "windowed_inspect_numeric_property.h"
 
 namespace bt {
 
@@ -46,46 +44,40 @@
 };
 
 using WindowedProperty = WindowedInspectNumericProperty<TestProperty<int>, int>;
-class WindowedInspectNumericPropertyTest : public ::gtest::TestLoopFixture {
- public:
-  pw::async::Dispatcher& pw_dispatcher() { return pw_dispatcher_; }
-
- private:
-  pw::async::fuchsia::FuchsiaDispatcher pw_dispatcher_{dispatcher()};
-};
+using WindowedInspectNumericPropertyTest = pw::async::test::FakeDispatcherFixture;
 
 TEST_F(WindowedInspectNumericPropertyTest, AddTwoValues) {
-  constexpr zx::duration kExpiryDuration = zx::min(3);
-  WindowedProperty windowed_prop(pw_dispatcher(), kExpiryDuration);
+  constexpr pw::chrono::SystemClock::duration kExpiryDuration = std::chrono::minutes(3);
+  WindowedProperty windowed_prop(dispatcher(), kExpiryDuration);
   int value = 0;
   auto value_cb = [&](auto val) { value = val; };
   windowed_prop.SetProperty(TestProperty<int>(0, value_cb));
 
   windowed_prop.Add(1);
   EXPECT_EQ(value, 1);
-  RunLoopFor(zx::min(1));
+  RunFor(std::chrono::minutes(1));
   EXPECT_EQ(value, 1);
 
   windowed_prop.Add(2);
   EXPECT_EQ(value, 3);
-  RunLoopFor(zx::min(1));
+  RunFor(std::chrono::minutes(1));
   EXPECT_EQ(value, 3);
 
   // Let first value expire.
-  RunLoopFor(zx::min(1));
+  RunFor(std::chrono::minutes(1));
   EXPECT_EQ(value, 2);
   // Let second value expire.
-  RunLoopFor(zx::min(1));
+  RunFor(std::chrono::minutes(1));
   EXPECT_EQ(value, 0);
 
   // Ensure timer doesn't fire again.
-  RunLoopFor(kExpiryDuration);
+  RunFor(kExpiryDuration);
   EXPECT_EQ(value, 0);
 }
 
 TEST_F(WindowedInspectNumericPropertyTest, AddTwoValuesAtSameTime) {
-  constexpr zx::duration kExpiryDuration = zx::min(3);
-  WindowedProperty windowed_prop(pw_dispatcher(), kExpiryDuration);
+  constexpr pw::chrono::SystemClock::duration kExpiryDuration = std::chrono::minutes(3);
+  WindowedProperty windowed_prop(dispatcher(), kExpiryDuration);
   int value = 0;
   auto value_cb = [&](auto val) { value = val; };
   windowed_prop.SetProperty(TestProperty<int>(0, value_cb));
@@ -93,73 +85,73 @@
   windowed_prop.Add(1);
   windowed_prop.Add(2);
   EXPECT_EQ(value, 3);
-  RunLoopFor(zx::min(1));
+  RunFor(std::chrono::minutes(1));
   EXPECT_EQ(value, 3);
-  RunLoopFor(zx::min(2));
+  RunFor(std::chrono::minutes(2));
   EXPECT_EQ(value, 0);
 
   // Ensure timer doesn't fire again.
-  RunLoopFor(kExpiryDuration);
+  RunFor(kExpiryDuration);
   EXPECT_EQ(value, 0);
 }
 
 TEST_F(WindowedInspectNumericPropertyTest, AddValueThenExpireThenAddValue) {
-  constexpr zx::duration kExpiryDuration = zx::min(3);
-  WindowedProperty windowed_prop(pw_dispatcher(), kExpiryDuration);
+  constexpr pw::chrono::SystemClock::duration kExpiryDuration = std::chrono::minutes(3);
+  WindowedProperty windowed_prop(dispatcher(), kExpiryDuration);
   int value = 0;
   auto value_cb = [&](auto val) { value = val; };
   windowed_prop.SetProperty(TestProperty<int>(0, value_cb));
 
   windowed_prop.Add(1);
   EXPECT_EQ(value, 1);
-  RunLoopFor(kExpiryDuration);
+  RunFor(kExpiryDuration);
   EXPECT_EQ(value, 0);
 
   windowed_prop.Add(2);
   EXPECT_EQ(value, 2);
-  RunLoopFor(kExpiryDuration);
+  RunFor(kExpiryDuration);
   EXPECT_EQ(value, 0);
 
   // Ensure timer doesn't fire again.
-  RunLoopFor(kExpiryDuration);
+  RunFor(kExpiryDuration);
   EXPECT_EQ(value, 0);
 }
 
 TEST_F(WindowedInspectNumericPropertyTest,
        AddTwoValuesWithinResolutionIntervalExpiresBothSimultaneously) {
-  constexpr zx::duration kExpiryDuration = zx::min(3);
-  constexpr zx::duration kResolution = zx::sec(3);
-  WindowedProperty windowed_prop(pw_dispatcher(), kExpiryDuration, kResolution);
+  constexpr pw::chrono::SystemClock::duration kExpiryDuration = std::chrono::minutes(3);
+  constexpr pw::chrono::SystemClock::duration kResolution = std::chrono::seconds(3);
+  WindowedProperty windowed_prop(dispatcher(), kExpiryDuration, kResolution);
   int value = 0;
   auto value_cb = [&](auto val) { value = val; };
   windowed_prop.SetProperty(TestProperty<int>(0, value_cb));
 
   // First two values are within kResolution of each other in time.
   windowed_prop.Add(1);
-  constexpr zx::duration kTinyDuration = zx::msec(1);
-  RunLoopFor(kTinyDuration);
+  constexpr pw::chrono::SystemClock::duration kTinyDuration = std::chrono::milliseconds(1);
+  RunFor(kTinyDuration);
   windowed_prop.Add(1);
   EXPECT_EQ(value, 2);
 
   // Third value is spaced kResolution apart from the first value.
-  RunLoopFor(kResolution - kTinyDuration);
+  RunFor(kResolution - kTinyDuration);
   windowed_prop.Add(1);
   EXPECT_EQ(value, 3);
 
   // Let first value expire.
-  RunLoopFor(kExpiryDuration - kResolution);
+  RunFor(kExpiryDuration - kResolution);
 
   // First and second values should have expired because they were merged.
   EXPECT_EQ(value, 1);
 
   // Let third value expire.
-  RunLoopFor(kResolution);
+  RunFor(kResolution);
   EXPECT_EQ(value, 0);
 }
 
 TEST_F(WindowedInspectNumericPropertyTest, SetPropertyClearsValueAndTimer) {
-  constexpr zx::duration kExpiryDuration = zx::min(3);
-  WindowedProperty windowed_prop(pw_dispatcher(), kExpiryDuration);
+  constexpr pw::chrono::SystemClock::duration kExpiryDuration = std::chrono::minutes(3);
+  WindowedProperty windowed_prop(dispatcher(), kExpiryDuration);
   int value_0 = 0;
   auto value_cb_0 = [&](auto val) { value_0 = val; };
   windowed_prop.SetProperty(TestProperty<int>(0, value_cb_0));
@@ -170,7 +162,7 @@
   auto value_cb_1 = [&](auto val) { value_1 = val; };
   windowed_prop.SetProperty(TestProperty<int>(0, value_cb_1));
   // Ensure timer doesn't fire.
-  RunLoopFor(kExpiryDuration);
+  RunFor(kExpiryDuration);
   EXPECT_EQ(value_0, 1);
   EXPECT_EQ(value_1, 0);
 
@@ -178,7 +170,7 @@
   windowed_prop.Add(3);
   EXPECT_EQ(value_0, 1);
   EXPECT_EQ(value_1, 3);
-  RunLoopFor(kExpiryDuration);
+  RunFor(kExpiryDuration);
   EXPECT_EQ(value_0, 1);
   EXPECT_EQ(value_1, 0);
 }
@@ -187,8 +179,8 @@
   ::inspect::Inspector inspector;
   auto& root = inspector.GetRoot();
 
-  constexpr zx::duration kExpiryDuration = zx::min(3);
-  WindowedInspectIntProperty windowed_property(pw_dispatcher(), kExpiryDuration);
+  constexpr pw::chrono::SystemClock::duration kExpiryDuration = std::chrono::minutes(3);
+  WindowedInspectIntProperty windowed_property(dispatcher(), kExpiryDuration);
   windowed_property.AttachInspect(root, "windowed");
 
   auto hierarchy = ::inspect::ReadFromVmo(inspector.DuplicateVmo());
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.cc b/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.cc
index 14edf0a..7261de0 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.cc
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.cc
@@ -7,7 +7,7 @@
 namespace bthost::testing {
 
 using bt::testing::FakeController;
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::ControllerTest<bt::testing::FakeController>;
 
 void AdapterTestFixture::SetUp() {
   FakeController::Settings settings;
@@ -17,7 +17,7 @@
 
 void AdapterTestFixture::SetUp(FakeController::Settings settings,
                                pw::bluetooth::Controller::FeaturesBits features) {
-  TestingBase::SetUp(features, /*initialize_transport=*/false);
+  TestingBase::Initialize(features, /*initialize_transport=*/false);
 
   auto l2cap = std::make_unique<bt::l2cap::testing::FakeL2cap>(pw_dispatcher());
   l2cap_ = l2cap.get();
@@ -45,7 +45,6 @@
   RunLoopUntilIdle();
 
   gatt_ = nullptr;
-  TestingBase::TearDown();
 }
 
 }  // namespace bthost::testing
diff --git a/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.h b/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.h
index cf95e6e..544ed82 100644
--- a/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.h
+++ b/src/connectivity/bluetooth/core/bt-host/fidl/adapter_test_fixture.h
@@ -11,17 +11,23 @@
 #include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_l2cap.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller.h"
+#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
 
 namespace bthost::testing {
 
 // This test fixture provides an instance of the Bluetooth stack with mock data plane (L2CAP) and
 // GATT test doubles. The fixture is backed by a FakeController and an event loop which can be used
 // to test interactions with the Bluetooth controller.
-class AdapterTestFixture : public bt::testing::ControllerTest<bt::testing::FakeController> {
+class AdapterTestFixture : public ::gtest::TestLoopFixture,
+                           public bt::testing::ControllerTest<bt::testing::FakeController> {
  public:
-  AdapterTestFixture() = default;
+  AdapterTestFixture()
+      : bt::testing::ControllerTest<bt::testing::FakeController>(pw_dispatcher_),
+        pw_dispatcher_(dispatcher()) {}
   ~AdapterTestFixture() override = default;
 
+  pw::async::Dispatcher& pw_dispatcher() { return pw_dispatcher_; }
+
  protected:
   void SetUp() override;
   void SetUp(bt::testing::FakeController::Settings settings,
@@ -35,6 +41,7 @@
   bt::l2cap::testing::FakeL2cap* l2cap() const { return l2cap_; }
 
  private:
+  pw::async::fuchsia::FuchsiaDispatcher pw_dispatcher_;
   std::unique_ptr<bt::gap::Adapter> adapter_;
   bt::l2cap::testing::FakeL2cap* l2cap_;
   std::unique_ptr<bt::gatt::testing::FakeLayer> gatt_;
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/adapter_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/adapter_unittest.cc
index d0ddf0a..cdc073e 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/adapter_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/adapter_unittest.cc
@@ -4,13 +4,8 @@
 
 #include "src/connectivity/bluetooth/core/bt-host/gap/adapter.h"
 
-#include <lib/async/cpp/task.h>
-#include <lib/zx/channel.h>
-
 #include <memory>
 
-#include <gmock/gmock.h>
-
 #include "bredr_discovery_manager.h"
 #include "low_energy_address_manager.h"
 #include "low_energy_advertising_manager.h"
@@ -29,7 +24,7 @@
 using namespace inspect::testing;
 using testing::FakeController;
 using testing::FakePeer;
-using TestingBase = testing::ControllerTest<FakeController>;
+using TestingBase = testing::FakeDispatcherControllerTest<FakeController>;
 
 using FeaturesBits = pw::bluetooth::Controller::FeaturesBits;
 
@@ -53,9 +48,9 @@
 
     transport_closed_called_ = false;
 
-    auto l2cap = std::make_unique<l2cap::testing::FakeL2cap>(pw_dispatcher());
-    gatt_ = std::make_unique<gatt::testing::FakeLayer>(pw_dispatcher());
-    adapter_ = Adapter::Create(pw_dispatcher(), transport()->GetWeakPtr(), gatt_->GetWeakPtr(),
+    auto l2cap = std::make_unique<l2cap::testing::FakeL2cap>(dispatcher());
+    gatt_ = std::make_unique<gatt::testing::FakeLayer>(dispatcher());
+    adapter_ = Adapter::Create(dispatcher(), transport()->GetWeakPtr(), gatt_->GetWeakPtr(),
                                std::move(l2cap));
   }
 
@@ -71,7 +66,7 @@
 
   void InitializeAdapter(Adapter::InitializeCallback callback) {
     adapter_->Initialize(std::move(callback), [this] { transport_closed_called_ = true; });
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   bool EnsureInitialized() {
@@ -304,7 +299,7 @@
   EXPECT_FALSE(transport_closed_called());
 
   test_device()->SignalError(pw::Status::Aborted());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(transport_closed_called());
   EXPECT_EQ(1, init_cb_count);
@@ -336,7 +331,7 @@
 
   // Further calls to ShutDown() should have no effect.
   adapter()->ShutDown();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(AdapterTest, SetNameError) {
@@ -355,7 +350,7 @@
 
   adapter()->SetLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::HARDWARE_FAILURE), result);
 }
@@ -372,7 +367,7 @@
   auto name_cb = [&result](const auto& status) { result = status; };
   adapter()->SetLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), result);
   EXPECT_EQ(kNewName, test_device()->local_name());
@@ -392,7 +387,7 @@
   auto name_cb = [&result](const auto& status) { result = status; };
   adapter()->SetLocalName(long_name, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), result);
   EXPECT_EQ(long_name, adapter()->state().local_name);
@@ -412,7 +407,7 @@
   auto name_cb = [&result](const auto& status) { result = status; };
   adapter()->SetLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), result);
   EXPECT_EQ(kNewName, adapter()->state().local_name);
@@ -434,7 +429,7 @@
   auto name_cb = [&result](const auto& status) { result = status; };
   adapter()->SetLocalName(long_name, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), result);
   // Both the adapter & discovery manager local name should be the original (untruncated) name.
@@ -460,7 +455,7 @@
 
   adapter()->SetLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // kWriteLocalName will succeed, but kWriteExtendedInquiryResponse will fail
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_BY_LOCAL_HOST),
@@ -492,7 +487,7 @@
 TEST_F(AdapterTest, PeerCacheReturnsNonNull) { EXPECT_TRUE(adapter()->peer_cache()); }
 
 TEST_F(AdapterTest, LeAutoConnect) {
-  constexpr zx::duration kTestScanPeriod = zx::sec(10);
+  constexpr pw::chrono::SystemClock::duration kTestScanPeriod = std::chrono::seconds(10);
   constexpr pw::chrono::SystemClock::duration kPwTestScanPeriod = std::chrono::seconds(10);
   constexpr PeerId kPeerId(1234);
 
@@ -503,7 +498,7 @@
   InitializeAdapter([](bool) {});
   adapter()->le()->set_scan_period_for_testing(kPwTestScanPeriod);
 
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, pw_dispatcher(), true, false);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, dispatcher(), true, false);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -515,7 +510,7 @@
   std::unique_ptr<LowEnergyDiscoverySession> session;
   adapter()->le()->StartDiscovery(/*active=*/false,
                                   [&session](auto cb_session) { session = std::move(cb_session); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn);
   EXPECT_EQ(0u, adapter()->peer_cache()->count());
 
@@ -529,7 +524,7 @@
 
   // FakeController only sends advertising reports at the start of scan periods, so we need to start
   // a second period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
 
   // The peer should have been auto-connected.
   ASSERT_TRUE(conn);
@@ -537,7 +532,7 @@
 }
 
 TEST_F(AdapterTest, LeSkipAutoConnectBehavior) {
-  constexpr zx::duration kTestScanPeriod = zx::sec(10);
+  constexpr pw::chrono::SystemClock::duration kTestScanPeriod = std::chrono::seconds(10);
   constexpr pw::chrono::SystemClock::duration kPwTestScanPeriod = std::chrono::seconds(10);
   constexpr PeerId kPeerId(1234);
 
@@ -548,7 +543,7 @@
   InitializeAdapter([](bool) {});
   adapter()->le()->set_scan_period_for_testing(kPwTestScanPeriod);
 
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, pw_dispatcher(), true, false);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, dispatcher(), true, false);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -560,7 +555,7 @@
   std::unique_ptr<LowEnergyDiscoverySession> session;
   adapter()->le()->StartDiscovery(/*active=*/false,
                                   [&session](auto cb_session) { session = std::move(cb_session); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn);
   EXPECT_EQ(0u, adapter()->peer_cache()->count());
 
@@ -576,20 +571,20 @@
   adapter()->peer_cache()->SetAutoConnectBehaviorForIntentionalDisconnect(kPeerId);
 
   // Advance the scan period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
 
   // The peer should NOT have been auto-connected.
   ASSERT_FALSE(conn);
 
   // The peer should still not auto-connect after a subsequent scan period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   ASSERT_FALSE(conn);
 
   // Fake a manual connection to reset auto-connect behavior.
   adapter()->peer_cache()->SetAutoConnectBehaviorForSuccessfulConnection(kPeerId);
 
   // Advance the scan period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
 
   // The peer SHOULD have been auto-connected.
   ASSERT_TRUE(conn);
@@ -614,7 +609,7 @@
   adapter()->le()->StartAdvertising(
       AdvertisingData(), AdvertisingData(), AdvertisingInterval::FAST1, /*anonymous=*/false,
       /*include_tx_power_level=*/false, /*connectable=*/std::nullopt, adv_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
             test_device()->legacy_advertising_state().own_address_type);
@@ -622,12 +617,12 @@
   // Enable privacy. The random address should not get configured while
   // advertising is in progress.
   adapter()->le()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->legacy_advertising_state().random_address);
 
   // Stop advertising.
   adapter()->le()->StopAdvertising(instance.id());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->legacy_advertising_state().enabled);
   EXPECT_FALSE(test_device()->legacy_advertising_state().random_address);
 
@@ -636,7 +631,7 @@
   adapter()->le()->StartAdvertising(
       AdvertisingData(), AdvertisingData(), AdvertisingInterval::FAST1, /*anonymous=*/false,
       /*include_tx_power_level=*/false, /*connectable=*/std::nullopt, adv_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->legacy_advertising_state().random_address);
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
@@ -645,7 +640,7 @@
   // Advance time to force the random address to refresh. The update should be
   // deferred while advertising.
   auto last_random_addr = *test_device()->legacy_advertising_state().random_address;
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   EXPECT_EQ(last_random_addr, *test_device()->legacy_advertising_state().random_address);
 
   // Restarting advertising should refresh the controller address.
@@ -653,7 +648,7 @@
   adapter()->le()->StartAdvertising(
       AdvertisingData(), AdvertisingData(), AdvertisingInterval::FAST1, /*anonymous=*/false,
       /*include_tx_power_level=*/false, /*connectable=*/std::nullopt, adv_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
             test_device()->legacy_advertising_state().own_address_type);
@@ -667,7 +662,7 @@
   adapter()->le()->StartAdvertising(
       AdvertisingData(), AdvertisingData(), AdvertisingInterval::FAST1, /*anonymous=*/false,
       /*include_tx_power_level=*/false, /*connectable=*/std::nullopt, adv_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
             test_device()->legacy_advertising_state().own_address_type);
@@ -683,9 +678,9 @@
 
   // Set a scan period that is longer than the private address timeout, for
   // testing.
-  constexpr zx::duration kTestDelay = zx::sec(5);
+  constexpr pw::chrono::SystemClock::duration kTestDelay = std::chrono::seconds(5);
   constexpr pw::chrono::SystemClock::duration kPwTestDelay = std::chrono::seconds(5);
-  constexpr zx::duration kTestScanPeriod = kPrivateAddressTimeout + kTestDelay;
+  constexpr pw::chrono::SystemClock::duration kTestScanPeriod = kPrivateAddressTimeout + kTestDelay;
   constexpr pw::chrono::SystemClock::duration kPwTestScanPeriod =
       kPwPrivateAddressTimeout + kPwTestDelay;
   adapter()->le()->set_scan_period_for_testing(kPwTestScanPeriod);
@@ -694,7 +689,7 @@
   LowEnergyDiscoverySessionPtr session;
   auto cb = [&](auto s) { session = std::move(s); };
   adapter()->le()->StartDiscovery(/*active=*/true, cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(session);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
@@ -703,19 +698,19 @@
   // Enable privacy. The random address should not get configured while a scan
   // is in progress.
   adapter()->le()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->legacy_advertising_state().random_address);
 
   // Stop discovery.
   session = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->le_scan_state().enabled);
   EXPECT_FALSE(test_device()->legacy_advertising_state().random_address);
 
   // Restart discovery. This should configure the LE random address and scan
   // using it.
   adapter()->le()->StartDiscovery(/*active=*/true, cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(session);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
@@ -725,12 +720,12 @@
   // deferred while still scanning.
   ASSERT_TRUE(test_device()->legacy_advertising_state().random_address);
   auto last_random_addr = *test_device()->legacy_advertising_state().random_address;
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   EXPECT_EQ(last_random_addr, *test_device()->legacy_advertising_state().random_address);
 
   // Let the scan period expire. This should restart scanning and refresh the
   // random address.
-  RunLoopFor(kTestDelay);
+  RunFor(kTestDelay);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
             test_device()->le_scan_state().own_address_type);
@@ -740,7 +735,7 @@
   // Disable privacy. The next time scanning gets started it should use a
   // public address.
   adapter()->le()->EnablePrivacy(false);
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
             test_device()->le_scan_state().own_address_type);
@@ -754,7 +749,7 @@
 
   // Set-up a device for testing.
   auto* peer = adapter()->peer_cache()->NewPeer(kTestAddr, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<bt::gap::LowEnergyConnectionHandle> conn_ref;
@@ -769,7 +764,7 @@
   // Enable privacy. The random address should not get configured while a
   // connection attempt is in progress.
   adapter()->le()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->legacy_advertising_state().random_address);
   ASSERT_TRUE(conn_ref);
   ASSERT_TRUE(test_device()->le_connect_params());
@@ -780,7 +775,7 @@
   // re-enabled.
   conn_ref = nullptr;
   adapter()->le()->Connect(peer->identifier(), connect_cb, LowEnergyConnectionOptions());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->legacy_advertising_state().random_address);
   ASSERT_TRUE(conn_ref);
   ASSERT_TRUE(test_device()->le_connect_params());
@@ -795,7 +790,7 @@
   adapter()->le()->EnablePrivacy(false);
   conn_ref = nullptr;
   adapter()->le()->Connect(peer->identifier(), connect_cb, LowEnergyConnectionOptions());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
             test_device()->le_connect_params()->own_address_type);
 }
@@ -811,13 +806,13 @@
   auto* peer = adapter()->peer_cache()->NewPeer(kTestAddr, /*connectable=*/true);
 
   // Cause scanning to succeed and the connection request to hang.
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, dispatcher());
   fake_peer->set_force_pending_connect(true);
   test_device()->AddPeer(std::move(fake_peer));
 
-  constexpr zx::duration kTestDelay = zx::sec(5);
+  constexpr pw::chrono::SystemClock::duration kTestDelay = std::chrono::seconds(5);
   constexpr pw::chrono::SystemClock::duration kPwTestDelay = std::chrono::seconds(5);
-  constexpr zx::duration kTestTimeout = kPrivateAddressTimeout + kTestDelay;
+  constexpr pw::chrono::SystemClock::duration kTestTimeout = kPrivateAddressTimeout + kTestDelay;
   constexpr pw::chrono::SystemClock::duration kPwTestTimeout =
       kPwPrivateAddressTimeout + kPwTestDelay;
 
@@ -839,7 +834,7 @@
     error = result.error_value();
   };
   adapter()->le()->Connect(peer->identifier(), connect_cb, LowEnergyConnectionOptions());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(test_device()->le_connect_params());
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
             test_device()->le_connect_params()->own_address_type);
@@ -847,11 +842,11 @@
   // Enable privacy. The random address should not get configured while a
   // connection request is outstanding.
   adapter()->le()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->legacy_advertising_state().random_address);
 
   // Let the connection request timeout.
-  RunLoopFor(kTestTimeout);
+  RunFor(kTestTimeout);
   ASSERT_TRUE(error.has_value());
   EXPECT_EQ(HostError::kTimedOut, error.value()) << "Error: " << HostErrorToString(error.value());
   EXPECT_EQ(1, connect_cb_calls);
@@ -859,7 +854,7 @@
   // The peer should not have expired.
   ASSERT_EQ(peer, adapter()->peer_cache()->FindByAddress(kTestAddr));
   adapter()->le()->Connect(peer->identifier(), connect_cb, LowEnergyConnectionOptions());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(test_device()->legacy_advertising_state().random_address);
   // TODO(fxbug.dev/63123): The current policy is to use a public address when initiating
   // connections. Change this test to expect a random address once RPAs for central connections are
@@ -870,21 +865,21 @@
   // Advance the time to cause the random address to refresh. The update should
   // be deferred while a connection request is outstanding.
   auto last_random_addr = *test_device()->legacy_advertising_state().random_address;
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   EXPECT_EQ(last_random_addr, *test_device()->legacy_advertising_state().random_address);
 
   ASSERT_EQ(peer, adapter()->peer_cache()->FindByAddress(kTestAddr));
 
   // The address should refresh after the pending request expires and before the
   // next connection attempt.
-  RunLoopFor(kTestDelay);
+  RunFor(kTestDelay);
   ASSERT_EQ(2, connect_cb_calls);
 
   // This will be notified when LowEnergyConnectionManager is destroyed.
   auto noop_connect_cb = [](auto) {};
   adapter()->le()->Connect(peer->identifier(), std::move(noop_connect_cb),
                            LowEnergyConnectionOptions());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_NE(last_random_addr, *test_device()->legacy_advertising_state().random_address);
   // TODO(fxbug.dev/63123): The current policy is to use a public address when initiating
   // connections. Change this test to expect a random address once RPAs for central connections are
@@ -910,10 +905,10 @@
   };
 
   auto* peer = adapter()->peer_cache()->NewPeer(kTestAddr, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddr, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
   adapter()->le()->Connect(peer->identifier(), connect_cb, LowEnergyConnectionOptions());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // TODO(fxbug.dev/63123): The current policy is to use a public address when initiating
   // connections. Change this test to expect a random address once RPAs for central connections are
   // re-enabled.
@@ -924,7 +919,7 @@
   // from the ongoing connection.
   ASSERT_TRUE(test_device()->legacy_advertising_state().random_address);
   auto last_random_addr = *test_device()->legacy_advertising_state().random_address;
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   ASSERT_TRUE(test_device()->legacy_advertising_state().random_address);
   EXPECT_NE(last_random_addr, *test_device()->legacy_advertising_state().random_address);
 }
@@ -945,11 +940,11 @@
                                       ASSERT_EQ(fit::ok(), status);
                                       instance = std::move(i);
                                     });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(adapter()->IsDiscoverable());
 
   instance = {};
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(adapter()->IsDiscoverable());
 }
 
@@ -963,11 +958,11 @@
 
   std::unique_ptr<BrEdrDiscoverableSession> session;
   adapter()->bredr()->RequestDiscoverable([&](auto, auto s) { session = std::move(s); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(adapter()->IsDiscoverable());
 
   session = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(adapter()->IsDiscoverable());
 }
 
@@ -989,12 +984,12 @@
                                       ASSERT_EQ(fit::ok(), status);
                                       instance = std::move(i);
                                     });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Even though we are advertising over LE, we are not discoverable since Privacy is enabled.
   EXPECT_FALSE(adapter()->IsDiscoverable());
 
   instance = {};
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(adapter()->IsDiscoverable());
 }
 
@@ -1122,7 +1117,7 @@
                                     bt::gap::Adapter::LowEnergy::ConnectableAdvertisingParameters{
                                         std::move(connect_cb), sm::BondableMode::NonBondable},
                                     adv_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result);
 
   fit::closure complete_interrogation;
@@ -1131,14 +1126,14 @@
       bt::hci_spec::kReadRemoteVersionInfo,
       [&](fit::closure trigger) { complete_interrogation = std::move(trigger); });
 
-  test_device()->AddPeer(std::make_unique<FakePeer>(kTestAddr, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kTestAddr, dispatcher()));
   test_device()->ConnectLowEnergy(kTestAddr);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_FALSE(conn_result);
   ASSERT_TRUE(complete_interrogation);
 
   complete_interrogation();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result);
   ASSERT_EQ(fit::ok(), *conn_result);
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle = std::move(*conn_result).value();
@@ -1158,8 +1153,8 @@
   void SetUp() override {
     TestingBase::SetUp();
 
-    l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(pw_dispatcher());
-    gatt_ = std::make_unique<gatt::testing::FakeLayer>(pw_dispatcher());
+    l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(dispatcher());
+    gatt_ = std::make_unique<gatt::testing::FakeLayer>(dispatcher());
   }
 
   void TearDown() override {
@@ -1193,7 +1188,7 @@
   EXPECT_EQ(set_persist_cb_count, 0);
   EXPECT_EQ(set_retrieve_cb_count, 0);
 
-  auto adapter = Adapter::Create(pw_dispatcher(), transport()->GetWeakPtr(), gatt_->GetWeakPtr(),
+  auto adapter = Adapter::Create(dispatcher(), transport()->GetWeakPtr(), gatt_->GetWeakPtr(),
                                  std::move(l2cap_));
 
   EXPECT_EQ(set_persist_cb_count, 1);
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/bredr_connection_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/bredr_connection_manager_unittest.cc
index f7f61b1..8e82a09 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/bredr_connection_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/bredr_connection_manager_unittest.cc
@@ -4,10 +4,6 @@
 
 #include "src/connectivity/bluetooth/core/bt-host/gap/bredr_connection_manager.h"
 
-#include <lib/async/time.h>
-
-#include <gmock/gmock.h>
-
 #include "src/connectivity/bluetooth/core/bt-host/common/error.h"
 #include "src/connectivity/bluetooth/core/bt-host/gap/fake_pairing_delegate.h"
 #include "src/connectivity/bluetooth/core/bt-host/gap/peer_cache.h"
@@ -37,7 +33,7 @@
 using pw::bluetooth::emboss::AuthenticationRequirements;
 using pw::bluetooth::emboss::IoCapability;
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 constexpr hci_spec::ConnectionHandle kConnectionHandle = 0x0BAA;
 constexpr hci_spec::ConnectionHandle kConnectionHandle2 = 0x0BAB;
@@ -564,8 +560,8 @@
     TestingBase::SetUp();
     InitializeACLDataChannel(kBrEdrBufferInfo, kLeBufferInfo);
 
-    peer_cache_ = std::make_unique<PeerCache>(pw_dispatcher());
-    l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(pw_dispatcher());
+    peer_cache_ = std::make_unique<PeerCache>(dispatcher());
+    l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(dispatcher());
 
     // Respond to BrEdrConnectionManager controller setup with success.
     EXPECT_CMD_PACKET_OUT(test_device(),
@@ -576,9 +572,9 @@
     connection_manager_ = std::make_unique<BrEdrConnectionManager>(
         transport()->GetWeakPtr(), peer_cache_.get(), kLocalDevAddr, l2cap_.get(),
         /*use_interlaced_scan=*/true,
-        /*local_secure_connections_supported=*/true, pw_dispatcher());
+        /*local_secure_connections_supported=*/true, dispatcher());
 
-    RunLoopUntilIdle();
+    RunUntilIdle();
 
     test_device()->SetTransactionCallback([this] { transaction_count_++; });
   }
@@ -592,7 +588,7 @@
       EXPECT_CMD_PACKET_OUT(test_device(), kWriteScanEnableInq, &kWriteScanEnableRsp);
       connection_manager_ = nullptr;
     }
-    RunLoopUntilIdle();
+    RunUntilIdle();
     // A disconnection may also occur for a queued disconnection, allow up to 1 extra transaction.
     EXPECT_LE(expected_transaction_count, transaction_count());
     EXPECT_GE(expected_transaction_count + 1, transaction_count());
@@ -805,7 +801,7 @@
 
   connmgr()->SetConnectable(/*connectable=*/false, cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, cb_count);
 
@@ -814,7 +810,7 @@
 
   connmgr()->SetConnectable(/*connectable=*/false, cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, cb_count);
 }
@@ -833,7 +829,7 @@
 
   connmgr()->SetConnectable(/*connectable=*/true, cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, cb_count);
 
@@ -844,7 +840,7 @@
 
   connmgr()->SetConnectable(/*connectable=*/true, cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, cb_count);
 }
@@ -868,7 +864,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(6, transaction_count());
 
@@ -885,7 +881,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -910,7 +906,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(peer, peer_cache()->FindByAddress(kTestDevAddr));
   EXPECT_EQ(peer->identifier(), connmgr()->GetPeerId(kConnectionHandle));
@@ -926,7 +922,7 @@
   QueueSuccessfulIncomingConn();
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -937,7 +933,7 @@
   // Remote end disconnects.
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kInvalidPeerId, connmgr()->GetPeerId(kConnectionHandle));
 }
@@ -970,7 +966,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(5, transaction_count());
 }
@@ -982,7 +978,7 @@
 
   test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count());
 }
@@ -997,7 +993,7 @@
 
   test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count());
 }
@@ -1011,7 +1007,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(kIncomingConnTransactions, transaction_count());
 
@@ -1024,7 +1020,7 @@
       IoCapability::DISPLAY_ONLY, AuthenticationRequirements::MITM_GENERAL_BONDING));
   test_device()->SendCommandChannelPacket(kIoCapabilityRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
 
@@ -1037,7 +1033,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
 
@@ -1074,7 +1070,7 @@
   // We disconnect the peer when authentication fails.
   QueueDisconnection(kConnectionHandle);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 const auto kUserPasskeyRequest = StaticByteBuffer(hci_spec::kUserPasskeyRequestEventCode,
@@ -1104,7 +1100,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
 
@@ -1138,7 +1134,7 @@
   // We disconnect the peer when authentication fails.
   QueueDisconnection(kConnectionHandle);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // Test: replies negative to Link Key Requests for unknown and unbonded peers
@@ -1148,7 +1144,7 @@
 
   test_device()->SendCommandChannelPacket(kLinkKeyRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count());
 
@@ -1156,7 +1152,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
 
@@ -1170,7 +1166,7 @@
 
   test_device()->SendCommandChannelPacket(kLinkKeyRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions + 2, transaction_count());
 
@@ -1191,7 +1187,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   ASSERT_TRUE(IsInitializing(peer));
@@ -1200,7 +1196,7 @@
 
   test_device()->SendCommandChannelPacket(kLinkKeyRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   /// Peer is still initializing until the Pairing is complete (OnPairingComplete)
   ASSERT_TRUE(IsInitializing(peer));
 
@@ -1217,7 +1213,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -1258,7 +1254,7 @@
                         &kEncryptionChangeEvent);
   EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   ASSERT_TRUE(IsConnected(peer));
   EXPECT_TRUE(peer->bonded());
 
@@ -1272,7 +1268,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -1306,7 +1302,7 @@
   pairing_delegate.SetCompletePairingCallback(
       [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   ASSERT_TRUE(IsInitializing(peer));
 
   test_device()->SendCommandChannelPacket(kSimplePairingCompleteSuccess);
@@ -1316,7 +1312,7 @@
                         &kEncryptionChangeEvent);
   EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   ASSERT_TRUE(IsConnected(peer));
   EXPECT_TRUE(peer->bonded());
 
@@ -1330,7 +1326,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -1367,7 +1363,7 @@
   pairing_delegate.SetCompletePairingCallback(
       [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   ASSERT_TRUE(IsInitializing(peer));
 
   test_device()->SendCommandChannelPacket(kSimplePairingCompleteSuccess);
@@ -1377,14 +1373,14 @@
                         &kEncryptionChangeEvent);
   EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   ASSERT_TRUE(IsConnected(peer));
   EXPECT_TRUE(peer->bonded());
 
   EXPECT_CMD_PACKET_OUT(test_device(), kLinkKeyRequestReply, &kLinkKeyRequestReplyRsp);
   test_device()->SendCommandChannelPacket(kLinkKeyRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   QueueDisconnection(kConnectionHandle);
 }
@@ -1395,7 +1391,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
 
@@ -1407,7 +1403,7 @@
   // Change the link key.
   test_device()->SendCommandChannelPacket(kLinkKeyNotificationChanged);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_FALSE(IsConnected(peer));
   EXPECT_FALSE(peer->bonded());
 
@@ -1415,7 +1411,7 @@
 
   test_device()->SendCommandChannelPacket(kLinkKeyRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_FALSE(IsConnected(peer));
   EXPECT_FALSE(peer->bonded());
@@ -1439,7 +1435,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
 
@@ -1450,14 +1446,14 @@
 
   test_device()->SendCommandChannelPacket(kLinkKeyNotificationLegacy);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(peer->bonded());
 
   EXPECT_CMD_PACKET_OUT(test_device(), kLinkKeyRequestNegativeReply, &kLinkKeyRequestReplyRsp);
 
   test_device()->SendCommandChannelPacket(kLinkKeyRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_FALSE(IsConnected(peer));
   EXPECT_FALSE(peer->bonded());
@@ -1472,7 +1468,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
 
@@ -1481,7 +1477,7 @@
 
   l2cap()->TriggerLinkError(kConnectionHandle);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
 }
@@ -1491,7 +1487,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
 
@@ -1501,7 +1497,7 @@
   EXPECT_FALSE(peer->bonded());
 
   // We want to make sure the connection doesn't expire just because they didn't pair.
-  RunLoopFor(zx::sec(600));
+  RunFor(std::chrono::seconds(600));
 
   auto* peer_still = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer_still);
@@ -1510,7 +1506,7 @@
   // Remote end disconnects.
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Peer should still be there, but not connected anymore, until they time out.
   peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -1541,7 +1537,7 @@
   l2cap()->set_channel_callback([&sdp_chan, &sdp_request_tid, this](auto new_chan) {
     new_chan->SetSendCallback(
         [&sdp_request_tid](auto packet) { sdp_request_tid = tid_from_sdp_packet(packet); },
-        pw_dispatcher());
+        dispatcher());
     sdp_chan = std::move(new_chan);
   });
 
@@ -1551,7 +1547,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(sdp_chan.is_alive());
   ASSERT_EQ(0u, search_cb_count);
@@ -1564,7 +1560,7 @@
 
   sdp_chan->Receive(*rsp_ptr);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(1u, search_cb_count);
 
@@ -1590,7 +1586,7 @@
   l2cap()->set_channel_callback([&sdp_chan, &sdp_request_tid, this](auto new_chan) {
     new_chan->SetSendCallback(
         [&sdp_request_tid](auto packet) { sdp_request_tid = tid_from_sdp_packet(packet); },
-        pw_dispatcher());
+        dispatcher());
     sdp_chan = std::move(new_chan);
   });
 
@@ -1599,7 +1595,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(sdp_chan.is_alive());
   ASSERT_EQ(0u, search_cb_count);
@@ -1610,7 +1606,7 @@
 
   sdp_chan->Receive(*rsp_ptr);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Search callback isn't called by empty attribute list from peer.
   ASSERT_EQ(0u, search_cb_count);
@@ -1659,18 +1655,17 @@
   l2cap::testing::FakeChannel::WeakPtr sdp_chan;
   std::optional<uint16_t> sdp_request_tid;
 
-  l2cap()->set_channel_callback(
-      [&sdp_chan, &sdp_request_tid, dispatcher = dispatcher(), this](auto new_chan) {
-        new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid), pw_dispatcher());
-        sdp_chan = std::move(new_chan);
-      });
+  l2cap()->set_channel_callback([&sdp_chan, &sdp_request_tid, this](auto new_chan) {
+    new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid), dispatcher());
+    sdp_chan = std::move(new_chan);
+  });
 
   QueueSuccessfulIncomingConn();
   l2cap()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, 0x40, 0x41, kChannelParams);
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(sdp_chan.is_alive());
   ASSERT_TRUE(sdp_request_tid);
@@ -1683,14 +1678,14 @@
 
   sdp_chan->Receive(*rsp_ptr);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(1u, search_cb_count);
 
   // Remote end disconnects.
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   sdp_request_tid.reset();
 
@@ -1707,7 +1702,7 @@
                         &kReadRemoteExtended2Complete);
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // We shouldn't have searched for anything.
   ASSERT_FALSE(sdp_request_tid);
@@ -1721,7 +1716,7 @@
   QueueSuccessfulIncomingConn();
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   size_t search_cb_count = 0;
   auto search_cb = [&](auto id, const auto& attributes) {
@@ -1736,7 +1731,7 @@
   std::optional<uint16_t> sdp_request_tid;
 
   l2cap()->set_channel_callback([&sdp_chan, &sdp_request_tid, this](auto new_chan) {
-    new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid), pw_dispatcher());
+    new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid), dispatcher());
     sdp_chan = std::move(new_chan);
   });
 
@@ -1749,7 +1744,7 @@
 
   ASSERT_NE(sdp::ServiceDiscoverer::kInvalidSearchId, search_id);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(sdp_chan.is_alive());
   ASSERT_TRUE(sdp_request_tid);
@@ -1762,14 +1757,14 @@
 
   sdp_chan->Receive(*rsp_ptr);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(1u, search_cb_count);
 
   // Remote end disconnects.
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   sdp_request_tid.reset();
   sdp_chan.reset();
@@ -1786,7 +1781,7 @@
   l2cap()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, 0x40, 0x41, kChannelParams);
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(sdp_chan.is_alive());
   ASSERT_TRUE(sdp_request_tid);
@@ -1819,7 +1814,7 @@
   std::optional<uint16_t> sdp_request_tid;
 
   l2cap()->set_channel_callback([&sdp_chan, &sdp_request_tid, this](auto new_chan) {
-    new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid), pw_dispatcher());
+    new_chan->SetSendCallback(MakeAudioSinkSearchExpected(&sdp_request_tid), dispatcher());
     sdp_chan = std::move(new_chan);
   });
 
@@ -1847,7 +1842,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(sdp_chan.is_alive());
   ASSERT_TRUE(sdp_request_tid);
@@ -1860,14 +1855,14 @@
 
   sdp_chan->Receive(*rsp_ptr);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(1u, search_cb_count);
 
   // Remote end disconnects.
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   sdp_request_tid.reset();
   sdp_chan.reset();
@@ -1881,7 +1876,7 @@
   l2cap()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kSDP, 0x40, 0x41, kChannelParams);
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // We should have searched again.
   ASSERT_TRUE(sdp_chan.is_alive());
@@ -1892,7 +1887,7 @@
 
   sdp_chan->Receive(*rsp_ptr);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(2u, search_cb_count);
 
@@ -1906,7 +1901,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -1956,7 +1951,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kNoSecurityRequirements,
                               kChannelParams, chan_cb);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   // We should not have a channel because the L2CAP open callback shouldn't have been called, but
   // the LTK should be stored since the link key got received.
@@ -1968,7 +1963,7 @@
 
   l2cap()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kAVDTP, 0x40, 0x41, kChannelParams);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   // We should signal to PeerCache as connected once we finish pairing.
   ASSERT_TRUE(IsConnected(peer));
 
@@ -1983,7 +1978,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kNoSecurityRequirements,
                               kChannelParams, chan_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(connected_chan);
 
@@ -2007,7 +2002,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   ASSERT_FALSE(IsNotConnected(peer));
@@ -2026,7 +2021,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kNoSecurityRequirements,
                               kChannelParams, socket_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // L2CAP connect shouldn't have been called, and callback shouldn't be called.
   // We should not have a socket.
@@ -2044,7 +2039,7 @@
                         &kEncryptionChangeEvent);
   EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, );
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // No socket until the encryption verification completes.
   ASSERT_FALSE(connected_chan);
@@ -2053,7 +2048,7 @@
 
   l2cap()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kAVDTP, 0x40, 0x41, kChannelParams);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Once the L2CAP channel has connected, we have connected.
   ASSERT_TRUE(IsConnected(peer));
@@ -2073,7 +2068,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -2094,7 +2089,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kNoSecurityRequirements,
                               kChannelParams, socket_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The L2CAP shouldn't have been called
   // We should not have a channel, and the callback shouldn't have been called.
@@ -2107,7 +2102,7 @@
   // We disconnect the peer when authentication fails.
   QueueDisconnection(kConnectionHandle);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // An invalid channel should have been sent because the connection failed.
   ASSERT_TRUE(connected_chan);
@@ -2121,7 +2116,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -2170,7 +2165,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kNoSecurityRequirements,
                               kChannelParams, chan_cb);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   // We should not have a channel because the L2CAP open callback shouldn't have been called, but
   // the LTK should be stored since the link key got received.
@@ -2179,7 +2174,7 @@
   // The remote device disconnects now, when the pairing has been started, then pairing completes.
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
   test_device()->SendCommandChannelPacket(kReadEncryptionKeySizeRsp);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // We should get a callback from the OpenL2capChannel
   ASSERT_TRUE(connected_chan);
@@ -2204,7 +2199,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -2232,7 +2227,7 @@
   test_device()->SendCommandChannelPacket(MakeIoCapabilityResponse(
       IoCapability::DISPLAY_YES_NO, AuthenticationRequirements::MITM_GENERAL_BONDING));
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   // Initial connection request
 
@@ -2255,7 +2250,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kNoSecurityRequirements,
                               kChannelParams, socket_cb);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   // We should not have a socket because the L2CAP open callback shouldn't have been called, but
   // the LTK should be stored since the link key got received.
@@ -2265,7 +2260,7 @@
 
   l2cap()->ExpectOutboundL2capChannel(kConnectionHandle, l2cap::kAVDTP, 0x40, 0x41, kChannelParams);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   // The socket should be returned.
   ASSERT_TRUE(connected_chan);
@@ -2291,7 +2286,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Ensure that the interrogation has begun but the peer hasn't yet bonded
   EXPECT_EQ(4, transaction_count());
@@ -2327,7 +2322,7 @@
                         &kEncryptionChangeEvent);
   EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   // At this point the peer is bonded and the link is encrypted but interrogation has not completed
   // so host-side L2CAP should still be inactive on this link (though it may be buffering packets).
@@ -2341,7 +2336,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), l2cap::kAVDTP, kNoSecurityRequirements,
                               kChannelParams, socket_fails_cb);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(socket_cb_called);
 
   // Complete interrogation successfully.
@@ -2351,7 +2346,7 @@
                         &kReadRemoteExtended1Complete);
   test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesComplete);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   EXPECT_TRUE(l2cap()->IsLinkConnected(kConnectionHandle));
 
@@ -2370,7 +2365,7 @@
 TEST_F(BrEdrConnectionManagerTest, DisconnectUnknownPeerDoesNothing) {
   EXPECT_TRUE(connmgr()->Disconnect(PeerId(999), DisconnectReason::kApiRequest));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(0, transaction_count());
 }
@@ -2381,7 +2376,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -2393,7 +2388,7 @@
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
   EXPECT_TRUE(IsNotConnected(peer));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
   EXPECT_TRUE(IsNotConnected(peer));
@@ -2404,7 +2399,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -2419,7 +2414,7 @@
   // Disconnection Complete not yet received).
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
   ASSERT_TRUE(IsNotConnected(peer));
@@ -2433,7 +2428,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -2448,7 +2443,7 @@
   // Remove the peer from PeerCache before receiving HCI Disconnection Complete.
   EXPECT_TRUE(peer_cache()->RemoveDisconnectedPeer(id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions + 1, transaction_count());
   EXPECT_FALSE(peer_cache()->FindById(id));
@@ -2488,7 +2483,7 @@
           ASSERT_EQ(kSearchExpectedParams, packet->view(sizeof(bt::sdp::Header)));
           sdp_request_tid = tid_from_sdp_packet(packet);
         },
-        pw_dispatcher());
+        dispatcher());
     sdp_chan = std::move(new_chan);
   });
 
@@ -2497,7 +2492,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(sdp_chan.is_alive());
   ASSERT_TRUE(sdp_request_tid);
@@ -2510,7 +2505,7 @@
 
   sdp_chan->Receive(*rsp_ptr);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(1u, search_cb_count);
 
@@ -2529,7 +2524,7 @@
   hci::Result<> status = fit::ok();
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), CALLBACK_EXPECT_FAILURE(status)));
   EXPECT_TRUE(IsInitializing(peer));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED),
             status);
@@ -2555,7 +2550,7 @@
   ASSERT_TRUE(peer->bredr());
   EXPECT_TRUE(IsInitializing(peer));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(callback_run);
 
@@ -2580,8 +2575,8 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
   EXPECT_TRUE(IsInitializing(peer));
-  RunLoopFor(kBrEdrCreateConnectionTimeout);
-  RunLoopFor(kBrEdrCreateConnectionTimeout);
+  RunFor(kBrEdrCreateConnectionTimeout);
+  RunFor(kBrEdrCreateConnectionTimeout);
   EXPECT_EQ(ToResult(HostError::kTimedOut), status);
   EXPECT_TRUE(IsNotConnected(peer));
 }
@@ -2609,7 +2604,7 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
   EXPECT_TRUE(IsInitializing(peer));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(fit::ok(), status);
   EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
   EXPECT_FALSE(IsNotConnected(peer));
@@ -2641,11 +2636,11 @@
   };
 
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesCompleteFailed);
   QueueDisconnection(kConnectionHandle);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
   EXPECT_TRUE(IsNotConnected(peer));
@@ -2677,7 +2672,7 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
   EXPECT_TRUE(IsInitializing(peer));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(fit::ok(), status);
   EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
   EXPECT_FALSE(IsNotConnected(peer));
@@ -2724,7 +2719,7 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
 
   // Run the loop which should complete both requests
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), status);
   EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
@@ -2757,7 +2752,7 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
   EXPECT_TRUE(IsInitializing(peer));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Launch second request, which should not complete immediately.
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
@@ -2765,7 +2760,7 @@
 
   // Finishing interrogation should complete both requests.
   CompleteInterrogation(kConnectionHandle);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), status);
   EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
@@ -2808,15 +2803,15 @@
   ASSERT_TRUE(peer_a->bredr());
   EXPECT_TRUE(IsInitializing(peer_a));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Launch second inflight request (this will wait for the first)
   EXPECT_TRUE(connmgr()->Connect(peer_b->identifier(), callback_b));
   ASSERT_TRUE(peer_b->bredr());
 
   // Run the loop which should complete both requests
-  RunLoopFor(kBrEdrCreateConnectionTimeout);
-  RunLoopFor(kBrEdrCreateConnectionTimeout);
+  RunFor(kBrEdrCreateConnectionTimeout);
+  RunFor(kBrEdrCreateConnectionTimeout);
 
   EXPECT_TRUE(status_a.is_error());
   EXPECT_EQ(fit::ok(), status_b);
@@ -2853,12 +2848,12 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
   EXPECT_TRUE(IsInitializing(peer));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   test_device()->SendCommandChannelPacket(kConnectionComplete);
   QueueSuccessfulInterrogation(peer->address(), kConnectionHandle);
   QueueDisconnection(kConnectionHandle);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), status);
   EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
@@ -2898,19 +2893,19 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
   // Cause the initial Create Connection to wait for 14s for Connection Complete
-  RunLoopFor(zx::sec(14));
+  RunFor(std::chrono::seconds(14));
   ASSERT_TRUE(test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));
   // Verify higher layers have not been notified of failure.
   EXPECT_EQ(ToResult(HostError::kFailed), status);
   // Cause the first retry Create Connection to wait for 14s for Connection Complete - now 28s since
   // the first Create Connection, bumping up on the retry window limit of 30s.
-  RunLoopFor(zx::sec(14));
+  RunFor(std::chrono::seconds(14));
   // Cause a second retry.
   ASSERT_TRUE(test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));
   // Verify higher layers have not been notified of failure until the Connection Complete propagates
   EXPECT_EQ(ToResult(HostError::kFailed), status);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(fit::ok(), status);
   EXPECT_TRUE(HasConnectionTo(peer, conn_ref));
   EXPECT_EQ(conn_ref->link().role(), pw::bluetooth::emboss::ConnectionRole::CENTRAL);
@@ -2936,15 +2931,15 @@
 
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
-  RunLoopFor(zx::sec(15));
+  RunFor(std::chrono::seconds(15));
   // Higher layers should not be notified yet.
   EXPECT_EQ(fit::ok(), status);
   ASSERT_TRUE(test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));
 
   // Create Connection will retry, and it hangs for 16s before ConnectionCompletePageTimeout
-  RunLoopFor(zx::sec(16));
+  RunFor(std::chrono::seconds(16));
   ASSERT_TRUE(test_device()->SendCommandChannelPacket(kConnectionCompletePageTimeout));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Create Connection will *not* be tried again as we are outside of the retry window.
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PAGE_TIMEOUT), status);
 }
@@ -2988,7 +2983,7 @@
   EXPECT_TRUE(IsInitializing(peer_b));
 
   // Run the loop which should complete both requests
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The Connect() request to peer_a should fail with the Page Timeout status code without retrying
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PAGE_TIMEOUT), status_a);
@@ -3016,7 +3011,7 @@
   EXPECT_TRUE(connmgr()->Connect(peer_b->identifier(), callback_b));
 
   // Put the first connection into flight.
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   ASSERT_TRUE(IsInitializing(peer_a));
   ASSERT_TRUE(IsInitializing(peer_b));
@@ -3031,14 +3026,14 @@
   // Peer successfully connects to us.
   QueueSuccessfulIncomingConn(kTestDevAddr);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_FALSE(IsNotConnected(peer));
 
   // Disconnect locally from an API Request.
   QueueDisconnection(kConnectionHandle);
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(IsNotConnected(peer));
 
   // Peer tries to connect to us. We should reject the connection.
@@ -3051,23 +3046,21 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(IsNotConnected(peer));
 
   // After the cooldown time, a successful incoming connection can happen.
-  RunLoopFor(zx::sec(std::chrono::duration_cast<std::chrono::seconds>(
-                         BrEdrConnectionManager::kLocalDisconnectCooldownDuration)
-                         .count()));
+  RunFor(BrEdrConnectionManager::kLocalDisconnectCooldownDuration);
 
   QueueRepeatIncomingConn(kTestDevAddr);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_FALSE(IsNotConnected(peer));
 
   // Can still connect out if we disconnect locally.
   QueueDisconnection(kConnectionHandle);
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   EXPECT_TRUE(IsNotConnected(peer));
 
@@ -3088,7 +3081,7 @@
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
 
   // Complete connection.
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   EXPECT_EQ(fit::ok(), status);
   EXPECT_TRUE(HasConnectionTo(peer, connection));
@@ -3096,23 +3089,23 @@
 
   // Remote disconnections can reconnect immediately
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(IsNotConnected(peer));
 
   QueueRepeatIncomingConn(kTestDevAddr);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_FALSE(IsNotConnected(peer));
 
   // If the reason is not kApiRequest, then the remote peer can reconnect immediately.
   QueueDisconnection(kConnectionHandle);
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kPairingFailed));
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(IsNotConnected(peer));
 
   QueueRepeatIncomingConn(kTestDevAddr);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_FALSE(IsNotConnected(peer));
 
   // Queue disconnection for teardown.
@@ -3125,14 +3118,14 @@
   // Peer successfully connects to us.
   QueueSuccessfulIncomingConn(kTestDevAddr);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_FALSE(IsNotConnected(peer));
 
   // Disconnect locally from an API Request.
   QueueDisconnection(kConnectionHandle);
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(IsNotConnected(peer));
 
   // Peer tries to connect to us. We should reject the connection.
@@ -3145,7 +3138,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(IsNotConnected(peer));
 
   // If we initiate a connection out, then an incoming connection can succeed, even if
@@ -3156,7 +3149,7 @@
   hci::Result<> status = fit::ok();
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), CALLBACK_EXPECT_FAILURE(status)));
   EXPECT_TRUE(IsInitializing(peer));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The outgoing connection failed to succeed
   EXPECT_TRUE(IsNotConnected(peer));
@@ -3164,7 +3157,7 @@
   // but an incoming connection can now succeed, since our intent is to connect now
   QueueRepeatIncomingConn(kTestDevAddr);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_FALSE(IsNotConnected(peer));
 
   // Queue disconnection for teardown.
@@ -3190,7 +3183,7 @@
                                       kChannelParams);
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Peer should still connect successfully.
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -3200,7 +3193,7 @@
   EXPECT_FALSE(IsNotConnected(peer));
 
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(IsNotConnected(peer));
 }
@@ -3217,7 +3210,7 @@
   QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -3226,7 +3219,7 @@
   QueueSuccessfulIncomingConn(kTestDevAddr2, kConnectionHandle2);
   test_device()->SendCommandChannelPacket(testing::ConnectionRequestPacket(kTestDevAddr2));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer2 = peer_cache()->FindByAddress(kTestDevAddr2);
   ASSERT_TRUE(peer2);
@@ -3259,7 +3252,7 @@
       /*payload_size=*/1);
   packet_0->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
   connection_0.QueuePacket(std::move(packet_0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_ACL_PACKET_OUT(test_device(),
                         StaticByteBuffer(
@@ -3275,7 +3268,7 @@
       /*payload_size=*/1);
   packet_1->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
   connection_1.QueuePacket(std::move(packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_EQ(connection_1.queued_packets().size(), 1u);
@@ -3284,7 +3277,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnect, &kDisconnectRsp);
 
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Packet for |kConnectionHandle2| should not have been sent before Disconnection Complete event.
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
@@ -3294,7 +3287,7 @@
   acl_data_channel()->UnregisterConnection(kConnectionHandle);
 
   test_device()->SendCommandChannelPacket(kDisconnectionComplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(IsNotConnected(peer));
 
@@ -3326,7 +3319,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -3360,7 +3353,7 @@
   connmgr()->Pair(peer->identifier(), kNoSecurityRequirements, pairing_complete_cb);
   ASSERT_TRUE(IsInitializing(peer));
   ASSERT_FALSE(peer->bonded());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(fit::ok(), pairing_status);
   ASSERT_TRUE(IsConnected(peer));
@@ -3374,7 +3367,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kIncomingConnTransactions, transaction_count());
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
@@ -3406,7 +3399,7 @@
   };
 
   connmgr()->Pair(peer->identifier(), kNoSecurityRequirements, pairing_complete_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(fit::ok(), pairing_status);
   ASSERT_TRUE(IsConnected(peer));
@@ -3417,7 +3410,7 @@
 
   // Note that we do not call QueueSuccessfulPairing twice, even though we pair twice - this is to
   // test that pairing on an already-paired link succeeds without sending any messages to the peer.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(fit::ok(), pairing_status);
   ASSERT_TRUE(peer->bonded());
 
@@ -3434,7 +3427,7 @@
   QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -3449,7 +3442,7 @@
       [](PeerId, sm::Result<> status) { EXPECT_EQ(fit::ok(), status); });
 
   QueueSuccessfulPairing();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   l2cap()->ExpectOutboundL2capChannel(kConnectionHandle, kPSM, kLocalId, 0x41, params);
 
@@ -3462,7 +3455,7 @@
   };
   connmgr()->OpenL2capChannel(peer->identifier(), kPSM, kNoSecurityRequirements, params, sock_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, sock_cb_count);
   ASSERT_TRUE(chan_info);
   EXPECT_EQ(*params.mode, chan_info->mode);
@@ -3494,7 +3487,7 @@
 
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), callback));
   ASSERT_TRUE(peer->bredr());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(fit::ok(), status);
 
   test_device()->SendCommandChannelPacket(testing::EncryptionChangeEventPacket(
@@ -3502,7 +3495,7 @@
       hci_spec::EncryptionStatus::kOff));
   test_device()->SendCommandChannelPacket(testing::DisconnectionCompletePacket(
       kConnectionHandle, pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(IsNotConnected(peer));
 }
@@ -3511,7 +3504,7 @@
   QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -3545,7 +3538,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), kPSM0, sec_reqs, l2cap::ChannelParameters(),
                               sock_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, sock_cb_count);
 
   // New pairing delegate with display can support authenticated pairing.
@@ -3568,7 +3561,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), kPSM1, sec_reqs1, l2cap::ChannelParameters(),
                               sock_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2u, sock_cb_count);
 
   QueueDisconnection(kConnectionHandle);
@@ -3578,7 +3571,7 @@
   QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
@@ -3618,7 +3611,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), kPSM0, sec_reqs_none, l2cap::ChannelParameters(),
                               sock_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, sock_cb_count);
 
   // Pairing caused by insufficient link key.
@@ -3630,7 +3623,7 @@
   connmgr()->OpenL2capChannel(peer->identifier(), kPSM1, sec_reqs_auth, l2cap::ChannelParameters(),
                               sock_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2u, sock_cb_count);
 
   // Pairing should not be attempted a third time.
@@ -3653,7 +3646,7 @@
 TEST_F(BrEdrConnectionManagerTest, OpenScoConnectionInitiator) {
   QueueSuccessfulIncomingConn();
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
 
@@ -3675,7 +3668,7 @@
   auto req_handle =
       connmgr()->OpenScoConnection(peer->identifier(), {kScoConnection}, std::move(conn_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value()->handle(), kScoConnectionHandle);
@@ -3685,7 +3678,7 @@
   QueueDisconnection(kScoConnectionHandle);
   QueueDisconnection(kConnectionHandle);
   connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 class ScoLinkTypesTest : public BrEdrConnectionManagerTest,
@@ -3694,7 +3687,7 @@
 TEST_P(ScoLinkTypesTest, OpenScoConnectionResponder) {
   QueueSuccessfulIncomingConn();
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
 
@@ -3723,7 +3716,7 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(peer->address(), sco_conn_params),
       &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   constexpr hci_spec::ConnectionHandle kScoConnectionHandle = 0x41;
@@ -3731,7 +3724,7 @@
       kScoConnectionHandle, peer->address(), /*link_type=*/GetParam(),
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
@@ -3741,7 +3734,7 @@
   QueueDisconnection(kScoConnectionHandle);
   QueueDisconnection(kConnectionHandle);
   connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 INSTANTIATE_TEST_SUITE_P(BrEdrConnectionManagerTest, ScoLinkTypesTest,
@@ -3765,7 +3758,7 @@
       &status_event, &complete_event);
   test_device()->SendCommandChannelPacket(
       testing::ConnectionRequestPacket(kTestDevAddr, /*link_type=*/GetParam()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 INSTANTIATE_TEST_SUITE_P(BrEdrConnectionManagerTest, UnconnectedLinkTypesTest,
@@ -3787,7 +3780,7 @@
           kTestDevAddr, pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER),
       &status_event, &complete_event);
   test_device()->SendCommandChannelPacket(testing::ConnectionRequestPacket(kTestDevAddr, linktype));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(BrEdrConnectionManagerTest, IncomingConnectionRacesOutgoing) {
@@ -3814,7 +3807,7 @@
   // We expect it to be accepted, and then return a command status response, but not a
   // ConnectionComplete event yet
   EXPECT_CMD_PACKET_OUT(test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The controller now establishes the link, but will respond to the outgoing connection with the
   // hci error: `ConnectionAlreadyExists`
@@ -3828,7 +3821,7 @@
   test_device()->SendCommandChannelPacket(kConnectionComplete);
   // We expect to connect and begin interrogation, and for our connect() callback to have been run
   QueueSuccessfulInterrogation(kTestDevAddr, kConnectionHandle);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(fit::ok(), status);
 
   // Peers are marked as initializing until a pairing procedure finishes.
@@ -3854,20 +3847,20 @@
   // We expect it to be accepted, and then return a command status response, but not a
   // ConnectionComplete event yet
   EXPECT_CMD_PACKET_OUT(test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Meanwhile, a client calls Connect() for the peer. We don't expect any packets out as the
   // connection manager will defer requests that have an active incoming request. Instead, this
   // request will be completed when the incoming procedure completes.
   EXPECT_TRUE(connmgr()->Connect(peer->identifier(), should_succeed));
   // We should still expect to connect
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The controller now notifies us of the complete incoming connection
   test_device()->SendCommandChannelPacket(kConnectionComplete);
   // We expect to connect and begin interrogation, and for the callback passed to Connect() to have
   // been executed when the incoming connection succeeded.
   QueueSuccessfulInterrogation(kTestDevAddr, kConnectionHandle);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(fit::ok(), status);
 
   // Peers are marked as initializing until a pairing procedure finishes.
@@ -3884,7 +3877,7 @@
   // complete yet
   EXPECT_CMD_PACKET_OUT(test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto status_event = testing::CommandStatusPacket(hci_spec::kRejectConnectionRequest,
                                                    pw::bluetooth::emboss::StatusCode::SUCCESS);
@@ -3897,14 +3890,14 @@
   // Our second request should be rejected - we already have an incoming request
   EXPECT_CMD_PACKET_OUT(test_device(), reject_packet, &status_event);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   QueueSuccessfulInterrogation(kTestDevAddr, kConnectionHandle);
   test_device()->SendCommandChannelPacket(kConnectionComplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   test_device()->SendCommandChannelPacket(complete_error);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(IsNotConnected(peer));
 
@@ -3920,7 +3913,7 @@
   // yet
   EXPECT_CMD_PACKET_OUT(test_device(), kAcceptConnectionRequest, &kAcceptConnectionRequestRsp);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // We should now have a peer in the cache to track our incoming request address
   // The peer is marked as 'Initializing` immediately.
@@ -3939,7 +3932,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), testing::AcceptConnectionRequestPacket(kTestDevAddr),
                         &kAcceptConnectionRequestRsp);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto requests_one_request_matcher =
       AllOf(NodeMatches(NameMatches("connection_requests")),
@@ -3956,7 +3949,7 @@
   const auto connection_complete =
       testing::ConnectionCompletePacket(kTestDevAddr, kConnectionHandle);
   test_device()->SendCommandChannelPacket(connection_complete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto* const peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
   ASSERT_EQ(peer->bredr()->connection_state(), Peer::ConnectionState::kInitializing);
@@ -3998,10 +3991,10 @@
   EXPECT_THAT(hierarchy.value(), ChildrenMatch(ElementsAre(conn_mgr_matcher)));
 
   // Delay disconnect so connection has non-zero duration.
-  RunLoopFor(zx::sec(1));
+  RunFor(std::chrono::seconds(1));
   QueueDisconnection(kConnectionHandle);
   EXPECT_TRUE(connmgr()->Disconnect(peer->identifier(), DisconnectReason::kApiRequest));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto incoming_matcher_after_disconnect =
       AllOf(NodeMatches(AllOf(NameMatches("incoming"),
@@ -4044,7 +4037,7 @@
 
   QueueSuccessfulIncomingConn();
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
   EXPECT_EQ(peer->bredr()->connection_state(), Peer::ConnectionState::kInitializing);
@@ -4060,7 +4053,7 @@
 
   test_device()->SendCommandChannelPacket(
       testing::RoleChangePacket(kTestDevAddr, pw::bluetooth::emboss::ConnectionRole::CENTRAL));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(conn_ref->link().role(), pw::bluetooth::emboss::ConnectionRole::CENTRAL);
 
   QueueDisconnection(kConnectionHandle);
@@ -4071,7 +4064,7 @@
 
   QueueSuccessfulIncomingConn();
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
   EXPECT_EQ(peer->bredr()->connection_state(), Peer::ConnectionState::kInitializing);
@@ -4087,7 +4080,7 @@
   test_device()->SendCommandChannelPacket(
       testing::RoleChangePacket(kTestDevAddr, pw::bluetooth::emboss::ConnectionRole::CENTRAL,
                                 pw::bluetooth::emboss::StatusCode::UNSPECIFIED_ERROR));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // The role should not change.
   EXPECT_EQ(conn_ref->link().role(), pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
 
@@ -4100,7 +4093,7 @@
   QueueSuccessfulIncomingConn(kTestDevAddr, kConnectionHandle,
                               /*role_change=*/pw::bluetooth::emboss::ConnectionRole::CENTRAL);
   test_device()->SendCommandChannelPacket(kConnectionRequest);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto* peer = peer_cache()->FindByAddress(kTestDevAddr);
   ASSERT_TRUE(peer);
   EXPECT_EQ(peer->bredr()->connection_state(), Peer::ConnectionState::kInitializing);
@@ -4168,7 +4161,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Ensure that the interrogation has begun but the peer hasn't yet bonded
   EXPECT_EQ(6, transaction_count());
@@ -4204,7 +4197,7 @@
                         &kEncryptionChangeEvent);
   EXPECT_CMD_PACKET_OUT(test_device(), kReadEncryptionKeySize, &kReadEncryptionKeySizeRsp);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   EXPECT_TRUE(l2cap()->IsLinkConnected(kConnectionHandle));
 
@@ -4255,7 +4248,7 @@
 
   test_device()->SendCommandChannelPacket(kConnectionRequest);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Ensure that the interrogation has begun but the peer hasn't yet bonded
   EXPECT_EQ(6, transaction_count());
@@ -4292,7 +4285,7 @@
   // When SC is supported, key type must be of SC type (kUnauthenticatedCombination256 or
   // kAuthenticatedCombination256).
   QueueDisconnection(kConnectionHandle);
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 }
 
 #undef COMMAND_COMPLETE_RSP
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/bredr_discovery_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/bredr_discovery_manager_unittest.cc
index 95188ad..af6736a 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/bredr_discovery_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/bredr_discovery_manager_unittest.cc
@@ -19,7 +19,7 @@
 
 using bt::testing::CommandTransaction;
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 // clang-format off
 #define COMMAND_COMPLETE_RSP(opcode)                                         \
@@ -73,9 +73,9 @@
     EXPECT_CMD_PACKET_OUT(test_device(), kWriteInquiryType, &kWriteInquiryTypeRsp);
 
     discovery_manager_ = std::make_unique<BrEdrDiscoveryManager>(
-        pw_dispatcher(), transport()->command_channel()->AsWeakPtr(), mode, &peer_cache_);
+        dispatcher(), transport()->command_channel()->AsWeakPtr(), mode, &peer_cache_);
 
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   void DestroyDiscoveryManager() { discovery_manager_.reset(); }
@@ -86,7 +86,7 @@
   BrEdrDiscoveryManager* discovery_manager() const { return discovery_manager_.get(); }
 
  private:
-  PeerCache peer_cache_{pw_dispatcher()};
+  PeerCache peer_cache_{dispatcher()};
   std::unique_ptr<BrEdrDiscoveryManager> discovery_manager_;
 
   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BrEdrDiscoveryManagerTest);
@@ -388,14 +388,14 @@
     session = std::move(cb_session);
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   for (auto event : {kInquiryResultIncompleteHeader.view(), kInquiryResultMissingResponses.view(),
                      kInquiryResultIncompleteResponse.view()}) {
     EXPECT_DEATH_IF_SUPPORTED(
         [=] {
           test_device()->SendCommandChannelPacket(event);
-          RunLoopUntilIdle();
+          RunUntilIdle();
         }(),
         ".*");
   }
@@ -426,7 +426,7 @@
 
   EXPECT_FALSE(discovery_manager()->discovering());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, peers_found);
   EXPECT_TRUE(discovery_manager()->discovering());
@@ -435,7 +435,7 @@
 
   test_device()->SendCommandChannelPacket(kInquiryComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Confirm that post-inquiry peer name request is processed correctly.
   Peer* peer = peer_cache()->FindByAddress(kDeviceAddress1);
@@ -450,13 +450,13 @@
   session = nullptr;
   test_device()->SendCommandChannelPacket(kInquiryResult);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, peers_found);
   EXPECT_FALSE(discovery_manager()->discovering());
 
   test_device()->SendCommandChannelPacket(kInquiryComplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // Test: requesting a second discovery should start a session without sending
@@ -479,7 +479,7 @@
 
   EXPECT_FALSE(discovery_manager()->discovering());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(session1);
   EXPECT_EQ(1u, peers_found1);
@@ -494,7 +494,7 @@
     session2 = std::move(cb_session);
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(session2);
   EXPECT_EQ(1u, peers_found1);
@@ -503,18 +503,18 @@
 
   test_device()->SendCommandChannelPacket(kInquiryResult);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, peers_found1);
   EXPECT_EQ(1u, peers_found2);
 
   session1 = nullptr;
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   test_device()->SendCommandChannelPacket(kInquiryResult);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, peers_found1);
   EXPECT_EQ(2u, peers_found2);
@@ -525,7 +525,7 @@
 
   test_device()->SendCommandChannelPacket(kInquiryResult);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, peers_found1);
   EXPECT_EQ(2u, peers_found2);
@@ -534,7 +534,7 @@
 
   test_device()->SendCommandChannelPacket(kInquiryComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // Test: starting a session "while" the other one is stopping a session should
@@ -559,7 +559,7 @@
 
   EXPECT_FALSE(discovery_manager()->discovering());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(session1);
   EXPECT_EQ(1u, peers_found1);
@@ -567,7 +567,7 @@
 
   // Drop the active session.
   session1 = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   std::unique_ptr<BrEdrDiscoverySession> session2;
   size_t peers_found2 = 0u;
@@ -582,7 +582,7 @@
   EXPECT_TRUE(session2);
   test_device()->SendCommandChannelPacket(kInquiryResult);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, peers_found2);
 
@@ -592,7 +592,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), kInquiry, &kInquiryRsp, &kInquiryResult);
   test_device()->SendCommandChannelPacket(kInquiryComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, peers_found1);
   EXPECT_EQ(2u, peers_found2);
@@ -600,7 +600,7 @@
 
   test_device()->SendCommandChannelPacket(kInquiryResult);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, peers_found1);
   EXPECT_EQ(3u, peers_found2);
@@ -612,7 +612,7 @@
   // are sent to the callback.
   test_device()->SendCommandChannelPacket(kInquiryResult);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, peers_found1);
   EXPECT_EQ(3u, peers_found2);
@@ -634,7 +634,7 @@
 
   EXPECT_FALSE(discovery_manager()->discovering());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(discovery_manager()->discovering());
 }
@@ -660,21 +660,21 @@
 
   EXPECT_FALSE(discovery_manager()->discovering());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, peers_found);
   EXPECT_TRUE(discovery_manager()->discovering());
 
   test_device()->SendCommandChannelPacket(kInquiryCompleteError);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(error_callback);
   EXPECT_FALSE(discovery_manager()->discovering());
 
   session = nullptr;
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // clang-format off
@@ -754,7 +754,7 @@
   kNewName.append("ABCDEFGHIJKLMNOPQRSTUVW");
   discovery_manager()->UpdateLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Local name should not be set, callback shouldn't be called yet.
   EXPECT_NE(kNewName, discovery_manager()->local_name());
@@ -763,7 +763,7 @@
   test_device()->SendCommandChannelPacket(kWriteLocalNameRsp);
   EXPECT_CMD_PACKET_OUT(test_device(), kWriteExtInquiryResponseMaxLen, );
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Still waiting on EIR response.
   // Local name should not be set, callback shouldn't be called yet.
@@ -772,7 +772,7 @@
 
   test_device()->SendCommandChannelPacket(kWriteExtendedInquiryResponseRsp);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kNewName, discovery_manager()->local_name());
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), result);
@@ -795,7 +795,7 @@
   const std::string kNewName = "ABC";
   discovery_manager()->UpdateLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Local name should not be set, callback shouldn't be called yet.
   EXPECT_NE(kNewName, discovery_manager()->local_name());
@@ -804,7 +804,7 @@
   test_device()->SendCommandChannelPacket(kWriteLocalNameRsp);
   EXPECT_CMD_PACKET_OUT(test_device(), kWriteExtendedInquiryResponse, );
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Still waiting on EIR response.
   // Local name should not be set, callback shouldn't be called yet.
@@ -813,7 +813,7 @@
 
   test_device()->SendCommandChannelPacket(kWriteExtendedInquiryResponseRsp);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kNewName, discovery_manager()->local_name());
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), result);
@@ -836,7 +836,7 @@
   const std::string kNewName = "ABC";
   discovery_manager()->UpdateLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Local name should not be set, callback shouldn't be called yet.
   EXPECT_NE(kNewName, discovery_manager()->local_name());
@@ -845,7 +845,7 @@
   // Send a response error.
   test_device()->SendCommandChannelPacket(kWriteLocalNameRspError);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // |local_name_| should not be updated, return status should be error.
   EXPECT_NE(kNewName, discovery_manager()->local_name());
@@ -870,7 +870,7 @@
   const std::string kNewName = "ABC";
   discovery_manager()->UpdateLocalName(kNewName, name_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Local name should not be set, callback shouldn't be called yet.
   EXPECT_NE(kNewName, discovery_manager()->local_name());
@@ -880,7 +880,7 @@
   test_device()->SendCommandChannelPacket(kWriteLocalNameRsp);
   EXPECT_CMD_PACKET_OUT(test_device(), kWriteExtendedInquiryResponse, );
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Still waiting on EIR response.
   // Local name should not be set, callback shouldn't be called yet.
@@ -890,7 +890,7 @@
   // kWriteExtendedInquiryResponse should fail.
   test_device()->SendCommandChannelPacket(kWriteExtendedInquiryResponseRspError);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // |local_name_| should not be updated, return status should be error.
   EXPECT_NE(kNewName, discovery_manager()->local_name());
@@ -912,7 +912,7 @@
 
   discovery_manager()->RequestDiscoverable(session_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(0u, sessions.size());
   EXPECT_FALSE(discovery_manager()->discoverable());
@@ -921,14 +921,14 @@
 
   test_device()->SendCommandChannelPacket(kReadScanEnableRspNone);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Request another session while the first is pending.
   discovery_manager()->RequestDiscoverable(session_cb);
 
   test_device()->SendCommandChannelPacket(kWriteScanEnableRsp);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, sessions.size());
   EXPECT_TRUE(discovery_manager()->discoverable());
@@ -943,7 +943,7 @@
 
   sessions.clear();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(discovery_manager()->discoverable());
 }
@@ -963,7 +963,7 @@
 
   discovery_manager()->RequestDiscoverable(session_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, sessions.size());
   EXPECT_TRUE(discovery_manager()->discoverable());
@@ -972,7 +972,7 @@
 
   sessions.clear();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Request a new discovery before the procedure finishes.
   // This will queue another ReadScanEnable just in case the disable write is
@@ -984,7 +984,7 @@
 
   // This shouldn't send any WriteScanEnable because we're already in the right
   // mode (MockController will assert if we do as it's not expecting)
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, sessions.size());
   EXPECT_TRUE(discovery_manager()->discoverable());
@@ -993,7 +993,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), kWriteScanEnableBoth, &kWriteScanEnableRsp);
   test_device()->SendCommandChannelPacket(kReadScanEnableRspPage);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, sessions.size());
   EXPECT_TRUE(discovery_manager()->discoverable());
@@ -1003,7 +1003,7 @@
 
   sessions.clear();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(discovery_manager()->discoverable());
 }
@@ -1031,7 +1031,7 @@
 
   EXPECT_FALSE(discovery_manager()->discovering());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(session1);
   EXPECT_EQ(2u, peers_found1);
@@ -1050,7 +1050,7 @@
 
   test_device()->SendCommandChannelPacket(kInquiryComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(discovery_manager()->discovering());
 }
@@ -1072,7 +1072,7 @@
     cb_session->set_result_callback([&peers_found](auto&) { peers_found++; });
     session = std::move(cb_session);
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   session = nullptr;
 
   EXPECT_EQ(1u, peers_found);
@@ -1081,7 +1081,7 @@
 
   test_device()->SendCommandChannelPacket(kInquiryComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(BrEdrDiscoveryManagerTest, ExtendedInquiryResultUpgradesKnownLowEnergyPeerToDualMode) {
@@ -1105,7 +1105,7 @@
     cb_session->set_result_callback([&peers_found](auto&) { peers_found++; });
     session = std::move(cb_session);
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   session = nullptr;
 
   EXPECT_EQ(2u, peers_found);
@@ -1114,7 +1114,7 @@
 
   test_device()->SendCommandChannelPacket(kInquiryComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 #ifndef NINSPECT
@@ -1133,7 +1133,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), kReadScanEnable, &kReadScanEnableRspPage);
   EXPECT_CMD_PACKET_OUT(test_device(), kWriteScanEnableBoth, &kWriteScanEnableRsp);
   discovery_manager()->RequestDiscoverable(session_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(discoverable_session);
 
   auto properties = inspect::ReadFromVmo(inspector.DuplicateVmo())
@@ -1148,11 +1148,11 @@
       {UintIs("discoverable_sessions", 0), UintIs("discoverable_sessions_count", 1),
        UintIs("last_discoverable_length_sec", 4)});
 
-  RunLoopFor(zx::sec(4));
+  RunFor(std::chrono::seconds(4));
   discoverable_session = nullptr;
   EXPECT_CMD_PACKET_OUT(test_device(), kReadScanEnable, &kReadScanEnableRspBoth);
   EXPECT_CMD_PACKET_OUT(test_device(), kWriteScanEnablePage, &kWriteScanEnableRsp);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   properties = inspect::ReadFromVmo(inspector.DuplicateVmo())
                    .take_value()
@@ -1172,7 +1172,7 @@
   });
 
   EXPECT_CMD_PACKET_OUT(test_device(), kInquiry, &kInquiryRsp);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(discovery_session);
 
   properties = inspect::ReadFromVmo(inspector.DuplicateVmo())
@@ -1187,11 +1187,11 @@
       ::testing::IsSupersetOf({UintIs("discovery_sessions", 0), UintIs("inquiry_sessions_count", 1),
                                UintIs("last_inquiry_length_sec", 7)});
 
-  RunLoopFor(zx::sec(7));
+  RunFor(std::chrono::seconds(7));
   discovery_session = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   test_device()->SendCommandChannelPacket(kInquiryComplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   properties = inspect::ReadFromVmo(inspector.DuplicateVmo())
                    .take_value()
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/bredr_interrogator_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/bredr_interrogator_unittest.cc
index 7b3884b..35d5b20 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/bredr_interrogator_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/bredr_interrogator_unittest.cc
@@ -4,8 +4,6 @@
 
 #include "src/connectivity/bluetooth/core/bt-host/gap/bredr_interrogator.h"
 
-#include <lib/async/default.h>
-
 #include "src/connectivity/bluetooth/core/bt-host/gap/peer_cache.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci-spec/protocol.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci-spec/util.h"
@@ -37,7 +35,7 @@
 
 using bt::testing::CommandTransaction;
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 class BrEdrInterrogatorTest : public TestingBase {
  public:
@@ -47,7 +45,7 @@
   void SetUp() override {
     TestingBase::SetUp();
 
-    peer_cache_ = std::make_unique<PeerCache>(pw_dispatcher());
+    peer_cache_ = std::make_unique<PeerCache>(dispatcher());
     peer_ = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
     EXPECT_FALSE(peer_->name());
     EXPECT_FALSE(peer_->version());
@@ -60,7 +58,7 @@
   }
 
   void TearDown() override {
-    RunLoopUntilIdle();
+    RunUntilIdle();
     test_device()->Stop();
     interrogator_ = nullptr;
     peer_cache_ = nullptr;
@@ -137,7 +135,7 @@
 
   hci::Result<> status = fit::ok();
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(status.is_error());
 }
 
@@ -146,7 +144,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(status.has_value());
   EXPECT_EQ(fit::ok(), *status);
@@ -163,7 +161,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(status.has_value());
   EXPECT_EQ(fit::ok(), *status);
@@ -171,7 +169,7 @@
 
   QueueSuccessfulReadRemoteExtendedFeatures(kConnectionHandle);
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(status.has_value());
   EXPECT_EQ(fit::ok(), *status);
 }
@@ -187,7 +185,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(status.has_value());
   EXPECT_FALSE(status->is_ok());
@@ -208,7 +206,7 @@
   result.reset();
 
   // Events should be ignored.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(result.has_value());
 }
 
@@ -220,7 +218,7 @@
     status = cb_status;
     DestroyInterrogator();
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(status.has_value());
   EXPECT_TRUE(status->is_ok());
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/gap.h b/src/connectivity/bluetooth/core/bt-host/gap/gap.h
index 38607ac..3696320 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/gap.h
+++ b/src/connectivity/bluetooth/core/bt-host/gap/gap.h
@@ -59,7 +59,8 @@
 
 // Constants used in Low Energy (see Core Spec v5.0, Vol 3, Part C, Appendix A).
 
-constexpr zx::duration kLEGeneralDiscoveryScanMin = zx::msec(10240);
+constexpr pw::chrono::SystemClock::duration kLEGeneralDiscoveryScanMin =
+    std::chrono::milliseconds(10240);
 constexpr pw::chrono::SystemClock::duration kPwLEGeneralDiscoveryScanMin =
     std::chrono::milliseconds(10240);
 constexpr zx::duration kLEGeneralDiscoveryScanMinCoded = zx::msec(30720);
@@ -110,15 +111,16 @@
 constexpr uint16_t kLEAdvertisingSlowIntervalCodedMax = 0x1680;  // 3.6 s
 
 // Timeout used for the LE Create Connection command.
-constexpr zx::duration kLECreateConnectionTimeout = zx::sec(20);
+constexpr pw::chrono::SystemClock::duration kLECreateConnectionTimeout = std::chrono::seconds(20);
 constexpr pw::chrono::SystemClock::duration kPwLECreateConnectionTimeout = std::chrono::seconds(20);
 // Timeout used for the Br/Edr Create Connection command.
-constexpr zx::duration kBrEdrCreateConnectionTimeout = zx::sec(20);
+constexpr pw::chrono::SystemClock::duration kBrEdrCreateConnectionTimeout =
+    std::chrono::seconds(20);
 constexpr pw::chrono::SystemClock::duration kPwBrEdrCreateConnectionTimeout =
     std::chrono::seconds(20);
 
 // Timeout used for scanning during LE General CEP. Selected to be longer than the scan period.
-constexpr zx::duration kLEGeneralCepScanTimeout = zx::sec(20);
+constexpr pw::chrono::SystemClock::duration kLEGeneralCepScanTimeout = std::chrono::seconds(20);
 constexpr pw::chrono::SystemClock::duration kPwLEGeneralCepScanTimeout = std::chrono::seconds(20);
 
 // Connection Interval Timing Parameters (see v5.0, Vol 3, Part C,
@@ -126,11 +128,11 @@
 constexpr zx::duration kLEConnectionParameterTimeout = zx::sec(30);
 // Recommended minimum time upon connection establishment before the central starts a connection
 // update procedure.
-constexpr zx::duration kLEConnectionPauseCentral = zx::sec(1);
+constexpr pw::chrono::SystemClock::duration kLEConnectionPauseCentral = std::chrono::seconds(1);
 constexpr pw::chrono::SystemClock::duration kPwLEConnectionPauseCentral = std::chrono::seconds(1);
 // Recommended minimum time upon connection establishment before the peripheral starts a connection
 // update procedure.
-constexpr zx::duration kLEConnectionPausePeripheral = zx::sec(5);
+constexpr pw::chrono::SystemClock::duration kLEConnectionPausePeripheral = std::chrono::seconds(5);
 constexpr pw::chrono::SystemClock::duration kPwLEConnectionPausePeripheral =
     std::chrono::seconds(5);
 
@@ -141,12 +143,12 @@
 
 // Time interval that must expire before a temporary device is removed from the
 // cache.
-constexpr zx::duration kCacheTimeout = zx::sec(60);
+constexpr pw::chrono::SystemClock::duration kCacheTimeout = std::chrono::seconds(60);
 constexpr pw::chrono::SystemClock::duration kPwCacheTimeout = std::chrono::seconds(60);
 
 // Time interval between random address changes when privacy is enabled (see
 // T_GAP(private_addr_int) in 5.0 Vol 3, Part C, Appendix A)
-constexpr zx::duration kPrivateAddressTimeout = zx::min(15);
+constexpr pw::chrono::SystemClock::duration kPrivateAddressTimeout = std::chrono::minutes(15);
 constexpr pw::chrono::SystemClock::duration kPwPrivateAddressTimeout = std::chrono::minutes(15);
 
 // Maximum duration for which a scannable advertisement will be stored and not reported to
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc
index 6cdcbf8..1113442 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc
@@ -4,8 +4,6 @@
 
 #include "low_energy_address_manager.h"
 
-#include <lib/fit/function.h>
-
 #include "gap.h"
 #include "src/connectivity/bluetooth/core/bt-host/sm/util.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
@@ -17,7 +15,7 @@
 using testing::CommandTransaction;
 using testing::MockController;
 
-using TestingBase = testing::ControllerTest<MockController>;
+using TestingBase = testing::FakeDispatcherControllerTest<MockController>;
 
 const DeviceAddress kPublic(DeviceAddress::Type::kLEPublic, {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});
 
@@ -31,7 +29,7 @@
     TestingBase::SetUp();
     addr_mgr_ = std::make_unique<LowEnergyAddressManager>(
         kPublic, [this] { return IsRandomAddressChangeAllowed(); }, cmd_channel()->AsWeakPtr(),
-        pw_dispatcher_);
+        dispatcher());
     ASSERT_EQ(kPublic, addr_mgr()->identity_address());
     ASSERT_FALSE(addr_mgr()->irk());
     addr_mgr_->register_address_changed_callback([&](auto) { address_changed_cb_count_++; });
@@ -49,7 +47,7 @@
       result = addr;
       called = true;
     });
-    RunLoopUntilIdle();
+    RunUntilIdle();
     EXPECT_TRUE(called);
     return result;
   }
@@ -64,7 +62,6 @@
   size_t address_changed_cb_count() const { return address_changed_cb_count_; }
 
  private:
-  pw::async::fuchsia::FuchsiaDispatcher pw_dispatcher_{dispatcher()};
   std::unique_ptr<LowEnergyAddressManager> addr_mgr_;
   bool random_address_change_allowed_ = true;
   size_t address_changed_cb_count_ = 0;
@@ -105,7 +102,7 @@
   EXPECT_EQ(address_changed_cb_count(), 0u);
   // Further requests to enable should not trigger additional HCI commands.
   addr_mgr()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(addr_mgr()->PrivacyEnabled());
   // We should have received a HCI command with a RPA resolvable using |kIrk|.
@@ -134,7 +131,7 @@
   // Disabling Privacy should result in the Public address being used so we expect a notification.
   EXPECT_EQ(address_changed_cb_count(), 2u);
   addr_mgr()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(addr, EnsureLocalAddress());
   EXPECT_TRUE(addr.IsResolvablePrivate());
@@ -167,7 +164,7 @@
   // trigger additional HCI commands.
   EXPECT_EQ(address_changed_cb_count(), 0u);
   addr_mgr()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // We should have received a HCI command with a NRPA.
   EXPECT_EQ(1, hci_cmd_count);
@@ -234,7 +231,7 @@
 
   // No HCI commands should be sent while disallowed.
   addr_mgr()->EnablePrivacy(true);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0, hci_count);
 
   EXPECT_TRUE(addr_mgr()->PrivacyEnabled());
@@ -282,7 +279,7 @@
 
   // A new address should be generated and configured after the random address
   // interval.
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   EXPECT_EQ(1, hci_count);
   // Address has changed due to timeout.
   EXPECT_EQ(address_changed_cb_count(), 2u);
@@ -323,7 +320,7 @@
   // After the interval ends, the address should be marked as expired but should
   // not send an HCI command while the command is disallowed.
   set_random_address_change_allowed(false);
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   EXPECT_EQ(addr1, EnsureLocalAddress());
   EXPECT_EQ(0, hci_count);
 
@@ -361,7 +358,7 @@
   // No HCI commands should get sent after private address interval expires.
   int hci_count = 0;
   test_device()->SetTransactionCallback([&] { hci_count++; });
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   EXPECT_EQ(0, hci_count);
   EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress().type());
 }
@@ -385,7 +382,7 @@
   EXPECT_EQ(1, hci_count);
 
   // No HCI commands should get sent after private address interval expires.
-  RunLoopFor(kPrivateAddressTimeout);
+  RunFor(kPrivateAddressTimeout);
   EXPECT_EQ(1, hci_count);
   EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress().type());
 }
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_advertising_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_advertising_manager_unittest.cc
index b86d73b..3d4b5243 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_advertising_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_advertising_manager_unittest.cc
@@ -16,14 +16,13 @@
 #include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller.h"
 #include "src/connectivity/bluetooth/core/bt-host/transport/error.h"
-#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
 
 namespace bt {
 using testing::FakeController;
 
 namespace gap {
 namespace {
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 
 constexpr size_t kDefaultMaxAdSize = 23;
 constexpr size_t kDefaultFakeAdSize = 20;
@@ -241,7 +240,7 @@
   FakeLowEnergyAdvertiser* advertiser() const { return advertiser_.get(); }
 
  private:
-  hci::FakeLocalAddressDelegate fake_address_delegate_{pw_dispatcher()};
+  hci::FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};
 
   // TODO(armansito): The address mapping is currently broken since the gap::LEAM always assigns the
   // controller random address. Make this track each instance by instance ID instead once the
@@ -263,7 +262,7 @@
                               /*connect_callback=*/nullptr, kTestInterval, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   ASSERT_EQ(1u, ad_store().size());
@@ -278,7 +277,7 @@
                               /*connect_callback=*/nullptr, kTestInterval, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_EQ(1u, ad_store().size());
@@ -287,7 +286,7 @@
                               /*connect_callback=*/nullptr, kTestInterval, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetErrorCallback());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_EQ(1u, ad_store().size());
@@ -305,7 +304,7 @@
                               /*connect_callback=*/nullptr, kTestInterval, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_EQ(1u, ad_store().size());
@@ -328,7 +327,7 @@
   adv_mgr()->StartAdvertising(CreateFakeAdvertisingData(), AdvertisingData(),
                               /*connect_callback=*/nullptr, kTestInterval, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetErrorCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_FALSE(adv_mgr()->advertising());
@@ -348,7 +347,7 @@
                               kTestInterval, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   advertised_id = last_ad_id();
@@ -356,7 +355,7 @@
   DeviceAddress peer_address(DeviceAddress::Type::kLEPublic, {3, 2, 1, 1, 2, 3});
   advertiser()->OnIncomingConnection(1, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL,
                                      peer_address, hci_spec::LEConnectionParameters());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(link);
 
   // Make sure that the link has the correct local and peer addresses assigned.
@@ -383,7 +382,7 @@
                               /*connect_callback=*/nullptr, kTestInterval, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_EQ(1u, ad_store().size());
@@ -406,7 +405,7 @@
                               CreateFakeAdvertisingData(/*packed_size=*/21), NopConnectCallback,
                               AdvertisingInterval::FAST1, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(MoveLastStatus());
   ASSERT_TRUE(current_adv());
   EXPECT_EQ(kLEAdvertisingFastIntervalMin1, current_adv()->interval_min);
@@ -417,7 +416,7 @@
                               CreateFakeAdvertisingData(/*packed_size=*/21), NopConnectCallback,
                               AdvertisingInterval::FAST2, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(MoveLastStatus());
   ASSERT_TRUE(current_adv());
   EXPECT_EQ(kLEAdvertisingFastIntervalMin2, current_adv()->interval_min);
@@ -428,7 +427,7 @@
                               CreateFakeAdvertisingData(/*packed_size=*/21), NopConnectCallback,
                               AdvertisingInterval::SLOW, /*anonymous=*/false,
                               /*include_tx_power_level=*/false, GetSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(MoveLastStatus());
   ASSERT_TRUE(current_adv());
   EXPECT_EQ(kLEAdvertisingSlowIntervalMin, current_adv()->interval_min);
@@ -447,7 +446,7 @@
       CreateFakeAdvertisingData(), CreateFakeAdvertisingData(/*packed_size=*/21),
       /*connect_callback=*/nullptr, AdvertisingInterval::FAST1, /*anonymous=*/false,
       /*include_tx_power_level=*/false, GetSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(MoveLastStatus());
   ASSERT_TRUE(current_adv());
   EXPECT_EQ(kLEAdvertisingFastIntervalMin2, current_adv()->interval_min);
@@ -458,7 +457,7 @@
       CreateFakeAdvertisingData(), CreateFakeAdvertisingData(/*packed_size=*/21),
       /*connect_callback=*/nullptr, AdvertisingInterval::FAST2, /*anonymous=*/false,
       /*include_tx_power_level=*/false, GetSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(MoveLastStatus());
   ASSERT_TRUE(current_adv());
   EXPECT_EQ(kLEAdvertisingFastIntervalMin2, current_adv()->interval_min);
@@ -469,7 +468,7 @@
       CreateFakeAdvertisingData(), CreateFakeAdvertisingData(/*packed_size=*/21),
       /*connect_callback=*/nullptr, AdvertisingInterval::SLOW, /*anonymous=*/false,
       /*include_tx_power_level=*/false, GetSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(MoveLastStatus());
   ASSERT_TRUE(current_adv());
   EXPECT_EQ(kLEAdvertisingSlowIntervalMin, current_adv()->interval_min);
@@ -487,13 +486,13 @@
                                   ASSERT_EQ(fit::ok(), status);
                                   instance = std::move(i);
                                 });
-    RunLoopUntilIdle();
+    RunUntilIdle();
     EXPECT_TRUE(adv_mgr()->advertising());
 
     // Destroying |instance| should stop the advertisement.
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(adv_mgr()->advertising());
 }
 
@@ -506,12 +505,12 @@
                                 ASSERT_EQ(fit::ok(), status);
                                 instance = std::move(i);
                               });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(adv_mgr()->advertising());
 
   // Destroying |instance| by invoking the move assignment operator should stop the advertisement.
   instance = {};
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(adv_mgr()->advertising());
 }
 
@@ -524,7 +523,7 @@
                                 ASSERT_EQ(fit::ok(), status);
                                 *instance = std::move(i);
                               });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(adv_mgr()->advertising());
 
   // Moving |instance| should transfer the ownership of the advertisement (assignment).
@@ -533,7 +532,7 @@
 
     // Explicitly clearing the old instance should have no effect.
     *instance = {};
-    RunLoopUntilIdle();
+    RunUntilIdle();
     EXPECT_TRUE(adv_mgr()->advertising());
 
     *instance = std::move(move_assigned_instance);
@@ -541,7 +540,7 @@
 
   // Advertisement should not stop when |move_assigned_instance| goes out of scope as it no longer
   // owns the advertisement.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(adv_mgr()->advertising());
 
   // Moving |instance| should transfer the ownership of the advertisement (move-constructor).
@@ -550,12 +549,12 @@
 
     // Explicitly destroying the old instance should have no effect.
     instance.reset();
-    RunLoopUntilIdle();
+    RunUntilIdle();
     EXPECT_TRUE(adv_mgr()->advertising());
   }
 
   // Advertisement should stop when |move_constructed_instance| goes out of scope.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(adv_mgr()->advertising());
 }
 
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h
index 3c02e78..26f1e17 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h
@@ -64,7 +64,8 @@
 class LowEnergyConnectionManager final {
  public:
   // Duration after which connection failures are removed from Inspect.
-  static constexpr zx::duration kInspectRecentConnectionFailuresExpiryDuration = zx::min(10);
+  static constexpr pw::chrono::SystemClock::duration
+      kInspectRecentConnectionFailuresExpiryDuration = std::chrono::minutes(10);
 
   // |hci|: The HCI transport used to track link layer connection events from
   //        the controller.
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc
index a3c6ec2..ba1f1a5 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc
@@ -11,9 +11,6 @@
 #include <memory>
 #include <vector>
 
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
 #include "src/connectivity/bluetooth/core/bt-host/common/assert.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/device_address.h"
@@ -56,7 +53,7 @@
 using bt::testing::FakeController;
 using bt::testing::FakePeer;
 
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 using l2cap::testing::FakeChannel;
 using TestSm = sm::testing::TestSecurityManager;
 using TestSmFactory = sm::testing::TestSecurityManagerFactory;
@@ -74,7 +71,8 @@
 const size_t kLEMaxNumPackets = 10;
 const hci::DataBufferInfo kLEDataBufferInfo(hci_spec::kMaxACLPayloadSize, kLEMaxNumPackets);
 
-constexpr std::array kConnectDelays = {zx::sec(0), zx::sec(2), zx::sec(4)};
+constexpr std::array kConnectDelays = {std::chrono::seconds(0), std::chrono::seconds(2),
+                                       std::chrono::seconds(4)};
 
 const LowEnergyConnectionOptions kConnectionOptions{};
 
@@ -94,28 +92,28 @@
     settings.ApplyLegacyLEConfig();
     test_device()->set_settings(settings);
 
-    peer_cache_ = std::make_unique<PeerCache>(pw_dispatcher());
-    l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(pw_dispatcher());
+    peer_cache_ = std::make_unique<PeerCache>(dispatcher());
+    l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(dispatcher());
 
     const hci::CommandChannel::WeakPtr cmd_weak = cmd_channel()->AsWeakPtr();
 
     connector_ = std::make_unique<hci::LowEnergyConnector>(
-        transport()->GetWeakPtr(), &addr_delegate_, pw_dispatcher(),
+        transport()->GetWeakPtr(), &addr_delegate_, dispatcher(),
         fit::bind_member<&LowEnergyConnectionManagerTest::OnIncomingConnection>(this));
 
-    gatt_ = std::make_unique<gatt::testing::FakeLayer>(pw_dispatcher());
+    gatt_ = std::make_unique<gatt::testing::FakeLayer>(dispatcher());
     sm_factory_ = std::make_unique<TestSmFactory>();
 
     address_manager_ = std::make_unique<LowEnergyAddressManager>(
-        kAdapterAddress, /*delegate=*/[] { return false; }, cmd_weak, pw_dispatcher());
+        kAdapterAddress, /*delegate=*/[] { return false; }, cmd_weak, dispatcher());
     scanner_ = std::make_unique<hci::LegacyLowEnergyScanner>(
-        address_manager_.get(), transport()->GetWeakPtr(), pw_dispatcher());
+        address_manager_.get(), transport()->GetWeakPtr(), dispatcher());
     discovery_manager_ = std::make_unique<LowEnergyDiscoveryManager>(
-        scanner_.get(), peer_cache_.get(), pw_dispatcher());
+        scanner_.get(), peer_cache_.get(), dispatcher());
     conn_mgr_ = std::make_unique<LowEnergyConnectionManager>(
         cmd_weak, &addr_delegate_, connector_.get(), peer_cache_.get(), l2cap_.get(),
         gatt_->GetWeakPtr(), discovery_manager_->GetWeakPtr(),
-        fit::bind_member<&TestSmFactory::CreateSm>(sm_factory_.get()), pw_dispatcher());
+        fit::bind_member<&TestSmFactory::CreateSm>(sm_factory_.get()), dispatcher());
 
     test_device()->set_connection_state_callback(
         fit::bind_member<&LowEnergyConnectionManagerTest::OnConnectionStateChanged>(this));
@@ -194,7 +192,7 @@
   }
 
   std::unique_ptr<l2cap::testing::FakeL2cap> l2cap_;
-  hci::FakeLocalAddressDelegate addr_delegate_{pw_dispatcher()};
+  hci::FakeLocalAddressDelegate addr_delegate_{dispatcher()};
   std::unique_ptr<PeerCache> peer_cache_;
   std::unique_ptr<hci::LowEnergyConnector> connector_;
   std::unique_ptr<gatt::testing::FakeLayer> gatt_;
@@ -245,7 +243,7 @@
 // An error is received via the HCI Command cb_status event
 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerErrorStatus) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_connect_status(
       pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
   test_device()->AddPeer(std::move(fake_peer));
@@ -259,7 +257,7 @@
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(result.is_error());
   EXPECT_EQ(HostError::kFailed, result.error_value());
@@ -269,7 +267,7 @@
 // LE Connection Complete event reports error
 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerFailure) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_connect_response(
       pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
   test_device()->AddPeer(std::move(fake_peer));
@@ -281,7 +279,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(result.is_error());
   EXPECT_EQ(HostError::kFailed, result.error_value());
@@ -300,7 +298,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopFor(kLEGeneralCepScanTimeout);
+  RunFor(kLEGeneralCepScanTimeout);
 
   ASSERT_TRUE(result.is_error());
   EXPECT_EQ(HostError::kTimedOut, result.error_value());
@@ -309,31 +307,31 @@
 
 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerAlreadyInScanCache) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Ensure peer is in scan cache by doing active discovery.
   LowEnergyDiscoverySessionPtr session;
   discovery_mgr()->StartDiscovery(/*active=*/true,
                                   [&session](auto cb_session) { session = std::move(cb_session); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ConnectionResult result = fit::ok(nullptr);
   auto callback = [&result](auto res) { result = std::move(res); };
 
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(fit::ok(), result);
 }
 
 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerRequestTimeout) {
-  constexpr zx::duration kTestRequestTimeout = zx::sec(20);
+  constexpr pw::chrono::SystemClock::duration kTestRequestTimeout = std::chrono::seconds(20);
   constexpr pw::chrono::SystemClock::duration kPwTestRequestTimeout = std::chrono::seconds(20);
 
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
 
   // Add a fake peer so that scan succeeds but connect stalls.
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_force_pending_connect(true);
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -345,8 +343,8 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopFor(kTestRequestTimeout);
-  RunLoopUntilIdle();
+  RunFor(kTestRequestTimeout);
+  RunUntilIdle();
 
   ASSERT_TRUE(result.is_error());
   EXPECT_EQ(HostError::kTimedOut, result.error_value());
@@ -360,7 +358,8 @@
   // timeout.
   // TODO(fxbug.dev/1418): Consider configuring the cache timeout explicitly rather than
   // relying on the kCacheTimeout constant.
-  constexpr zx::duration kTestRequestTimeout = kCacheTimeout + zx::sec(1);
+  constexpr pw::chrono::SystemClock::duration kTestRequestTimeout =
+      kCacheTimeout + std::chrono::seconds(1);
   constexpr pw::chrono::SystemClock::duration kPwTestRequestTimeout =
       kPwCacheTimeout + std::chrono::seconds(1);
   conn_mgr()->set_request_timeout_for_testing(kPwTestRequestTimeout);
@@ -377,7 +376,7 @@
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
   EXPECT_FALSE(peer->temporary());
 
-  RunLoopFor(kTestRequestTimeout);
+  RunFor(kTestRequestTimeout);
   ASSERT_TRUE(result.is_error());
   EXPECT_EQ(HostError::kTimedOut, result.error_value());
   EXPECT_EQ(peer, peer_cache()->FindByAddress(kAddress1));
@@ -388,19 +387,20 @@
 TEST_F(LowEnergyConnectionManagerTest, PeerDoesNotExpireDuringDelayedConnect) {
   // Make the connection resolve after a delay that is longer than the cache
   // timeout.
-  constexpr zx::duration kConnectionDelay = kCacheTimeout + zx::sec(1);
+  constexpr pw::chrono::SystemClock::duration kConnectionDelay =
+      kCacheTimeout + std::chrono::seconds(1);
   constexpr pw::chrono::SystemClock::duration kPwConnectionDelay =
       kPwCacheTimeout + std::chrono::seconds(1);
   FakeController::Settings settings;
   settings.ApplyLegacyLEConfig();
-  settings.le_connection_delay = std::chrono::seconds(kConnectionDelay.to_secs());
+  settings.le_connection_delay = kConnectionDelay;
   test_device()->set_settings(settings);
 
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   auto id = peer->identifier();
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Make sure the connection request doesn't time out while waiting for a
@@ -418,7 +418,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopFor(kConnectionDelay);
+  RunFor(kConnectionDelay);
   ASSERT_TRUE(conn_handle);
 
   // The peer should not have expired during this time.
@@ -434,7 +434,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Use a StaticPacket so that the packet is copied.
@@ -457,7 +457,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
@@ -485,7 +485,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, DeleteRefInClosedCallback) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   bool deleted = false;
   auto obj = std::make_shared<TestObject>(&deleted);
@@ -506,14 +506,14 @@
   };
 
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   ASSERT_TRUE(conn_handle->active());
 
   // This will trigger the closed callback.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, closed_count);
   EXPECT_TRUE(connected_peers().empty());
@@ -525,7 +525,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, ReleaseRef) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -538,7 +538,7 @@
   EXPECT_TRUE(connected_peers().empty());
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   ASSERT_TRUE(peer->le());
@@ -547,7 +547,7 @@
   ASSERT_TRUE(conn_handle);
   conn_handle = nullptr;
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(connected_peers().empty());
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
@@ -557,7 +557,7 @@
   constexpr size_t kRequestCount = 2;
 
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_connect_response(
       pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
   test_device()->AddPeer(std::move(fake_peer));
@@ -570,7 +570,7 @@
     conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(kRequestCount, results.size());
   for (size_t i = 0; i < results.size(); ++i) {
@@ -583,7 +583,7 @@
   constexpr size_t kRequestCount = 50;
 
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
@@ -596,7 +596,7 @@
     conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
@@ -621,7 +621,7 @@
   // Drop the last reference.
   conn_handles[kRequestCount - 1] = nullptr;
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(connected_peers().empty());
 }
@@ -630,7 +630,7 @@
   constexpr size_t kRefCount = 50;
 
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
@@ -641,7 +641,7 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
@@ -650,7 +650,7 @@
   // Add new references.
   for (size_t i = 1; i < kRefCount; ++i) {
     conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   EXPECT_EQ(1u, connected_peers().size());
@@ -660,7 +660,7 @@
   // Disconnect.
   conn_handles.clear();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(connected_peers().empty());
 }
@@ -669,8 +669,8 @@
   auto* peer0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   auto* peer1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
 
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
 
   std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
   auto callback = [&conn_handles](auto result) {
@@ -681,7 +681,7 @@
   conn_mgr()->Connect(peer0->identifier(), callback, kConnectionOptions);
   conn_mgr()->Connect(peer1->identifier(), callback, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
@@ -696,14 +696,14 @@
   // |peer1| should disconnect first.
   conn_handles[1] = nullptr;
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
 
   conn_handles.clear();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(connected_peers().empty());
 }
 
@@ -711,11 +711,11 @@
   auto* peer0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   auto* peer1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
 
-  auto fake_peer0 = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer0->set_connect_response(
       pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
   test_device()->AddPeer(std::move(fake_peer0));
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
 
   std::vector<ConnectionResult> conn_results;
   auto callback = [&conn_results](auto result) { conn_results.emplace_back(std::move(result)); };
@@ -723,7 +723,7 @@
   conn_mgr()->Connect(peer0->identifier(), callback, kConnectionOptions);
   conn_mgr()->Connect(peer1->identifier(), callback, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress1));
@@ -736,7 +736,7 @@
   // Both connections should disconnect.
   conn_results.clear();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(connected_peers().empty());
 }
 
@@ -745,10 +745,10 @@
   auto* peer1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
 
   // Connecting to this peer will succeed.
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // Connecting to this peer will remain pending.
-  auto pending_peer = std::make_unique<FakePeer>(kAddress1, pw_dispatcher());
+  auto pending_peer = std::make_unique<FakePeer>(kAddress1, dispatcher());
   pending_peer->set_force_pending_connect(true);
   test_device()->AddPeer(std::move(pending_peer));
 
@@ -762,7 +762,7 @@
   };
 
   conn_mgr()->Connect(peer0->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   bool conn_closed = false;
@@ -779,12 +779,12 @@
   // connection manager before a connection event gets received which should
   // cancel the connection.
   conn_mgr()->Connect(peer1->identifier(), error_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(error_cb_called);
 
   DeleteConnMgr();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(error_cb_called);
   EXPECT_TRUE(conn_closed);
@@ -795,7 +795,7 @@
 TEST_F(LowEnergyConnectionManagerTest, DisconnectPendingConnectionWhileAwaitingScanStart) {
   auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
 
   int conn_cb_0_count = 0;
   auto conn_cb_0 = [&](auto result) {
@@ -819,7 +819,7 @@
   // Do NOT wait for scanning to start asynchronously before calling Disconnect synchronously.
   // After peer_0's connection request is cancelled, peer_1's connection request should succeed.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(conn_cb_0_count, 1);
   ASSERT_TRUE(conn_handle);
   EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
@@ -831,7 +831,7 @@
   // Don't add FakePeer for peer_0 in order to stall during scanning.
   auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
 
   int conn_cb_0_count = 0;
   auto conn_cb_0 = [&](auto result) {
@@ -851,13 +851,13 @@
   conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
 
   // Wait for scanning to start & OnScanStart callback to be called.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_0->le()->connection_state());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_1->le()->connection_state());
 
   // After peer_0's connection request is cancelled, peer_1's connection request should succeed.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(conn_cb_0_count, 1);
   ASSERT_TRUE(conn_handle);
   EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
@@ -867,12 +867,12 @@
 
 TEST_F(LowEnergyConnectionManagerTest, LocalDisconnectWhileConnectorPending) {
   auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer_0->set_force_pending_connect(true);
   test_device()->AddPeer(std::move(fake_peer_0));
 
   auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
 
   int conn_cb_0_count = 0;
   auto conn_cb_0 = [&](auto result) {
@@ -893,11 +893,11 @@
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_1->le()->connection_state());
 
   // Wait for peer_0 scanning to complete and kLECreateConnection command to be sent.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // After peer_0's connection request is cancelled, peer_1's connection request should succeed.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(conn_cb_0_count, 1);
   ASSERT_TRUE(conn_handle);
   EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
@@ -908,12 +908,12 @@
 TEST_F(LowEnergyConnectionManagerTest,
        DisconnectQueuedPendingConnectionAndThenPendingConnectionWithPendingConnector) {
   auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer_0->set_force_pending_connect(true);
   test_device()->AddPeer(std::move(fake_peer_0));
 
   auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
 
   int conn_cb_0_count = 0;
   auto conn_cb_0 = [&](auto result) {
@@ -937,14 +937,14 @@
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_1->le()->connection_state());
 
   EXPECT_TRUE(conn_mgr()->Disconnect(peer_1->identifier()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(conn_cb_0_count, 0);
   EXPECT_EQ(conn_cb_1_count, 1);
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer_0->le()->connection_state());
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_1->le()->connection_state());
 
   EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(conn_cb_0_count, 1);
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_0->le()->connection_state());
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer_1->le()->connection_state());
@@ -957,7 +957,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, DisconnectUnconnectedPeer) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // This returns true so long the peer is not connected.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
@@ -965,7 +965,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, Disconnect) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   int closed_count = 0;
   auto closed_cb = [&closed_count] { closed_count++; };
@@ -982,7 +982,7 @@
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(2u, conn_handles.size());
 
@@ -991,19 +991,19 @@
   bool peer_removed = peer_cache()->RemoveDisconnectedPeer(peer->identifier());
   EXPECT_TRUE(peer_removed);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2, closed_count);
   EXPECT_TRUE(connected_peers().empty());
   EXPECT_TRUE(canceled_peers().empty());
 
   // The central pause timeout handler should not run.
-  RunLoopFor(kLEConnectionPauseCentral);
+  RunFor(kLEConnectionPauseCentral);
 }
 
 TEST_F(LowEnergyConnectionManagerTest, IntentionalDisconnectDisablesAutoConnectBehavior) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
   auto success_cb = [&conn_handles](auto result) {
@@ -1018,25 +1018,25 @@
 
   // Issue connection ref.
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Bonded peer should have auto-connection enabled.
   EXPECT_TRUE(peer->le()->should_auto_connect());
 
   // Explicit disconnect should disable the auto-connection property.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(peer->le()->should_auto_connect());
 
   // Intentional re-connection should re-enable the auto-connection property.
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(peer->le()->should_auto_connect());
 }
 
 TEST_F(LowEnergyConnectionManagerTest, IncidentalDisconnectDoesNotAffectAutoConnectBehavior) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
   auto success_cb = [&conn_handles](auto result) {
@@ -1051,7 +1051,7 @@
 
   // Issue connection ref.
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Bonded peer should have auto-connection enabled.
   EXPECT_TRUE(peer->le()->should_auto_connect());
@@ -1059,13 +1059,13 @@
   // Incidental disconnect should NOT disable the auto-connection property.
   ASSERT_TRUE(conn_handles.size());
   conn_handles[0] = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(peer->le()->should_auto_connect());
 }
 
 TEST_F(LowEnergyConnectionManagerTest, DisconnectThrice) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   int closed_count = 0;
   auto closed_cb = [&closed_count] { closed_count++; };
@@ -1080,14 +1080,14 @@
 
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
 
   // Try to disconnect again while the first disconnection is in progress.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The single ref should get only one "closed" call.
   EXPECT_EQ(1, closed_count);
@@ -1102,7 +1102,7 @@
 TEST_F(LowEnergyConnectionManagerTest, DisconnectEvent) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
 
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   int closed_count = 0;
   auto closed_cb = [&closed_count] { closed_count++; };
@@ -1119,21 +1119,21 @@
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(2u, conn_handles.size());
 
   // This makes FakeController send us HCI Disconnection Complete events.
   test_device()->Disconnect(kAddress0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2, closed_count);
 }
 
 TEST_F(LowEnergyConnectionManagerTest, DisconnectAfterRefsReleased) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
   auto success_cb = [&conn_handle](auto result) {
@@ -1143,7 +1143,7 @@
 
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   conn_handle.reset();
@@ -1151,7 +1151,7 @@
   // Try to disconnect while the zero-refs connection is being disconnected.
   EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(connected_peers().empty());
   EXPECT_TRUE(canceled_peers().empty());
@@ -1159,7 +1159,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, DisconnectAfterSecondConnectionRequestInvalidatesRefs) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle_0;
   auto success_cb = [&conn_handle_0](auto result) {
@@ -1170,7 +1170,7 @@
   };
 
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle_0);
   EXPECT_TRUE(conn_handle_0->active());
 
@@ -1190,7 +1190,7 @@
   EXPECT_FALSE(conn_handle_1->active());
   EXPECT_FALSE(conn_handle_0->active());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // This tests that a connection reference callback succeeds if a HCI
@@ -1198,7 +1198,7 @@
 // immediately after the callback gets run.
 TEST_F(LowEnergyConnectionManagerTest, DisconnectCompleteEventAfterConnect) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
   auto success_cb = [&conn_handle](auto result) {
@@ -1208,7 +1208,7 @@
   };
 
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
 
   // Request a new reference. Disconnect the link before the reference is
@@ -1233,7 +1233,7 @@
 
   test_device()->SendDisconnectionCompleteEvent(conn_handle->handle());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, ref_cb_count);
   EXPECT_EQ(1u, disconn_cb_count);
@@ -1241,7 +1241,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, RemovePeerFromPeerCacheDuringDisconnection) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
   auto success_cb = [&conn_handle](auto result) {
@@ -1251,7 +1251,7 @@
   };
 
   conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
 
   // This should invalidate the ref that was bound to |ref_cb|.
@@ -1262,7 +1262,7 @@
 
   EXPECT_TRUE(peer_cache()->RemoveDisconnectedPeer(id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(peer_cache()->FindById(id));
   EXPECT_FALSE(peer_cache()->FindByAddress(kAddress0));
@@ -1270,12 +1270,12 @@
 
 // Listener receives remote initiated connection ref.
 TEST_F(LowEnergyConnectionManagerTest, RegisterRemoteInitiatedLink) {
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // First create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -1290,7 +1290,7 @@
   auto* peer = peer_cache()->FindByAddress(kAddress0);
   EXPECT_EQ(peer->le()->connection_state(), Peer::ConnectionState::kInitializing);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
@@ -1303,20 +1303,20 @@
 
   conn_handle = nullptr;
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(connected_peers().empty());
 }
 
 TEST_F(LowEnergyConnectionManagerTest,
        RegisterRemoteInitiatedLinkDuringLocalInitiatedLinkConnecting) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_force_pending_connect(true);
   test_device()->AddPeer(std::move(fake_peer));
 
   // Create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
 
@@ -1331,12 +1331,12 @@
                                             ASSERT_EQ(fit::ok(), result);
                                             conn_handle = std::move(result).value();
                                           });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
 
   // Local connector result handler should not crash when it finds that connection to peer already
   // exists.
-  RunLoopFor(kLECreateConnectionTimeout);
+  RunFor(kLECreateConnectionTimeout);
   // An error should be returned if the connection complete was incorrectly not matched to the
   // pending connection request (see fxbug.dev/68969).
   // In the future it may make sense to return success because a link to the peer already exists.
@@ -1347,13 +1347,13 @@
 TEST_F(LowEnergyConnectionManagerTest,
        RegisterRemoteInitiatedLinkDuringLocalInitiatedConnectionScanning) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_advertising_enabled(false);
   test_device()->AddPeer(std::move(fake_peer));
 
   // Create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
 
@@ -1368,12 +1368,12 @@
                                             ASSERT_EQ(fit::ok(), result);
                                             conn_handle = std::move(result).value();
                                           });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
 
   // Local connector result handler should not crash when it finds that connection to peer already
   // exists.
-  RunLoopFor(kLEGeneralCepScanTimeout);
+  RunFor(kLEGeneralCepScanTimeout);
   ASSERT_TRUE(result.is_error());
   EXPECT_TRUE(peer->le()->connected());
 }
@@ -1386,12 +1386,12 @@
   ASSERT_EQ(peer, peer_cache()->FindByAddress(kAddress0));
   ASSERT_EQ(TechnologyType::kClassic, peer->technology());
 
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // First create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -1402,7 +1402,7 @@
                                             ASSERT_EQ(fit::ok(), result);
                                             conn_handle = std::move(result).value();
                                           });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
 
   EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
@@ -1423,7 +1423,7 @@
   ASSERT_EQ(DeviceAddress::Type::kBREDR, peer->address().type());
 
   // Only the LE transport connects in this test, so only add an LE FakePeer to FakeController.
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
   auto callback = [&conn_handle](auto result) {
@@ -1435,7 +1435,7 @@
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
@@ -1447,7 +1447,7 @@
   EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
 
   conn_handle = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, connected_peers().size());
 }
 
@@ -1456,7 +1456,7 @@
 TEST_F(LowEnergyConnectionManagerTest, CentralAppliesL2capConnectionParameterUpdateRequestParams) {
   // Set up a fake peer and a connection over which to process the L2CAP
   // request.
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer);
 
@@ -1467,7 +1467,7 @@
   };
   conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
 
   hci_spec::LEPreferredConnectionParameters preferred(
@@ -1487,12 +1487,12 @@
   hci_spec::LEConnectionParameters wrong_handle_conn_params(0, 1, 2);
   test_device()->SendLEConnectionUpdateCompleteSubevent(conn_handle->handle() + 1,
                                                         wrong_handle_conn_params);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   test_device()->SendLEConnectionUpdateCompleteSubevent(conn_handle->handle() + 1,
                                                         wrong_handle_conn_params);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(actual.has_value());
   ASSERT_TRUE(peer->le());
@@ -1503,7 +1503,7 @@
 TEST_F(LowEnergyConnectionManagerTest, L2CAPSignalLinkError) {
   // Set up a fake peer and a connection over which to process the L2CAP
   // request.
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer);
 
@@ -1518,7 +1518,7 @@
   };
   conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
   ASSERT_TRUE(smp_chan.is_alive());
   ASSERT_EQ(1u, connected_peers().size());
@@ -1526,14 +1526,14 @@
   // Signaling a link error through the channel should disconnect the link.
   smp_chan->SignalLinkError();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(connected_peers().empty());
 }
 
 TEST_F(LowEnergyConnectionManagerTest, AttBearerSignalsLinkError) {
   // Set up a fake peer and a connection over which to process the L2CAP
   // request.
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer);
 
@@ -1552,7 +1552,7 @@
   };
   conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
   ASSERT_TRUE(att_chan.is_alive());
   ASSERT_EQ(1u, connected_peers().size());
@@ -1562,13 +1562,13 @@
   too_large_att_sdu.Fill(0x00);
   att_chan->Receive(too_large_att_sdu);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_FALSE(att_chan.is_alive());
   EXPECT_TRUE(connected_peers().empty());
 }
 
 TEST_F(LowEnergyConnectionManagerTest, OutboundConnectATTChannelActivateFails) {
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer);
 
@@ -1588,7 +1588,7 @@
   };
   conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(att_chan.has_value());
   // The link should have been closed due to the error, invalidating the channel.
   EXPECT_FALSE(att_chan.value().is_alive());
@@ -1598,7 +1598,7 @@
 }
 
 TEST_F(LowEnergyConnectionManagerTest, InboundConnectionATTChannelActivateFails) {
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer);
 
@@ -1617,13 +1617,13 @@
     result = std::move(cb_result);
   };
   test_device()->ConnectLowEnergy(kAddress0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
   conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable,
                                           std::move(conn_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(att_chan.has_value());
   // The link should have been closed due to the error, invalidating the channel.
   EXPECT_FALSE(att_chan.value().is_alive());
@@ -1633,7 +1633,7 @@
 }
 
 TEST_F(LowEnergyConnectionManagerTest, LinkErrorDuringInterrogation) {
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer);
 
@@ -1656,13 +1656,13 @@
   };
   conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(chan.is_alive());
   fake_l2cap()->TriggerLinkError(chan->link_handle());
 
   send_read_remote_features_rsp();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(result.has_value());
   ASSERT_TRUE(result->is_error());
   EXPECT_EQ(HostError::kFailed, result->error_value());
@@ -1688,7 +1688,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -1702,7 +1702,7 @@
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
   ASSERT_TRUE(peer->le());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   TestSm::WeakPtr mock_sm = TestSmByHandle(conn_handle->handle());
   ASSERT_TRUE(mock_sm.is_alive());
 
@@ -1711,14 +1711,14 @@
   EXPECT_FALSE(mock_sm->last_requested_upgrade().has_value());
   conn_mgr()->Pair(peer->identifier(), sm::SecurityLevel::kEncrypted, sm::BondableMode::Bondable,
                    [](sm::Result<> cb_status) {});
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(BondableMode::Bondable, mock_sm->bondable_mode());
   EXPECT_EQ(sm::SecurityLevel::kEncrypted, mock_sm->last_requested_upgrade());
 
   conn_mgr()->Pair(peer->identifier(), sm::SecurityLevel::kAuthenticated,
                    sm::BondableMode::NonBondable, [](sm::Result<> cb_status) {});
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(BondableMode::NonBondable, mock_sm->bondable_mode());
   EXPECT_EQ(sm::SecurityLevel::kAuthenticated, mock_sm->last_requested_upgrade());
@@ -1734,7 +1734,7 @@
   };
   fake_gatt()->SetInitializeClientCallback(expect_uuids);
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -1748,7 +1748,7 @@
   LowEnergyConnectionOptions connection_options{.service_uuid = std::nullopt};
   conn_mgr()->Connect(peer->identifier(), callback, connection_options);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(cb_called);
 }
@@ -1766,7 +1766,7 @@
   };
   fake_gatt()->SetInitializeClientCallback(expect_uuid);
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -1780,7 +1780,7 @@
   LowEnergyConnectionOptions connection_options{.service_uuid = std::optional(kConnectUuid)};
   conn_mgr()->Connect(peer->identifier(), callback, connection_options);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(cb_called);
 }
@@ -1791,7 +1791,7 @@
 
 TEST_P(ReadDeviceNameParameterizedFixture, ReadDeviceNameParameterized) {
   Peer* peer = peer_cache()->NewPeer(kAddress0, true);
-  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -1823,7 +1823,7 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   ASSERT_TRUE(peer->name());
   EXPECT_EQ(peer->name_source(), Peer::NameSource::kGenericAccessService);
@@ -1838,7 +1838,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, ReadDeviceNameLong) {
   Peer* peer = peer_cache()->NewPeer(kAddress0, true);
-  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -1872,7 +1872,7 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   ASSERT_TRUE(peer->name());
   EXPECT_EQ(peer->name_source(), Peer::NameSource::kGenericAccessService);
@@ -1882,7 +1882,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, ReadAppearance) {
   Peer* peer = peer_cache()->NewPeer(kAddress0, true);
-  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -1913,7 +1913,7 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   ASSERT_TRUE(peer->appearance());
   uint16_t device_appearance = peer->appearance().value();
@@ -1922,7 +1922,7 @@
 
 TEST_F(LowEnergyConnectionManagerTest, ReadAppearanceInvalidSize) {
   Peer* peer = peer_cache()->NewPeer(kAddress0, true);
-  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  std::unique_ptr<FakePeer> fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -1953,7 +1953,7 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   EXPECT_FALSE(peer->appearance());
 }
@@ -1961,7 +1961,7 @@
 TEST_F(LowEnergyConnectionManagerTest,
        ReadPeripheralPreferredConnectionParametersCharacteristicAndUpdateConnectionParameters) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -1998,7 +1998,7 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   ASSERT_TRUE(peer->le()->preferred_connection_parameters());
   auto params = peer->le()->preferred_connection_parameters().value();
@@ -2011,7 +2011,7 @@
   test_device()->set_le_connection_parameters_callback(
       [&](auto address, auto parameters) { conn_params = parameters; });
 
-  RunLoopFor(kLEConnectionPauseCentral);
+  RunFor(kLEConnectionPauseCentral);
   ASSERT_TRUE(conn_params.has_value());
   EXPECT_EQ(conn_params->interval(), 1u);  // FakeController will use min interval
   EXPECT_EQ(conn_params->latency(), 3u);
@@ -2021,7 +2021,7 @@
 TEST_F(LowEnergyConnectionManagerTest,
        ReadPeripheralPreferredConnectionParametersCharacteristicInvalidValueSize) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -2052,14 +2052,14 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   EXPECT_FALSE(peer->le()->preferred_connection_parameters());
 }
 
 TEST_F(LowEnergyConnectionManagerTest, GapServiceCharacteristicDiscoveryError) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -2083,14 +2083,14 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   EXPECT_FALSE(peer->le()->preferred_connection_parameters());
 }
 
 TEST_F(LowEnergyConnectionManagerTest, GapServiceListServicesError) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   fake_gatt()->set_list_services_status(ToResult(HostError::kFailed));
@@ -2103,14 +2103,14 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   EXPECT_FALSE(peer->le()->preferred_connection_parameters());
 }
 
 TEST_F(LowEnergyConnectionManagerTest, PeerGapServiceMissingConnectionParameterCharacteristic) {
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Set up GAP service
@@ -2126,19 +2126,19 @@
 
   conn_mgr()->Connect(peer->identifier(), callback, LowEnergyConnectionOptions());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_ref);
   EXPECT_FALSE(peer->le()->preferred_connection_parameters());
 }
 
 // Listener receives remote initiated connection ref.
 TEST_F(LowEnergyConnectionManagerTest, PassBondableThroughRemoteInitiatedLink) {
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // First create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -2149,7 +2149,7 @@
                                             ASSERT_EQ(fit::ok(), result);
                                             conn_handle = std::move(result).value();
                                           });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
@@ -2157,12 +2157,12 @@
 }
 
 TEST_F(LowEnergyConnectionManagerTest, PassNonBondableThroughRemoteInitiatedLink) {
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // First create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -2173,7 +2173,7 @@
                                             ASSERT_EQ(fit::ok(), result);
                                             conn_handle = std::move(result).value();
                                           });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
@@ -2185,7 +2185,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -2199,7 +2199,7 @@
   EXPECT_TRUE(connected_peers().empty());
   conn_mgr()->Connect(peer->identifier(), callback, {.bondable_mode = BondableMode::Bondable});
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::Bondable);
@@ -2210,7 +2210,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -2224,7 +2224,7 @@
   EXPECT_TRUE(connected_peers().empty());
   conn_mgr()->Connect(peer->identifier(), callback, {.bondable_mode = BondableMode::NonBondable});
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::NonBondable);
@@ -2237,7 +2237,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn;
@@ -2248,7 +2248,7 @@
         conn = std::move(result).value();
       },
       kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn);
 
   hci_spec::ConnectionHandle handle = conn->handle();
@@ -2264,7 +2264,7 @@
       handle, pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE,
       pw::bluetooth::emboss::EncryptionStatus::OFF);
   test_device()->SendDisconnectionCompleteEvent(handle);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(ref_cleaned_up);
   EXPECT_TRUE(disconnected);
@@ -2278,7 +2278,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer->le());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_le_features(kLEFeatures);
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -2293,7 +2293,7 @@
 
   EXPECT_FALSE(peer->version().has_value());
   EXPECT_FALSE(peer->le()->features().has_value());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn);
   EXPECT_TRUE(peer->version().has_value());
   EXPECT_TRUE(peer->le()->features().has_value());
@@ -2306,7 +2306,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer->le());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::optional<HostError> error;
@@ -2323,7 +2323,7 @@
   test_device()->set_le_read_remote_features_callback(
       [this]() { test_device()->RemovePeer(kAddress0); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(error.has_value());
   EXPECT_FALSE(peer->connected());
   EXPECT_FALSE(peer->le()->connected());
@@ -2331,12 +2331,12 @@
 }
 
 TEST_F(LowEnergyConnectionManagerTest, RemoteInitiatedLinkInterrogationFailure) {
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // First create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -2352,7 +2352,7 @@
   test_device()->set_le_read_remote_features_callback(
       [this]() { test_device()->RemovePeer(kAddress0); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(error.has_value());
 
   // A Peer should now exist in the cache.
@@ -2370,14 +2370,14 @@
 
   // Connection Parameter Update procedure NOT supported.
   constexpr hci_spec::LESupportedFeatures kLEFeatures{0};
-  auto peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   peer->set_le_features(kLEFeatures);
   test_device()->AddPeer(std::move(peer));
 
   // First create a fake incoming connection as peripheral.
   test_device()->ConnectLowEnergy(kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -2400,13 +2400,13 @@
   test_device()->set_le_connection_parameters_callback(
       [&](auto address, auto parameters) { hci_update_conn_param_count++; });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
   EXPECT_EQ(0u, l2cap_conn_param_update_count);
   EXPECT_EQ(0u, hci_update_conn_param_count);
 
-  RunLoopFor(kLEConnectionPausePeripheral);
+  RunFor(kLEConnectionPausePeripheral);
   EXPECT_EQ(1u, l2cap_conn_param_update_count);
   EXPECT_EQ(0u, hci_update_conn_param_count);
 }
@@ -2419,8 +2419,8 @@
 // Test that this behavior is followed for 2 concurrent connections in order to ensure correct
 // command/event handling.
 TEST_F(LowEnergyConnectionManagerTest, PeripheralsRetryLLConnectionUpdateWithL2capRequest) {
-  auto peer0 = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
-  auto peer1 = std::make_unique<FakePeer>(kAddress1, pw_dispatcher());
+  auto peer0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
+  auto peer1 = std::make_unique<FakePeer>(kAddress1, dispatcher());
 
   // Connection Parameter Update procedure supported by controller.
   constexpr hci_spec::LESupportedFeatures kLEFeatures{
@@ -2439,7 +2439,7 @@
 
   // First create fake incoming connections with local host as peripheral.
   test_device()->ConnectLowEnergy(kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto link0 = MoveLastRemoteInitiated();
   ASSERT_TRUE(link0);
 
@@ -2451,7 +2451,7 @@
                                           });
 
   test_device()->ConnectLowEnergy(kAddress1, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto link1 = MoveLastRemoteInitiated();
   ASSERT_TRUE(link1);
 
@@ -2494,7 +2494,7 @@
     }
   });
 
-  RunLoopFor(kLEConnectionPausePeripheral);
+  RunFor(kLEConnectionPausePeripheral);
   ASSERT_TRUE(conn_handle0);
   EXPECT_TRUE(conn_handle0->active());
   ASSERT_TRUE(conn_handle1);
@@ -2509,7 +2509,7 @@
   test_device()->SendLEConnectionUpdateCompleteSubevent(
       conn_handle1->handle(), hci_spec::LEConnectionParameters(),
       pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, l2cap_conn_param_update_count0);
   EXPECT_EQ(1u, l2cap_conn_param_update_count1);
 }
@@ -2520,7 +2520,7 @@
 // Parameter Update Request after receiving this kUnsupportedRemoteFeature command status.
 TEST_F(LowEnergyConnectionManagerTest,
        PeripheralSendsL2capConnParamReqAfterConnUpdateCommandStatusUnsupportedRemoteFeature) {
-  auto peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
 
   // Connection Parameter Update procedure supported by controller.
   constexpr hci_spec::LESupportedFeatures kLEFeatures{
@@ -2530,7 +2530,7 @@
 
   // First create a fake incoming connection with local host as peripheral.
   test_device()->ConnectLowEnergy(kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -2556,7 +2556,7 @@
   test_device()->SetDefaultCommandStatus(
       hci_spec::kLEConnectionUpdate, pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
 
-  RunLoopFor(kLEConnectionPausePeripheral);
+  RunFor(kLEConnectionPausePeripheral);
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
   EXPECT_EQ(0u, hci_update_conn_param_count);
@@ -2569,7 +2569,7 @@
       conn_handle->handle(), hci_spec::LEConnectionParameters(),
       pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, l2cap_conn_param_update_count);
 }
 
@@ -2577,7 +2577,7 @@
 // status of the LE Connection Update command is not success.
 TEST_F(LowEnergyConnectionManagerTest,
        PeripheralDoesNotSendL2capConnParamReqAfterConnUpdateCommandStatusError) {
-  auto peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
 
   // Connection Parameter Update procedure supported by controller.
   constexpr hci_spec::LESupportedFeatures kLEFeatures{
@@ -2587,7 +2587,7 @@
 
   // First create a fake incoming connection with local host as peripheral.
   test_device()->ConnectLowEnergy(kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -2613,7 +2613,7 @@
   test_device()->SetDefaultCommandStatus(hci_spec::kLEConnectionUpdate,
                                          pw::bluetooth::emboss::StatusCode::UNSPECIFIED_ERROR);
 
-  RunLoopFor(kLEConnectionPausePeripheral);
+  RunFor(kLEConnectionPausePeripheral);
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
   EXPECT_EQ(0u, hci_update_conn_param_count);
@@ -2626,7 +2626,7 @@
       conn_handle->handle(), hci_spec::LEConnectionParameters(),
       pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, l2cap_conn_param_update_count);
 }
 
@@ -2634,14 +2634,14 @@
   constexpr hci_spec::LESupportedFeatures kLEFeatures{
       static_cast<uint64_t>(hci_spec::LESupportedFeature::kConnectionParametersRequestProcedure)};
 
-  auto peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   peer->set_le_features(kLEFeatures);
   test_device()->AddPeer(std::move(peer));
 
   // First create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -2671,13 +2671,13 @@
         hci_update_conn_param_count++;
       });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
   EXPECT_EQ(0u, l2cap_conn_param_update_count);
   EXPECT_EQ(0u, hci_update_conn_param_count);
 
-  RunLoopFor(kLEConnectionPausePeripheral);
+  RunFor(kLEConnectionPausePeripheral);
   EXPECT_EQ(0u, l2cap_conn_param_update_count);
   EXPECT_EQ(1u, hci_update_conn_param_count);
 }
@@ -2688,7 +2688,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer->le());
 
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   size_t hci_update_conn_param_count = 0;
   test_device()->set_le_connection_parameters_callback(
@@ -2710,10 +2710,10 @@
       },
       kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, hci_update_conn_param_count);
 
-  RunLoopFor(kLEConnectionPauseCentral);
+  RunFor(kLEConnectionPauseCentral);
   EXPECT_EQ(1u, hci_update_conn_param_count);
   EXPECT_TRUE(conn);
 }
@@ -2723,7 +2723,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer->le());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Prevent remote features event from being received.
@@ -2733,7 +2733,7 @@
   conn_mgr()->Connect(
       peer->identifier(), [&](auto result) { ASSERT_TRUE(result.is_error()); }, kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Interrogation should not complete.
   EXPECT_FALSE(peer->le()->features().has_value());
 
@@ -2741,7 +2741,7 @@
   // No asserts should fail.
   conn_mgr()->Connect(
       peer->identifier(), [&](auto result) { ASSERT_TRUE(result.is_error()); }, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 LowEnergyConnectionManager::ConnectionResultCallback MakeConnectionResultCallback(
@@ -2760,9 +2760,9 @@
   Peer* encrypted_peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   Peer* unencrypted_peer = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
   Peer* secure_authenticated_peer = peer_cache()->NewPeer(kAddress3, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3, dispatcher()));
 
   std::unique_ptr<LowEnergyConnectionHandle> unencrypted_conn_handle, encrypted_conn_handle,
       secure_authenticated_conn_handle;
@@ -2774,7 +2774,7 @@
   conn_mgr()->Connect(secure_authenticated_peer->identifier(),
                       MakeConnectionResultCallback(secure_authenticated_conn_handle),
                       kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   std::function<void(sm::Result<>)> pair_cb = [](sm::Result<> s) { EXPECT_EQ(fit::ok(), s); };
   EXPECT_EQ(3u, connected_peers().size());
   ASSERT_TRUE(unencrypted_conn_handle);
@@ -2789,7 +2789,7 @@
                    sm::BondableMode::Bondable, pair_cb);
   conn_mgr()->Pair(secure_authenticated_peer->identifier(), sm::SecurityLevel::kSecureAuthenticated,
                    sm::BondableMode::Bondable, pair_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(sm::SecurityLevel::kNoSecurity, unencrypted_conn_handle->security().level());
   EXPECT_EQ(sm::SecurityLevel::kEncrypted, encrypted_conn_handle->security().level());
   EXPECT_EQ(sm::SecurityLevel::kSecureAuthenticated,
@@ -2799,7 +2799,7 @@
   // disconnected (in this case, `encrypted_peer` is encrypted, SC-generated, and with max
   // encryption key size, but not authenticated).
   conn_mgr()->SetSecurityMode(LESecurityMode::SecureConnectionsOnly);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(LESecurityMode::SecureConnectionsOnly, conn_mgr()->security_mode());
   EXPECT_EQ(2u, connected_peers().size());
   EXPECT_TRUE(unencrypted_conn_handle->active());
@@ -2814,31 +2814,31 @@
 
   // This peer will already be connected when we set LE Secure Connections Only mode.
   Peer* existing_peer = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
   std::unique_ptr<LowEnergyConnectionHandle> existing_conn_handle;
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   conn_mgr()->Connect(existing_peer->identifier(),
                       MakeConnectionResultCallback(existing_conn_handle), kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   TestSm::WeakPtr existing_peer_sm = TestSmByHandle(existing_conn_handle->handle());
   ASSERT_TRUE(existing_peer_sm.is_alive());
   EXPECT_EQ(LESecurityMode::Mode1, existing_peer_sm->security_mode());
   EXPECT_EQ(1u, connected_peers().size());
 
   conn_mgr()->SetSecurityMode(LESecurityMode::SecureConnectionsOnly);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(LESecurityMode::SecureConnectionsOnly, existing_peer_sm->security_mode());
 
   // This peer is connected after setting LE Secure Connections Only mode.
   Peer* new_peer = peer_cache()->NewPeer(kAddress3, /*connectable=*/true);
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3, dispatcher()));
   std::unique_ptr<LowEnergyConnectionHandle> new_conn_handle;
 
   conn_mgr()->Connect(new_peer->identifier(), MakeConnectionResultCallback(new_conn_handle),
                       kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   TestSm::WeakPtr new_peer_sm = TestSmByHandle(new_conn_handle->handle());
   ASSERT_TRUE(new_peer_sm.is_alive());
   EXPECT_EQ(2u, connected_peers().size());
@@ -2851,7 +2851,7 @@
   auto* peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer_0->le());
 
-  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
   auto fake_peer_0_ptr = fake_peer_0.get();
   test_device()->AddPeer(std::move(fake_peer_0));
 
@@ -2869,7 +2869,7 @@
       },
       kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Interrogation should not complete.
   EXPECT_FALSE(peer_0->le()->connected());
   EXPECT_FALSE(conn_0);
@@ -2877,7 +2877,7 @@
   auto* peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
   ASSERT_TRUE(peer_1->le());
 
-  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, pw_dispatcher());
+  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, dispatcher());
   auto fake_peer_1_ptr = fake_peer_1.get();
   test_device()->AddPeer(std::move(fake_peer_1));
 
@@ -2891,7 +2891,7 @@
         ASSERT_TRUE(conn_1);
       },
       kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Complete interrogation of peer_0
   ASSERT_FALSE(fake_peer_0_ptr->logical_links().empty());
@@ -2906,7 +2906,7 @@
   view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
   view.le_features().BackingStorage().WriteUInt(0u);
   test_device()->SendCommandChannelPacket(response.data());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_0);
   EXPECT_TRUE(peer_0->le()->connected());
 
@@ -2915,7 +2915,7 @@
   auto handle_1 = *fake_peer_0_ptr->logical_links().begin();
   view.connection_handle().Write(handle_1);
   test_device()->SendCommandChannelPacket(response.data());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_1);
   EXPECT_TRUE(peer_1->le()->connected());
 }
@@ -2924,7 +2924,7 @@
   auto* peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer_0->le());
 
-  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
   auto fake_peer_0_ptr = fake_peer_0.get();
   test_device()->AddPeer(std::move(fake_peer_0));
 
@@ -2941,7 +2941,7 @@
       },
       kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Interrogation should not complete.
   EXPECT_FALSE(peer_0->le()->connected());
   EXPECT_FALSE(conn_0);
@@ -2954,14 +2954,14 @@
   auto* peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
   ASSERT_TRUE(peer_1->le());
 
-  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, pw_dispatcher());
+  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, dispatcher());
   test_device()->AddPeer(std::move(fake_peer_1));
 
   // Connect to different peer, before interrogation has completed.
   conn_mgr()->Connect(
       peer_1->identifier(), [&](auto result) { EXPECT_TRUE(result.is_error()); },
       kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Complete interrogation of peer_0. No asserts should fail.
   ASSERT_FALSE(fake_peer_0_ptr->logical_links().empty());
@@ -2975,7 +2975,7 @@
   view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
   view.le_features().BackingStorage().WriteUInt(0u);
   test_device()->SendCommandChannelPacket(response.data());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_0);
   EXPECT_TRUE(peer_0->le()->connected());
 }
@@ -2984,7 +2984,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   ASSERT_TRUE(peer->le());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn;
@@ -2996,13 +2996,13 @@
       },
       kConnectionOptions);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(peer->le()->connected());
   EXPECT_TRUE(conn);
 
   // Disconnect
   conn = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Second interrogation will complete synchronously because peer has already been interrogated.
   bool conn_cb_called = false;
@@ -3015,7 +3015,7 @@
       },
       kConnectionOptions);
   // Wait for connect complete event.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(conn_cb_called);
 }
 
@@ -3023,7 +3023,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   size_t scan_cb_count = 0;
@@ -3042,7 +3042,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
@@ -3059,7 +3059,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   size_t connect_cb_count = 0;
@@ -3077,7 +3077,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connect_cb_count, 1u);
   EXPECT_FALSE(peer->temporary());
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
@@ -3099,13 +3099,13 @@
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connect_cb_count, 0u);
 
   // Cause discovery to fail when attempting to restart scan after scan period ends.
   test_device()->SetDefaultCommandStatus(hci_spec::kLESetScanEnable,
                                          pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED);
-  RunLoopFor(kLEGeneralDiscoveryScanMin);
+  RunFor(kLEGeneralDiscoveryScanMin);
   EXPECT_EQ(connect_cb_count, 1u);
   EXPECT_FALSE(peer->temporary());
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
@@ -3115,7 +3115,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   auto fake_peer_ptr = fake_peer.get();
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -3134,14 +3134,14 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_FALSE(fake_peer_ptr->logical_links().empty());
   auto handle = *fake_peer_ptr->logical_links().begin();
 
   test_device()->Disconnect(peer->address());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Complete interrogation so that callback gets called.
   auto response =
@@ -3152,7 +3152,7 @@
   view.connection_handle().Write(handle);
   test_device()->SendCommandChannelPacket(response.data());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, connected_peers().size());
   EXPECT_EQ(1, connect_count);
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
@@ -3162,7 +3162,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   auto fake_peer_ptr = fake_peer.get();
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -3181,14 +3181,14 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_FALSE(fake_peer_ptr->logical_links().empty());
   auto handle = *fake_peer_ptr->logical_links().begin();
 
   conn_mgr()->Disconnect(peer->identifier());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Complete interrogation so that callback gets called.
   auto response =
@@ -3199,7 +3199,7 @@
   view.connection_handle().Write(handle);
   test_device()->SendCommandChannelPacket(response.data());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, connected_peers().size());
   EXPECT_EQ(1, connect_count);
   EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
@@ -3209,7 +3209,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   size_t connected_count = 0;
@@ -3240,23 +3240,23 @@
   for (size_t i = 0; i < kConnectDelays.size(); i++) {
     SCOPED_TRACE(i);
     if (i != 0) {
-      RunLoopFor(kConnectDelays[i] - zx::nsec(1));
+      RunFor(kConnectDelays[i] - std::chrono::nanoseconds(1));
       EXPECT_EQ(connected_count, i);
-      RunLoopFor(zx::nsec(1));
+      RunFor(std::chrono::nanoseconds(1));
     } else {
-      RunLoopFor(kConnectDelays[i]);
+      RunFor(kConnectDelays[i]);
     }
     EXPECT_EQ(connected_count, i + 1);
     EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
     test_device()->Disconnect(
         kAddress0, pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
-    RunLoopUntilIdle();
+    RunUntilIdle();
     EXPECT_EQ(connected_count, i + 1);
     // A connect command should be sent in connect_delays[i+1]
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(connected_peers().empty());
   EXPECT_EQ(connect_cb_count, 1);
   EXPECT_FALSE(peer->temporary());
@@ -3267,7 +3267,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -3288,7 +3288,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
   EXPECT_FALSE(conn_handle);
 
@@ -3298,7 +3298,7 @@
   // Disconnect should initiate retry #2 after a pause.
   test_device()->Disconnect(kAddress0,
                             pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
-  RunLoopFor(zx::sec(2));
+  RunFor(std::chrono::seconds(2));
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
   ASSERT_TRUE(conn_handle);
@@ -3312,7 +3312,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   int connect_cb_count = 0;
@@ -3333,7 +3333,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
   EXPECT_EQ(connect_cb_count, 0);
 
@@ -3343,11 +3343,13 @@
   // Peer disconnection during interrogation should also cause retry (after a pause)
   test_device()->Disconnect(kAddress0,
                             pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Disconnect will cancel request.
   conn_mgr()->Disconnect(peer->identifier());
   // Ensure timer is canceled.
-  RunLoopRepeatedlyFor(zx::sec(1));
+  // TODO(saeedali): run repeatedly?
+  // RunLoopRepeatedlyFor(std::chrono::seconds(1));
+  RunFor(std::chrono::seconds(1));
   EXPECT_EQ(connect_cb_count, 1);
   EXPECT_EQ(0u, connected_peers().size());
   EXPECT_FALSE(peer->temporary());
@@ -3361,7 +3363,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   int connect_cb_count = 0;
@@ -3382,7 +3384,7 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
   EXPECT_EQ(connect_cb_count, 0);
 
@@ -3392,7 +3394,7 @@
   // Peer disconnection during interrogation should also cause retry (after a pause).
   test_device()->Disconnect(kAddress0,
                             pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Complete interrogation with an error that will be received after the disconnect event.
   // Event params other than status will be ignored because status is an error.
@@ -3403,12 +3405,12 @@
   view.status().Write(pw::bluetooth::emboss::StatusCode::UNKNOWN_CONNECTION_ID);
   test_device()->SendCommandChannelPacket(response.data());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
   EXPECT_EQ(connect_cb_count, 0);
 
   // Wait for retry.
-  RunLoopFor(kConnectDelays[1]);
+  RunFor(kConnectDelays[1]);
   EXPECT_EQ(connect_cb_count, 1);
   EXPECT_TRUE(conn_handle);
   EXPECT_EQ(1u, connected_peers().size());
@@ -3441,7 +3443,7 @@
     SCOPED_TRACE(hci_spec::StatusCodeToString(statuses_that_disable_autoconnect[i]));
     const DeviceAddress kAddressI(DeviceAddress::Type::kLEPublic, {i});
     auto* peer = peer_cache()->NewPeer(kAddressI, /*connectable=*/true);
-    auto fake_peer = std::make_unique<FakePeer>(kAddressI, pw_dispatcher());
+    auto fake_peer = std::make_unique<FakePeer>(kAddressI, dispatcher());
     test_device()->AddPeer(std::move(fake_peer));
 
     std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -3452,7 +3454,7 @@
     };
 
     conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
-    RunLoopUntilIdle();
+    RunUntilIdle();
     // Peer needs to be bonded to set auto connect
     peer->MutLe().SetBondData(sm::PairingData{});
 
@@ -3466,7 +3468,7 @@
     // unset auto connect behavior.
     test_device()->Disconnect(peer->address());
 
-    RunLoopUntilIdle();
+    RunUntilIdle();
 
     EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
     EXPECT_TRUE(peer->le()->should_auto_connect());
@@ -3480,19 +3482,19 @@
     auto failure_cb = [&result](auto res) { result = std::move(res); };
     // Create an inbound HCI connection and try to register it with the LECM
     test_device()->ConnectLowEnergy(kAddressI);
-    RunLoopUntilIdle();
+    RunUntilIdle();
     auto link = MoveLastRemoteInitiated();
     ASSERT_TRUE(link);
     result = fit::ok(nullptr);
     conn_mgr()->RegisterRemoteInitiatedLink(std::move(link), BondableMode::Bondable, failure_cb);
-    RunLoopUntilIdle();
+    RunUntilIdle();
     // We always wait until the peer disconnects to relay connection failure when dealing with
     // the 0x3e kConnectionFailedToBeEstablished error.
     if (statuses_that_disable_autoconnect[i] ==
         pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED) {
       test_device()->Disconnect(
           kAddressI, pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
-      RunLoopUntilIdle();
+      RunUntilIdle();
     }
     // Remote-initiated connection attempts that fail should not disable the auto-connect flag.
     ASSERT_TRUE(result.is_error());
@@ -3509,7 +3511,7 @@
     // User-initiated connection attempts that fail should not disable the auto-connect flag.
     const LowEnergyConnectionOptions kNotAutoConnectOptions{.auto_connect = false};
     conn_mgr()->Connect(peer->identifier(), failure_cb, kNotAutoConnectOptions);
-    RunLoopUntilIdle();
+    RunUntilIdle();
 
     ASSERT_TRUE(result.is_error());
     EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
@@ -3524,7 +3526,7 @@
     ASSERT_TRUE(peer->le());
     EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-    RunLoopUntilIdle();
+    RunUntilIdle();
 
     ASSERT_TRUE(result.is_error());
     EXPECT_EQ(Peer::ConnectionState::kNotConnected, peer->le()->connection_state());
@@ -3540,7 +3542,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
@@ -3583,7 +3585,7 @@
   EXPECT_THAT(hierarchy.value(), ChildrenMatch(ElementsAre(conn_mgr_during_connecting_matcher)));
 
   // Finish connecting.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto empty_requests_matcher =
       AllOf(NodeMatches(NameMatches("pending_requests")), ChildrenMatch(::testing::IsEmpty()));
@@ -3626,13 +3628,13 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   fake_peer->set_connect_status(pw::bluetooth::emboss::StatusCode::CONNECTION_LIMIT_EXCEEDED);
   test_device()->AddPeer(std::move(fake_peer));
 
   auto callback = [](auto result) { ASSERT_TRUE(result.is_error()); };
   conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto conn_mgr_property_matcher = PropertyList(UnorderedElementsAre(
       UintIs("disconnect_explicit_disconnect_count", 0), UintIs("disconnect_link_error_count", 0),
@@ -3646,14 +3648,14 @@
   EXPECT_THAT(hierarchy.value(),
               ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));
 
-  RunLoopFor(LowEnergyConnectionManager::kInspectRecentConnectionFailuresExpiryDuration -
-             zx::nsec(1));
+  RunFor(LowEnergyConnectionManager::kInspectRecentConnectionFailuresExpiryDuration -
+         std::chrono::nanoseconds(1));
   hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
   EXPECT_THAT(hierarchy.value(),
               ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));
 
   // Failures should revert to 0 after expiry duration.
-  RunLoopFor(zx::nsec(1));
+  RunFor(std::chrono::nanoseconds(1));
   conn_mgr_property_matcher = PropertyList(UnorderedElementsAre(
       UintIs("disconnect_explicit_disconnect_count", 0), UintIs("disconnect_link_error_count", 0),
       UintIs("disconnect_remote_disconnection_count", 0), UintIs("disconnect_zero_ref_count", 0),
@@ -3684,9 +3686,9 @@
   EXPECT_TRUE(peer_cache()->StoreLowEnergyBond(peer->identifier(), data));
   EXPECT_EQ(peer->address(), kIdentityAddress);
 
-  test_device()->AddPeer(std::make_unique<FakePeer>(kRandomAddress, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kRandomAddress, dispatcher()));
   test_device()->ConnectLowEnergy(kRandomAddress);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
@@ -3699,7 +3701,7 @@
                                           });
   EXPECT_EQ(peer->le()->connection_state(), Peer::ConnectionState::kInitializing);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
@@ -3712,7 +3714,7 @@
   auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   EXPECT_TRUE(peer->temporary());
 
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer));
 
   // Cause interrogation to stall so that we can expire the central pause timeout.
@@ -3737,19 +3739,19 @@
   ASSERT_TRUE(peer->le());
   EXPECT_EQ(Peer::ConnectionState::kInitializing, peer->le()->connection_state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
   EXPECT_FALSE(conn_handle);
   EXPECT_EQ(hci_update_conn_param_count, 0u);
 
-  RunLoopFor(kLEConnectionPausePeripheral);
+  RunFor(kLEConnectionPausePeripheral);
   EXPECT_FALSE(conn_handle);
   EXPECT_EQ(hci_update_conn_param_count, 0u);
 
   // Allow interrogation to complete.
   send_read_remote_features_rsp();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(hci_update_conn_param_count, 1u);
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
@@ -3760,7 +3762,7 @@
        RegisterRemoteInitiatedLinkWithInterrogationLongerThanPeripheralPauseTimeout) {
   // A FakePeer does not support the HCI connection parameter update procedure by default, so the
   // L2CAP procedure will be used.
-  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, pw_dispatcher()));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
 
   // Cause interrogation to stall so that we can expire the peripheral pause timeout.
   fit::closure send_read_remote_features_rsp;
@@ -3776,7 +3778,7 @@
 
   // First create a fake incoming connection.
   test_device()->ConnectLowEnergy(kAddress0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto link = MoveLastRemoteInitiated();
   ASSERT_TRUE(link);
 
@@ -3792,19 +3794,19 @@
   ASSERT_TRUE(peer);
   EXPECT_EQ(peer->le()->connection_state(), Peer::ConnectionState::kInitializing);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, connected_peers().size());
   EXPECT_EQ(1u, connected_peers().count(kAddress0));
   EXPECT_FALSE(conn_handle);
   EXPECT_EQ(l2cap_conn_param_update_count, 0u);
 
-  RunLoopFor(kLEConnectionPausePeripheral);
+  RunFor(kLEConnectionPausePeripheral);
   EXPECT_FALSE(conn_handle);
   EXPECT_EQ(l2cap_conn_param_update_count, 0u);
 
   // Allow interrogation to complete.
   send_read_remote_features_rsp();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(l2cap_conn_param_update_count, 1u);
   ASSERT_TRUE(conn_handle);
   EXPECT_TRUE(conn_handle->active());
@@ -3826,11 +3828,11 @@
 
     peer0_ = peer_cache()->NewPeer(kPeerAddr0, /*connectable=*/true);
     EXPECT_TRUE(peer0_->temporary());
-    test_device()->AddPeer(std::make_unique<FakePeer>(kPeerAddr0, pw_dispatcher()));
+    test_device()->AddPeer(std::make_unique<FakePeer>(kPeerAddr0, dispatcher()));
 
     peer1_ = peer_cache()->NewPeer(kPeerAddr1, /*connectable=*/true);
     EXPECT_TRUE(peer1_->temporary());
-    test_device()->AddPeer(std::make_unique<FakePeer>(kPeerAddr1, pw_dispatcher()));
+    test_device()->AddPeer(std::make_unique<FakePeer>(kPeerAddr1, dispatcher()));
 
     // Connect |peer0|
     conn_handle0_.reset();
@@ -3840,7 +3842,7 @@
       EXPECT_TRUE(conn_handle0_->active());
     };
     conn_mgr()->Connect(peer0_->identifier(), callback0, kConnectionOptions);
-    RunLoopUntilIdle();
+    RunUntilIdle();
 
     // Connect |peer1|
     conn_handle1_.reset();
@@ -3850,10 +3852,10 @@
       EXPECT_TRUE(conn_handle1_->active());
     };
     conn_mgr()->Connect(peer1_->identifier(), callback1, kConnectionOptions);
-    RunLoopUntilIdle();
+    RunUntilIdle();
 
     packet_count_ = 0;
-    test_device()->SetDataCallback([&](const auto&) { packet_count_++; }, pw_dispatcher());
+    test_device()->SetDataCallback([&](const auto&) { packet_count_++; }, dispatcher());
     test_device()->set_auto_completed_packets_event_enabled(false);
     test_device()->set_auto_disconnection_complete_event_enabled(false);
   }
@@ -3899,7 +3901,7 @@
         hci_spec::ACLBroadcastFlag::kPointToPoint,
         /*payload_size=*/1);
     connection_0.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   // Queue packet for |peer1|
@@ -3908,7 +3910,7 @@
       hci_spec::ACLBroadcastFlag::kPointToPoint,
       /*payload_size=*/1);
   connection_1.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Packet for |peer1| should not have been sent because controller buffer is full
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
@@ -3919,7 +3921,7 @@
   // Send HCI Disconnect to controller
   EXPECT_TRUE(conn_mgr()->Disconnect(peer0()->identifier()));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Packet for |peer1| should not have been sent before Disconnection Complete event
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
@@ -3929,7 +3931,7 @@
 
   // FakeController send us the HCI Disconnection Complete event
   test_device()->SendDisconnectionCompleteEvent(handle0_);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // |peer0|'s link should have been unregistered and packet for |peer1| should have been sent
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
@@ -3952,7 +3954,7 @@
         hci_spec::ACLBroadcastFlag::kPointToPoint,
         /*payload_size=*/1);
     connection_0.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   // Queue packet for |peer1|
@@ -3961,7 +3963,7 @@
       hci_spec::ACLBroadcastFlag::kPointToPoint,
       /*payload_size=*/1);
   connection_1.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Packet for |peer1| should not have been sent before Disconnection Complete event
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
@@ -3972,7 +3974,7 @@
   // Releasing ref should send HCI Disconnect to controller
   conn_handle0().reset();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Packet for |peer1| should not have been sent before Disconnection Complete event
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
@@ -3982,7 +3984,7 @@
 
   // FakeController send us the HCI Disconnection Complete event
   test_device()->SendDisconnectionCompleteEvent(handle0_);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // |peer0|'s link should have been unregistered and packet for |peer1| should have been sent
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_discovery_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_discovery_manager_unittest.cc
index b772f5e..4fe163f 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_discovery_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_discovery_manager_unittest.cc
@@ -30,7 +30,7 @@
 using bt::testing::FakePeer;
 using PauseToken = LowEnergyDiscoveryManager::PauseToken;
 
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 
 const DeviceAddress kAddress0(DeviceAddress::Type::kLEPublic, {0});
 const DeviceAddress kAddrAlias0(DeviceAddress::Type::kBREDR, kAddress0.value());
@@ -42,7 +42,7 @@
 
 constexpr uint16_t kServiceDataUuid = 0x1234;
 
-constexpr zx::duration kTestScanPeriod = zx::sec(10);
+constexpr pw::chrono::SystemClock::duration kTestScanPeriod = std::chrono::seconds(10);
 constexpr pw::chrono::SystemClock::duration kPwTestScanPeriod = std::chrono::seconds(10);
 
 const char* kInspectNodeName = "low_energy_discovery_manager";
@@ -66,9 +66,9 @@
     // could be injected directly. Consider providing fake behavior here in this
     // harness rather than using a FakeController.
     scanner_ = std::make_unique<hci::LegacyLowEnergyScanner>(
-        &fake_address_delegate_, transport()->GetWeakPtr(), pw_dispatcher());
+        &fake_address_delegate_, transport()->GetWeakPtr(), dispatcher());
     discovery_manager_ =
-        std::make_unique<LowEnergyDiscoveryManager>(scanner_.get(), &peer_cache_, pw_dispatcher());
+        std::make_unique<LowEnergyDiscoveryManager>(scanner_.get(), &peer_cache_, dispatcher());
     discovery_manager_->AttachInspect(inspector_.GetRoot(), kInspectNodeName);
 
     test_device()->set_scan_state_callback(
@@ -168,7 +168,7 @@
 
         // Complete local name
         0x09, 0x09, 'D', 'e', 'v', 'i', 'c', 'e', ' ', '0');
-    auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), true, true);
+    auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher(), true, true);
     fake_peer->SetAdvertisingData(kAdvData0);
     test_device()->AddPeer(std::move(fake_peer));
 
@@ -179,7 +179,7 @@
 
         // Complete 16-bit service UUIDs
         0x03, 0x03, 0x0d, 0x18);
-    fake_peer = std::make_unique<FakePeer>(kAddress1, pw_dispatcher(), true, true);
+    fake_peer = std::make_unique<FakePeer>(kAddress1, dispatcher(), true, true);
     fake_peer->SetAdvertisingData(kAdvData1);
     test_device()->AddPeer(std::move(fake_peer));
 
@@ -190,7 +190,7 @@
 
         // Complete local name
         0x09, 0x09, 'D', 'e', 'v', 'i', 'c', 'e', ' ', '2');
-    fake_peer = std::make_unique<FakePeer>(kAddress2, pw_dispatcher(), false, false);
+    fake_peer = std::make_unique<FakePeer>(kAddress2, dispatcher(), false, false);
     fake_peer->SetAdvertisingData(kAdvData2);
     test_device()->AddPeer(std::move(fake_peer));
 
@@ -201,7 +201,7 @@
 
         // Complete local name
         0x09, 0x09, 'D', 'e', 'v', 'i', 'c', 'e', ' ', '3');
-    fake_peer = std::make_unique<FakePeer>(kAddress3, pw_dispatcher(), false, false);
+    fake_peer = std::make_unique<FakePeer>(kAddress3, dispatcher(), false, false);
     fake_peer->SetAdvertisingData(kAdvData3);
     test_device()->AddPeer(std::move(fake_peer));
   }
@@ -214,14 +214,14 @@
       session = std::move(cb_session);
     });
 
-    RunLoopUntilIdle();
+    RunUntilIdle();
     BT_ASSERT(session);
     return session;
   }
 
  private:
-  PeerCache peer_cache_{pw_dispatcher()};
-  hci::FakeLocalAddressDelegate fake_address_delegate_{pw_dispatcher()};
+  PeerCache peer_cache_{dispatcher()};
+  hci::FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};
   std::unique_ptr<hci::LegacyLowEnergyScanner> scanner_;
   std::unique_ptr<LowEnergyDiscoveryManager> discovery_manager_;
 
@@ -241,12 +241,12 @@
   discovery_manager()->StartDiscovery(
       /*active=*/true, [&session](auto cb_session) { session = std::move(cb_session); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The test fixture will be notified of the change in scan state before we
   // receive the session.
   EXPECT_TRUE(scan_enabled());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(session);
   EXPECT_TRUE(session->alive());
@@ -254,7 +254,7 @@
   session->Stop();
   EXPECT_FALSE(session->alive());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 }
 
@@ -265,19 +265,19 @@
   discovery_manager()->StartDiscovery(
       /*active=*/true, [&session](auto cb_session) { session = std::move(cb_session); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // The test fixture will be notified of the change in scan state before we
   // receive the session.
   EXPECT_TRUE(scan_enabled());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(session);
   EXPECT_TRUE(session->alive());
 
   session = nullptr;
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 }
 
@@ -288,7 +288,7 @@
   discovery_manager()->StartDiscovery(
       /*active=*/true, [&session](auto cb_session) { session = std::move(cb_session); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(scan_enabled());
 
@@ -309,7 +309,7 @@
   // should terminate the session when |session| goes out of scope.
   discovery_manager()->StartDiscovery(/*active=*/true, [](auto session) {});
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(2u, scan_states().size());
   EXPECT_TRUE(scan_states()[0]);
   EXPECT_FALSE(scan_states()[1]);
@@ -322,7 +322,7 @@
   // |session| should contain nullptr.
   discovery_manager()->StartDiscovery(/*active=*/true, [](auto session) { EXPECT_FALSE(session); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 }
 
@@ -338,7 +338,7 @@
 
   discovery_manager()->StartDiscovery(/*active=*/true, cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_EQ(1u, sessions.size());
 
@@ -348,24 +348,24 @@
     discovery_manager()->StartDiscovery(/*active=*/true, cb);
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_EQ(kExpectedSessionCount, sessions.size());
 
   // Remove one session from the list. Scan should continue.
   sessions.pop_back();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 
   // Remove all but one session from the list. Scan should continue.
   sessions.erase(sessions.begin() + 1, sessions.end());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_EQ(1u, sessions.size());
 
   // Remove the last session.
   sessions.clear();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 }
 
@@ -383,13 +383,13 @@
     discovery_manager()->StartDiscovery(/*active=*/true, cb);
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_EQ(kExpectedSessionCount, sessions.size());
 
   // Remove all sessions. This should stop the scan.
   sessions.clear();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 }
 
@@ -410,17 +410,17 @@
     discovery_manager()->StartDiscovery(/*active=*/true, cb);
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_TRUE(session);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(kExpectedSessionCount, cb_count);
   EXPECT_TRUE(scan_enabled());
 
   // Deleting the only remaning session should stop the scan.
   session = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 }
 
@@ -430,7 +430,7 @@
   discovery_manager()->StartDiscovery(
       /*active=*/true, [&session](auto cb_session) { session = std::move(cb_session); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_TRUE(session);
 
@@ -444,7 +444,7 @@
       /*active=*/true, [&session](auto cb_session) { session = std::move(cb_session); });
 
   // Discovery should stop and start again.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(3u, scan_states().size());
   EXPECT_TRUE(scan_states()[0]);
   EXPECT_FALSE(scan_states()[1]);
@@ -467,7 +467,7 @@
     discovery_manager()->StartDiscovery(/*active=*/true, cb);
   }
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 }
 
@@ -481,11 +481,11 @@
       /*active=*/true, [&session](auto cb_session) { session = std::move(cb_session); });
 
   // We should observe the scan state become enabled -> disabled -> enabled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 
   // End the scan period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   ASSERT_EQ(kNumScanStates, scan_states().size());
   EXPECT_TRUE(scan_states()[0]);
   EXPECT_FALSE(scan_states()[1]);
@@ -512,11 +512,11 @@
                                             pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED);
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 
   // End the scan period. The scan should not restart.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
 
   ASSERT_EQ(kNumScanStates, scan_states().size());
   EXPECT_TRUE(scan_states()[0]);
@@ -545,11 +545,11 @@
     session->Stop();
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 
   // End the scan period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   EXPECT_THAT(scan_states(), ::testing::ElementsAre(true, false, true, false));
 }
 
@@ -575,11 +575,11 @@
     session->Stop();
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 
   // End the scan period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   EXPECT_THAT(scan_states(), ::testing::ElementsAre(true, false));
 }
 
@@ -608,11 +608,11 @@
     discovery_manager()->StartDiscovery(/*active=*/true, cb);
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 
   // End the scan period.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
 
   // Scan should have been disabled and re-enabled.
   ASSERT_EQ(kTotalNumStates, scan_states().size());
@@ -678,7 +678,7 @@
   sessions[5]->filter()->set_service_data_uuids({UUID(kServiceDataUuid)});
   sessions[5]->SetResultCallback(std::move(result_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(6u, sessions.size());
 
@@ -734,7 +734,7 @@
   sessions[0]->filter()->SetGeneralDiscoveryFlags();
   sessions[0]->SetResultCallback(std::move(result_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(3u, peers_session0.size());
 
   // Session 1 is interested in performing limited discovery.
@@ -805,7 +805,7 @@
 }
 
 TEST_F(LowEnergyDiscoveryManagerTest, DirectedAdvertisingEventFromUnknownPeer) {
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), /*connectable=*/true,
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher(), /*connectable=*/true,
                                               /*scannable=*/false);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
@@ -822,7 +822,7 @@
   int passive_count = 0;
   passive_session->SetResultCallback([&](auto& peer) { passive_count++; });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(active_session);
   ASSERT_TRUE(passive_session);
   EXPECT_EQ(0, connectable_count);
@@ -831,7 +831,7 @@
 }
 
 TEST_F(LowEnergyDiscoveryManagerTest, DirectedAdvertisingEventFromKnownNonConnectablePeer) {
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), /*connectable=*/false,
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher(), /*connectable=*/false,
                                               /*scannable=*/false);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
@@ -850,7 +850,7 @@
   int passive_count = 0;
   passive_session->SetResultCallback([&](auto& peer) { passive_count++; });
 
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   ASSERT_TRUE(active_session);
   ASSERT_TRUE(passive_session);
   EXPECT_EQ(0, connectable_count);
@@ -859,7 +859,7 @@
 }
 
 TEST_F(LowEnergyDiscoveryManagerTest, DirectedAdvertisingEventFromKnownConnectablePeer) {
-  auto fake_peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), /*connectable=*/true,
+  auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher(), /*connectable=*/true,
                                               /*scannable=*/false);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
@@ -883,7 +883,7 @@
   int passive_count = 0;
   passive_session->SetResultCallback([&](auto& peer) { passive_count++; });
 
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   ASSERT_TRUE(active_session);
   ASSERT_TRUE(passive_session);
   // Connectable callback will be notified at the start of each scan period.
@@ -910,7 +910,7 @@
   session->filter()->SetGeneralDiscoveryFlags();
   session->SetResultCallback(std::move(result_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(3u, addresses_found.size());
   EXPECT_TRUE(addresses_found.find(kAddrAlias0) != addresses_found.end());
@@ -921,13 +921,13 @@
   ASSERT_FALSE(test_device()->le_scan_state().enabled);
 
   auto session = StartDiscoverySession(/*active=*/false);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEScanType::PASSIVE, test_device()->le_scan_state().scan_type);
   EXPECT_FALSE(discovery_manager()->discovering());
 
   session.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->le_scan_state().enabled);
 }
 
@@ -937,7 +937,7 @@
   // Session will be destroyed in callback, stopping scan.
   discovery_manager()->StartDiscovery(/*active=*/false,
                                       [&](auto cb_session) { BT_ASSERT(cb_session); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(2u, scan_states().size());
@@ -951,7 +951,7 @@
     BT_ASSERT(cb_session);
     session = std::move(cb_session);
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(3u, scan_states().size());
 
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
@@ -970,14 +970,14 @@
 
   // Enabling passive scans should not disable the active scan.
   auto passive_session = StartDiscoverySession(false);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(pw::bluetooth::emboss::LEScanType::ACTIVE, test_device()->le_scan_state().scan_type);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(1u, scan_states().size());
 
   // Stopping the active session should fall back to passive scan.
   active_session = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEScanType::PASSIVE, test_device()->le_scan_state().scan_type);
   EXPECT_THAT(scan_states(), ::testing::ElementsAre(true, false, true));
@@ -995,28 +995,28 @@
 
   // Enabling passive scans should not disable the active scan.
   auto passive_session = StartDiscoverySession(false);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(pw::bluetooth::emboss::LEScanType::ACTIVE, test_device()->le_scan_state().scan_type);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(1u, scan_states().size());
 
   // Disabling the passive scan should not disable the active scan.
   passive_session.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(pw::bluetooth::emboss::LEScanType::ACTIVE, test_device()->le_scan_state().scan_type);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(1u, scan_states().size());
 
   // Stopping the active session should stop scans.
   active_session = nullptr;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->le_scan_state().enabled);
   EXPECT_THAT(scan_states(), ::testing::ElementsAre(true, false));
 }
 
 TEST_F(LowEnergyDiscoveryManagerTest, StartActiveScanDuringPassiveScan) {
   auto passive_session = StartDiscoverySession(false);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(test_device()->le_scan_state().enabled);
   ASSERT_EQ(pw::bluetooth::emboss::LEScanType::PASSIVE, test_device()->le_scan_state().scan_type);
 
@@ -1054,7 +1054,7 @@
 
   // Process all the requests. We should observe multiple state transitions:
   // -> enabled (passive) -> disabled -> enabled (active)
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEScanType::ACTIVE, test_device()->le_scan_state().scan_type);
   EXPECT_THAT(scan_states(), ::testing::ElementsAre(true, false, true));
@@ -1067,19 +1067,19 @@
        PeerConnectableCallbackOnlyHandlesEventsFromKnownConnectableDevices) {
   // Address 0: undirected connectable; added to cache below
   {
-    auto peer = std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), /*connectable=*/true,
+    auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher(), /*connectable=*/true,
                                            /*scannable=*/true);
     test_device()->AddPeer(std::move(peer));
   }
   // Address 1: undirected connectable; NOT in cache
   {
-    auto peer = std::make_unique<FakePeer>(kAddress1, pw_dispatcher(), /*connectable=*/true,
+    auto peer = std::make_unique<FakePeer>(kAddress1, dispatcher(), /*connectable=*/true,
                                            /*scannable=*/true);
     test_device()->AddPeer(std::move(peer));
   }
   // Address 2: not connectable; added to cache below
   {
-    auto peer = std::make_unique<FakePeer>(kAddress2, pw_dispatcher(), /*connectable=*/false,
+    auto peer = std::make_unique<FakePeer>(kAddress2, dispatcher(), /*connectable=*/false,
                                            /*scannable=*/false);
     test_device()->AddPeer(std::move(peer));
   }
@@ -1089,21 +1089,21 @@
   //
   // added to cache below
   {
-    auto peer = std::make_unique<FakePeer>(kAddress3, pw_dispatcher(), /*connectable=*/false,
+    auto peer = std::make_unique<FakePeer>(kAddress3, dispatcher(), /*connectable=*/false,
                                            /*scannable=*/false);
     peer->enable_directed_advertising(true);
     test_device()->AddPeer(std::move(peer));
   }
   // Address 4: directed connectable; added to cache below
   {
-    auto peer = std::make_unique<FakePeer>(kAddress4, pw_dispatcher(), /*connectable=*/true,
+    auto peer = std::make_unique<FakePeer>(kAddress4, dispatcher(), /*connectable=*/true,
                                            /*scannable=*/false);
     peer->enable_directed_advertising(true);
     test_device()->AddPeer(std::move(peer));
   }
   // Address 5: directed connectable; NOT in cache
   {
-    auto peer = std::make_unique<FakePeer>(kAddress5, pw_dispatcher(), /*connectable=*/true,
+    auto peer = std::make_unique<FakePeer>(kAddress5, dispatcher(), /*connectable=*/true,
                                            /*scannable=*/false);
     peer->enable_directed_advertising(true);
     test_device()->AddPeer(std::move(peer));
@@ -1125,7 +1125,7 @@
     EXPECT_TRUE(id == address0_id || id == address4_id) << id.ToString();
   });
   auto session = StartDiscoverySession(/*active=*/false);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2, count);
 
   // No new remote peer cache entries should have been created.
@@ -1137,13 +1137,13 @@
   auto session = StartDiscoverySession(/*active=*/false);
 
   // The scan state should transition to enabled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   ASSERT_EQ(1u, scan_states().size());
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
 
   // End the scan period by advancing time.
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEScanType::PASSIVE, test_device()->le_scan_state().scan_type);
   EXPECT_THAT(scan_states(), ::testing::ElementsAre(true, false, true));
@@ -1155,57 +1155,57 @@
   EXPECT_TRUE(scan_enabled());
 
   std::optional<PauseToken> pause_0 = discovery_manager()->PauseDiscovery();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
   EXPECT_TRUE(discovery_manager()->discovering());
 
   std::optional<PauseToken> pause_1 = discovery_manager()->PauseDiscovery();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
   EXPECT_TRUE(discovery_manager()->discovering());
 
   pause_0.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
   EXPECT_TRUE(discovery_manager()->discovering());
 
   pause_1.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_TRUE(discovery_manager()->discovering());
 }
 
 TEST_F(LowEnergyDiscoveryManagerTest, EnablePassiveScanAfterPausing) {
   std::optional<PauseToken> pause = discovery_manager()->PauseDiscovery();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 
   std::unique_ptr<LowEnergyDiscoverySession> session;
   discovery_manager()->StartDiscovery(/*active=*/false,
                                       [&](auto cb_session) { session = std::move(cb_session); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
   EXPECT_FALSE(session);
 
   pause.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 }
 
 TEST_F(LowEnergyDiscoveryManagerTest, StartActiveScanAfterPausing) {
   std::optional<PauseToken> pause = discovery_manager()->PauseDiscovery();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
 
   std::unique_ptr<LowEnergyDiscoverySession> session;
   discovery_manager()->StartDiscovery(/*active=*/true,
                                       [&](auto cb_session) { session = std::move(cb_session); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(scan_enabled());
   EXPECT_FALSE(session);
 
   pause.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   EXPECT_TRUE(session);
 }
@@ -1222,7 +1222,7 @@
   std::optional<PauseToken> pause;
   set_scan_state_handler(2, [this, &pause]() { pause = discovery_manager()->PauseDiscovery(); });
 
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   EXPECT_TRUE(pause.has_value());
   EXPECT_EQ(scan_states().size(), 2u);
   EXPECT_FALSE(scan_enabled());
@@ -1239,7 +1239,7 @@
   set_scan_state_handler(2, [this, &pause]() { pause = discovery_manager()->PauseDiscovery(); });
 
   session.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(pause.has_value());
   EXPECT_EQ(scan_states().size(), 2u);
   EXPECT_FALSE(scan_enabled());
@@ -1256,7 +1256,7 @@
                                       [&](auto cb_session) { session = std::move(cb_session); });
 
   // The scan should be canceled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(session);
   EXPECT_TRUE(pause.has_value());
   EXPECT_EQ(scan_states().size(), 2u);
@@ -1265,7 +1265,7 @@
 
   // Resume discovery.
   pause.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(session);
   EXPECT_TRUE(scan_enabled());
   EXPECT_TRUE(discovery_manager()->discovering());
@@ -1282,7 +1282,7 @@
                                       [&](auto cb_session) { session = std::move(cb_session); });
 
   // The scan should be canceled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(session);
   EXPECT_TRUE(pause.has_value());
   EXPECT_EQ(scan_states().size(), 2u);
@@ -1290,7 +1290,7 @@
 
   // Resume scan.
   pause.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
 }
 
@@ -1304,7 +1304,7 @@
     discovery_manager()->StartDiscovery(
         /*active=*/true, [&active_session](auto session) { active_session = std::move(session); });
   });
-  RunLoopFor(kTestScanPeriod);
+  RunFor(kTestScanPeriod);
   EXPECT_TRUE(test_device()->le_scan_state().enabled);
   EXPECT_EQ(pw::bluetooth::emboss::LEScanType::ACTIVE, test_device()->le_scan_state().scan_type);
   EXPECT_THAT(scan_states(), ::testing::ElementsAre(true, false, true));
@@ -1314,21 +1314,21 @@
   auto session = StartDiscoverySession(/*active=*/false);
   auto result_cb = [&session](const auto& peer) { session->Stop(); };
   session->SetResultCallback(std::move(result_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   AddFakePeers();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(LowEnergyDiscoveryManagerTest, PeerChangesFromNonConnectableToConnectable) {
   test_device()->AddPeer(
-      std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), /*connectable=*/false));
+      std::make_unique<FakePeer>(kAddress0, dispatcher(), /*connectable=*/false));
 
   std::unique_ptr<LowEnergyDiscoverySession> session;
   discovery_manager()->StartDiscovery(
       /*active=*/true, [&session](auto cb_session) { session = std::move(cb_session); });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scan_enabled());
   auto peer = peer_cache()->FindByAddress(kAddress0);
   ASSERT_TRUE(peer);
@@ -1336,10 +1336,9 @@
 
   // Make peer connectable.
   test_device()->RemovePeer(kAddress0);
-  test_device()->AddPeer(
-      std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), /*connectable=*/true));
+  test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher(), /*connectable=*/true));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   peer = peer_cache()->FindByAddress(kAddress0);
   ASSERT_TRUE(peer);
   EXPECT_TRUE(peer->connectable());
@@ -1347,9 +1346,9 @@
   // Ensure peer stays connectable after non-connectable advertisement.
   test_device()->RemovePeer(kAddress0);
   test_device()->AddPeer(
-      std::make_unique<FakePeer>(kAddress0, pw_dispatcher(), /*connectable=*/false));
+      std::make_unique<FakePeer>(kAddress0, dispatcher(), /*connectable=*/false));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   peer = peer_cache()->FindByAddress(kAddress0);
   ASSERT_TRUE(peer);
   EXPECT_TRUE(peer->connectable());
@@ -1375,7 +1374,7 @@
                                        DoubleIs("scan_interval_ms", ::testing::Gt(0.0)),
                                        DoubleIs("scan_window_ms", ::testing::Gt(0.0))}));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_THAT(InspectProperties(),
               ::testing::IsSupersetOf({StringIs("state", "Passive"),
                                        DoubleIs("scan_interval_ms", ::testing::Gt(0.0)),
@@ -1396,25 +1395,25 @@
   passive_session.reset();
   active_session.reset();
   EXPECT_THAT(InspectProperties(), ::testing::IsSupersetOf({StringIs("state", "Stopping")}));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_THAT(InspectProperties(), ::testing::IsSupersetOf({StringIs("state", "Idle")}));
 
   // Cause discovery to fail.
   test_device()->SetDefaultResponseStatus(hci_spec::kLESetScanEnable,
                                           pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED);
   discovery_manager()->StartDiscovery(/*active=*/true, [](auto session) { EXPECT_FALSE(session); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_THAT(InspectProperties(), ::testing::IsSupersetOf({UintIs("failed_count", 1u)}));
 }
 #endif  // NINSPECT
 
 TEST_F(LowEnergyDiscoveryManagerTest, SetResultCallbackIgnoresRemovedPeers) {
-  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, pw_dispatcher());
+  auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
   test_device()->AddPeer(std::move(fake_peer_0));
   Peer* peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
   PeerId peer_id_0 = peer_0->identifier();
 
-  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, pw_dispatcher());
+  auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, dispatcher());
   test_device()->AddPeer(std::move(fake_peer_1));
   Peer* peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
   PeerId peer_id_1 = peer_1->identifier();
@@ -1424,7 +1423,7 @@
 
   std::unordered_map<PeerId, int> result_counts;
   session->SetResultCallback([&](const Peer& peer) { result_counts[peer.identifier()]++; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(result_counts[peer_id_0], 1);
   EXPECT_EQ(result_counts[peer_id_1], 1);
 
@@ -1432,7 +1431,7 @@
   // for peer_0.
   ASSERT_TRUE(peer_cache()->RemoveDisconnectedPeer(peer_0->identifier()));
   session->SetResultCallback([&](const Peer& peer) { result_counts[peer.identifier()]++; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(result_counts[peer_id_0], 1);
   EXPECT_EQ(result_counts[peer_id_1], 2);
 }
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_interrogator_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_interrogator_unittest.cc
index 5652f06..40e093e 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_interrogator_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_interrogator_unittest.cc
@@ -26,7 +26,7 @@
 const auto kLEReadRemoteFeaturesRsp = testing::CommandStatusPacket(
     hci_spec::kLEReadRemoteFeatures, pw::bluetooth::emboss::StatusCode::SUCCESS);
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 class LowEnergyInterrogatorTest : public TestingBase {
  public:
@@ -36,7 +36,7 @@
   void SetUp() override {
     TestingBase::SetUp();
 
-    peer_cache_ = std::make_unique<PeerCache>(pw_dispatcher());
+    peer_cache_ = std::make_unique<PeerCache>(dispatcher());
 
     peer_ = peer_cache()->NewPeer(kTestDevAddr, /*connectable=*/true);
     ASSERT_TRUE(peer_->le());
@@ -48,7 +48,7 @@
   }
 
   void TearDown() override {
-    RunLoopUntilIdle();
+    RunUntilIdle();
     test_device()->Stop();
     interrogator_ = nullptr;
     peer_cache_ = nullptr;
@@ -93,7 +93,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(status.has_value());
   EXPECT_EQ(fit::ok(), *status);
@@ -116,7 +116,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(status.has_value());
   EXPECT_EQ(fit::ok(), *status);
   ASSERT_TRUE(peer()->le()->features());
@@ -128,7 +128,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(status.has_value());
   EXPECT_EQ(fit::ok(), *status);
@@ -142,7 +142,7 @@
 
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(status.has_value());
   EXPECT_EQ(fit::ok(), *status);
 }
@@ -159,7 +159,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(status.has_value());
   EXPECT_FALSE(status->is_ok());
   EXPECT_FALSE(peer()->le()->features().has_value());
@@ -177,7 +177,7 @@
 
   std::optional<hci::Result<>> status;
   interrogator()->Start([&status](hci::Result<> cb_status) { status = cb_status; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(status.has_value());
   EXPECT_FALSE(status->is_ok());
   EXPECT_FALSE(peer()->version());
@@ -196,18 +196,18 @@
 
   std::optional<hci::Result<>> result;
   interrogator()->Start([&result](hci::Result<> cb_result) { result = cb_result; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(result.has_value());
 
   interrogator()->Cancel();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(result.has_value());
   EXPECT_TRUE(result->is_error());
   EXPECT_EQ(result.value(), ToResult(HostError::kCanceled));
   result.reset();
 
   test_device()->SendCommandChannelPacket(le_remote_features_complete_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(result.has_value());
   // The read remote features handler should not update the features of a canceled interrogation.
   EXPECT_FALSE(peer()->le()->features().has_value());
@@ -226,18 +226,18 @@
 
   std::optional<hci::Result<>> result;
   interrogator()->Start([&result](hci::Result<> cb_result) { result = cb_result; });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(result.has_value());
 
   interrogator()->Cancel();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(result.has_value());
   EXPECT_TRUE(result->is_error());
   EXPECT_EQ(result.value(), ToResult(HostError::kCanceled));
   result.reset();
 
   test_device()->SendCommandChannelPacket(remote_version_complete_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(result.has_value());
   // The read remote version handler should not update the version after a canceled interrogation.
   EXPECT_FALSE(peer()->version());
@@ -253,7 +253,7 @@
     status = cb_status;
     DestroyInterrogator();
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(status.has_value());
   EXPECT_TRUE(status->is_ok());
 }
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/pairing_state_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/pairing_state_unittest.cc
index 01983f3..8579d1f 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/pairing_state_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/pairing_state_unittest.cc
@@ -4,8 +4,6 @@
 
 #include "src/connectivity/bluetooth/core/bt-host/gap/pairing_state.h"
 
-#include <gtest/gtest.h>
-
 #include "src/connectivity/bluetooth/core/bt-host/gap/fake_pairing_delegate.h"
 #include "src/connectivity/bluetooth/core/bt-host/gap/peer_cache.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/fake_bredr_connection.h"
@@ -16,7 +14,6 @@
 #include "src/connectivity/bluetooth/core/bt-host/testing/test_helpers.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/test_packets.h"
 #include "src/connectivity/bluetooth/core/bt-host/transport/error.h"
-#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
 
 namespace bt::gap {
 namespace {
@@ -73,7 +70,7 @@
   WeakSelf<PairingDelegate> weak_self_;
 };
 
-using TestBase = testing::ControllerTest<testing::MockController>;
+using TestBase = testing::FakeDispatcherControllerTest<testing::MockController>;
 class PairingStateTest : public TestBase {
  public:
   PairingStateTest() = default;
@@ -83,7 +80,7 @@
     TestBase::SetUp();
     InitializeACLDataChannel();
 
-    peer_cache_ = std::make_unique<PeerCache>(pw_dispatcher());
+    peer_cache_ = std::make_unique<PeerCache>(dispatcher());
     peer_ = peer_cache_->NewPeer(kPeerAddress, /*connectable=*/true);
 
     auth_request_count_ = 0;
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/command_handler_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/command_handler_unittest.cc
index ec0c1b3..42055f3 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/command_handler_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/command_handler_unittest.cc
@@ -4,8 +4,6 @@
 
 #include "command_handler.h"
 
-#include <gtest/gtest.h>
-
 #include "src/connectivity/bluetooth/core/bt-host/common/error.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"
@@ -89,7 +87,7 @@
                                           0x01,  // param length
                                           kEncodedTestCommandParam);
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 class CommandHandlerTest : public TestingBase {
  public:
   void SetUp() override {
@@ -115,7 +113,7 @@
     event = result.value();
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(event.has_value());
   EXPECT_EQ(event->test_param, kTestEventParam);
 }
@@ -131,7 +129,7 @@
     error = std::move(result).error_value();
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(error.has_value());
   EXPECT_TRUE(error->is(pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED));
 }
@@ -147,7 +145,7 @@
     error = std::move(result).error_value();
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(error.has_value());
   EXPECT_TRUE(error->is(HostError::kPacketMalformed));
 }
@@ -166,7 +164,7 @@
     cb_count++;
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(cb_count, 1u);
   ASSERT_TRUE(event.has_value());
   EXPECT_EQ(event->test_param, kTestEventParam);
@@ -182,7 +180,7 @@
   });
   test_device()->SendCommandChannelPacket(MakeTestEventPacket());
   test_device()->SendCommandChannelPacket(MakeTestEventPacket());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(cb_count, 2u);
   ASSERT_TRUE(event.has_value());
   EXPECT_EQ(event->test_param, kTestEventParam);
@@ -196,7 +194,7 @@
   });
   test_device()->SendCommandChannelPacket(MakeTestEventPacket());
   test_device()->SendCommandChannelPacket(MakeTestEventPacket());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(cb_count, 0u);
 }
 
@@ -211,7 +209,7 @@
     cb_count++;
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(cb_count, 1u);
 }
 
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/connection_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/connection_unittest.cc
index 1bff482..4862d07 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/connection_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/connection_unittest.cc
@@ -34,7 +34,7 @@
 
 using bt::testing::CommandTransaction;
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 const StaticByteBuffer kReadEncryptionKeySizeCommand =
     StaticByteBuffer(0x08, 0x14,  // opcode: HCI_ReadEncryptionKeySize
@@ -179,7 +179,7 @@
 
   connection->Disconnect(pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(callback_called);
   EXPECT_EQ(1u, disconn_cb_count);
 }
@@ -220,7 +220,7 @@
                            /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     acl_connection_0.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   // Create packet to send on |acl_connection_1|
   ACLDataPacketPtr packet =
@@ -229,7 +229,7 @@
                          /*payload_size=*/1);
   packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
   acl_connection_1.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Packet for |acl_connection_1| should not have been sent because controller buffer is full
   EXPECT_EQ(acl_connection_0.queued_packets().size(), 0u);
@@ -241,7 +241,7 @@
                         &disconnect_status_rsp);
   hci_connection_0->Disconnect(
       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   acl_data_channel()->UnregisterConnection(kHandle0);
 
@@ -259,7 +259,7 @@
                                            0x01, 0x00,
                                            // payload
                                            1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Connection handle |kHandle0| should have been unregistered with ACL Data Channel.
   // Since controller packet count was cleared, packet for |kHandle1| should have been sent.
@@ -309,7 +309,7 @@
                            /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     acl_connection_0.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   // Create packet to send on |acl_connection_1|
   ACLDataPacketPtr packet =
@@ -318,7 +318,7 @@
                          /*payload_size=*/1);
   packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
   acl_connection_1.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Packet for |acl_connection_1| should not have been sent because controller buffer is full
   EXPECT_EQ(acl_connection_0.queued_packets().size(), 0u);
@@ -349,7 +349,7 @@
                                            1));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kHandle0, 10));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Connection handle |kHandle0| should have been unregistered with ACL Data Channel.
   // Since controller packet count was cleared, packet for |kHandle1| should have been sent.
@@ -410,7 +410,7 @@
 
   connection->Disconnect(pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(callback_called);
 }
 
@@ -453,7 +453,7 @@
 
   EXPECT_TRUE(conn->StartEncryption());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(callback);
   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kTestHandle));
 }
@@ -484,7 +484,7 @@
 
   // Callback shouldn't be called until the controller sends an encryption
   // changed event.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(callback);
   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kTestHandle));
 }
@@ -516,7 +516,7 @@
 
   EXPECT_TRUE(conn->StartEncryption());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(callback);
   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kTestHandle));
 }
@@ -544,7 +544,7 @@
   EXPECT_TRUE(conn->StartEncryption());
 
   // Callback shouldn't be called until the controller sends an encryption changed event.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(callback);
   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kTestHandle));
 }
@@ -575,7 +575,7 @@
   test_device()->SendCommandChannelPacket(kEncChangeMalformed);
   test_device()->SendCommandChannelPacket(kEncChangeWrongHandle);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(callback);
   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kTestHandle));
 }
@@ -626,14 +626,14 @@
 
   test_device()->SendCommandChannelPacket(bt::testing::EncryptionChangeEventPacket(
       pw::bluetooth::emboss::StatusCode::SUCCESS, kTestHandle, hci_spec::EncryptionStatus::kOn));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, callback_count);
   EXPECT_EQ(fit::ok(), result);
   EXPECT_TRUE(result.value_or(false));
 
   test_device()->SendCommandChannelPacket(kEncryptionChangeEventDisabled);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2, callback_count);
   EXPECT_EQ(fit::ok(), result);
@@ -642,7 +642,7 @@
   // The host should disconnect the link if encryption fails.
   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
   test_device()->SendCommandChannelPacket(kEncryptionChangeEventFailed);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(3, callback_count);
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING).error_value(), result);
@@ -661,7 +661,7 @@
   test_device()->SendCommandChannelPacket(bt::testing::EncryptionChangeEventPacket(
       pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE, kTestHandle,
       hci_spec::EncryptionStatus::kOff));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(peer_disconnect_callback_received);
 
   // Send the disconnection complete resulting from the encryption failure (this usually does not
@@ -669,7 +669,7 @@
   // subsequent event).
   test_device()->SendCommandChannelPacket(bt::testing::DisconnectionCompletePacket(
       kTestHandle, pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(peer_disconnect_callback_received);
 }
 
@@ -696,7 +696,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
   test_device()->SendCommandChannelPacket(bt::testing::EncryptionChangeEventPacket(
       pw::bluetooth::emboss::StatusCode::SUCCESS, kTestHandle, hci_spec::EncryptionStatus::kOn));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, callback_count);
 }
@@ -724,7 +724,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
   test_device()->SendCommandChannelPacket(bt::testing::EncryptionChangeEventPacket(
       pw::bluetooth::emboss::StatusCode::SUCCESS, kTestHandle, hci_spec::EncryptionStatus::kOn));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, callback_count);
 }
@@ -755,7 +755,7 @@
   test_device()->SendCommandChannelPacket(bt::testing::EncryptionChangeEventPacket(
       pw::bluetooth::emboss::StatusCode::SUCCESS, kTestHandle,
       hci_spec::EncryptionStatus::kBredrSecureConnections));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, callback_count);
   EXPECT_EQ(fit::ok(), result);
@@ -784,7 +784,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
   test_device()->SendCommandChannelPacket(bt::testing::EncryptionChangeEventPacket(
       pw::bluetooth::emboss::StatusCode::SUCCESS, kTestHandle, hci_spec::EncryptionStatus::kOn));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, callback_count);
   EXPECT_TRUE(result.is_error());
@@ -818,7 +818,7 @@
   });
 
   test_device()->SendCommandChannelPacket(kEncryptionKeyRefresh);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, callback_count);
   ASSERT_EQ(fit::ok(), result);
@@ -827,7 +827,7 @@
   // The host should disconnect the link if encryption fails.
   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
   test_device()->SendCommandChannelPacket(kEncryptionKeyRefreshFailed);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2, callback_count);
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING).error_value(), result);
@@ -867,7 +867,7 @@
   test_device()->SendCommandChannelPacket(kMalformed);
   test_device()->SendCommandChannelPacket(kWrongHandle);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Test will fail if the connection sends a response without ignoring these events.
   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kTestHandle));
@@ -899,7 +899,7 @@
   auto conn = NewLEConnection();
 
   test_device()->SendCommandChannelPacket(kEvent);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // There is a link key but EDiv and Rand values don't match.
@@ -930,7 +930,7 @@
   conn->set_ltk(hci_spec::LinkKey(kLTK, 1, 1));
 
   test_device()->SendCommandChannelPacket(kEvent);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ConnectionTest, LELongTermKeyRequestReply) {
@@ -962,7 +962,7 @@
   conn->set_ltk(hci_spec::LinkKey(kLTK, 0x8899AABBCCDDEEFF, 0xBEEF));
 
   test_device()->SendCommandChannelPacket(kEvent);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ConnectionTest,
@@ -997,10 +997,10 @@
                            /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     acl_connection_0.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   // Run until the data is flushed out to the MockController.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Only packets that fit in buffer should have been received.
   EXPECT_EQ(acl_connection_0.queued_packets().size(), 1u);
@@ -1017,7 +1017,7 @@
   // Disconnect |hci_connection_0| by destroying it. The received disconnection complete event will
   // cause the handler to clear pending packets.
   hci_connection_0.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Register connection with same handle.
   FakeAclConnection acl_connection_1(acl_data_channel(), kHandle, bt::LinkType::kACL);
@@ -1047,10 +1047,10 @@
                            /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     acl_connection_1.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   // Run until the data is flushed out to the MockController.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(acl_connection_1.queued_packets().size(), 1u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -1062,7 +1062,7 @@
   hci_connection_1.reset();
   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kHandle),
                         &disconnect_status_rsp, &disconnection_complete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ConnectionTest, PeerDisconnectCallback) {
@@ -1079,12 +1079,12 @@
   };
   conn->set_peer_disconnect_callback(disconn_complete_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, cb_count);
 
   DynamicByteBuffer disconnection_complete(bt::testing::DisconnectionCompletePacket(kHandle));
   test_device()->SendCommandChannelPacket(disconnection_complete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, cb_count);
 }
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/extended_low_energy_advertiser_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/extended_low_energy_advertiser_unittest.cc
index 567dd5b..d956a45 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/extended_low_energy_advertiser_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/extended_low_energy_advertiser_unittest.cc
@@ -11,7 +11,7 @@
 namespace {
 
 using bt::testing::FakeController;
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 using AdvertisingOptions = LowEnergyAdvertiser::AdvertisingOptions;
 using LEAdvertisingState = FakeController::LEAdvertisingState;
 
@@ -101,7 +101,7 @@
 
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, conn_cb,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(this->GetLastStatus());
   EXPECT_EQ(1u, this->advertiser()->NumAdvertisements());
   EXPECT_TRUE(this->advertiser()->IsAdvertising());
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_advertiser_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_advertiser_unittest.cc
index c9aeb1b..5cca9a5 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_advertiser_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_advertiser_unittest.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 
 const DeviceAddress kPublicAddress(DeviceAddress::Type::kLEPublic, {1});
 const DeviceAddress kRandomAddress(DeviceAddress::Type::kLERandom, {2});
@@ -143,7 +143,7 @@
 
   advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                  MakeExpectSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
@@ -159,7 +159,7 @@
   ad.SetAppearance(new_appearance);
   advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, nullptr,
                                  MakeExpectErrorCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Should still be using the random address.
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
@@ -181,7 +181,7 @@
 
   advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                  MakeExpectSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
 
@@ -200,7 +200,7 @@
                               expected_scan_rsp));
 
   advertiser()->StopAdvertising(kRandomAddress);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->legacy_advertising_state().enabled);
 }
 
@@ -224,7 +224,7 @@
   // This call should override the previous call and succeed with the new parameters.
   advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr,
                                  MakeExpectSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(new_interval.max(), test_device()->legacy_advertising_state().interval_max);
@@ -262,7 +262,7 @@
   // This call should override the previous call and succeed with the new parameters.
   advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr,
                                  MakeExpectSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(new_interval.max(), test_device()->legacy_advertising_state().interval_max);
@@ -295,7 +295,7 @@
   // This call should override the previous call and succeed with the new parameters.
   advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr,
                                  MakeExpectSuccessCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(new_interval.max(), test_device()->legacy_advertising_state().interval_max);
@@ -330,7 +330,7 @@
   advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr, MakeExpectErrorCallback());
   EXPECT_FALSE(test_device()->legacy_advertising_state().enabled);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // At this point in time, the first StartAdvertising call is still waiting on the TX Power Level
   // Read response.
 
@@ -343,7 +343,7 @@
   // Explicitly respond to the first TX Power Level read command.
   test_device()->OnLEReadAdvertisingChannelTxPower();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_EQ(new_interval.max(), test_device()->legacy_advertising_state().interval_max);
 }
@@ -361,7 +361,7 @@
 
   advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                  MakeExpectErrorCallback());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto status = MoveLastStatus();
   ASSERT_TRUE(status.has_value());
   ASSERT_TRUE(status->is_error());
@@ -390,7 +390,7 @@
   EXPECT_FALSE(advertiser()->AllowsRandomAddressChange());
 
   // The random address cannot be changed while advertising is enabled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_FALSE(advertiser()->AllowsRandomAddressChange());
@@ -401,7 +401,7 @@
   EXPECT_TRUE(test_device()->legacy_advertising_state().enabled);
   EXPECT_TRUE(advertiser()->AllowsRandomAddressChange());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(test_device()->legacy_advertising_state().enabled);
   EXPECT_TRUE(advertiser()->AllowsRandomAddressChange());
 }
@@ -416,7 +416,7 @@
                                        MakeExpectErrorCallback());
   this->advertiser()->StopAdvertising(kPublicAddress);
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(MoveLastStatus());
   EXPECT_FALSE(test_device()->legacy_advertising_state().enabled);
 }
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_scanner_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_scanner_unittest.cc
index c8341ec..78858a1 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_scanner_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/legacy_low_energy_scanner_unittest.cc
@@ -16,11 +16,11 @@
 
 using bt::testing::FakeController;
 using bt::testing::FakePeer;
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 
-constexpr zx::duration kScanPeriod = zx::sec(10);
+constexpr pw::chrono::SystemClock::duration kScanPeriod = std::chrono::seconds(10);
 constexpr pw::chrono::SystemClock::duration kPwScanPeriod = std::chrono::seconds(10);
-constexpr zx::duration kScanResponseTimeout = zx::sec(2);
+constexpr pw::chrono::SystemClock::duration kScanResponseTimeout = std::chrono::seconds(2);
 constexpr pw::chrono::SystemClock::duration kPwScanResponseTimeout = std::chrono::seconds(2);
 
 // The unit tests below assume that the scan period is longer than the scan response timeout when
@@ -58,7 +58,7 @@
     test_device()->set_settings(settings);
 
     scanner_ = std::make_unique<LegacyLowEnergyScanner>(&fake_address_delegate_,
-                                                        transport()->GetWeakPtr(), pw_dispatcher());
+                                                        transport()->GetWeakPtr(), dispatcher());
     scanner_->set_delegate(this);
   }
 
@@ -100,39 +100,39 @@
   // Adds 6 fake peers using kAddress[0-5] above.
   void AddFakePeers() {
     // Generates ADV_IND, scan response is reported in a single HCI event.
-    auto fake_peer = std::make_unique<FakePeer>(kPublicAddress1, pw_dispatcher(), true, true);
+    auto fake_peer = std::make_unique<FakePeer>(kPublicAddress1, dispatcher(), true, true);
     fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
     fake_peer->SetScanResponse(/*should_batch_reports=*/true, kPlainScanRspBytes);
     test_device()->AddPeer(std::move(fake_peer));
 
     // Generates ADV_SCAN_IND, scan response is reported over multiple HCI
     // events.
-    fake_peer = std::make_unique<FakePeer>(kRandomAddress1, pw_dispatcher(), false, true);
+    fake_peer = std::make_unique<FakePeer>(kRandomAddress1, dispatcher(), false, true);
     fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
     fake_peer->SetScanResponse(/*should_batch_reports=*/false, kPlainScanRspBytes);
     test_device()->AddPeer(std::move(fake_peer));
 
     // Generates ADV_IND, empty scan response is reported over multiple HCI
     // events.
-    fake_peer = std::make_unique<FakePeer>(kPublicAddress2, pw_dispatcher(), true, true);
+    fake_peer = std::make_unique<FakePeer>(kPublicAddress2, dispatcher(), true, true);
     fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
     fake_peer->SetScanResponse(/*should_batch_reports=*/false, DynamicByteBuffer());
     test_device()->AddPeer(std::move(fake_peer));
 
     // Generates ADV_IND, empty adv data and non-empty scan response is reported
     // over multiple HCI events.
-    fake_peer = std::make_unique<FakePeer>(kRandomAddress2, pw_dispatcher(), true, true);
+    fake_peer = std::make_unique<FakePeer>(kRandomAddress2, dispatcher(), true, true);
     fake_peer->SetScanResponse(/*should_batch_reports=*/false, kPlainScanRspBytes);
     test_device()->AddPeer(std::move(fake_peer));
 
     // Generates ADV_IND, a scan response is never sent even though ADV_IND is
     // scannable.
-    fake_peer = std::make_unique<FakePeer>(kRandomAddress3, pw_dispatcher(), true, false);
+    fake_peer = std::make_unique<FakePeer>(kRandomAddress3, dispatcher(), true, false);
     fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
     test_device()->AddPeer(std::move(fake_peer));
 
     // Generates ADV_NONCONN_IND
-    fake_peer = std::make_unique<FakePeer>(kRandomAddress4, pw_dispatcher(), false, false);
+    fake_peer = std::make_unique<FakePeer>(kRandomAddress4, dispatcher(), false, false);
     fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
     test_device()->AddPeer(std::move(fake_peer));
   }
@@ -145,7 +145,7 @@
  private:
   PeerFoundCallback peer_found_cb_;
   DirectedAdvCallback directed_adv_cb_;
-  FakeLocalAddressDelegate fake_address_delegate_{pw_dispatcher()};
+  FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};
   std::unique_ptr<LegacyLowEnergyScanner> scanner_;
 
   LowEnergyScanner::ScanStatus last_scan_status_;
@@ -170,7 +170,7 @@
 
   // Calling StartScan() should fail as the state is not kIdle.
   EXPECT_FALSE(StartScan(false));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Status should be failure and the scan parameters shouldn't have applied.
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kFailed, last_scan_status());
@@ -186,7 +186,7 @@
 
   EXPECT_TRUE(StartScan(false));
   EXPECT_EQ(LowEnergyScanner::State::kInitiating, scanner()->state());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Status should be failure but the scan parameters should have applied.
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kFailed, last_scan_status());
@@ -206,7 +206,7 @@
 
   EXPECT_TRUE(StartScan(true, kPwScanPeriod));
   EXPECT_EQ(LowEnergyScanner::State::kInitiating, scanner()->state());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Scan should have started.
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kActive, last_scan_status());
@@ -224,7 +224,7 @@
   EXPECT_FALSE(StartScan(true));
 
   // After 10 s (kScanPeriod) the scan should stop by itself.
-  RunLoopFor(kScanPeriod);
+  RunFor(kScanPeriod);
 
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kComplete, last_scan_status());
   EXPECT_FALSE(test_device()->le_scan_state().enabled);
@@ -244,7 +244,7 @@
   // the scan directly.
   EXPECT_TRUE(StartScan(true, kPwScanPeriod * 10u));
   EXPECT_EQ(LowEnergyScanner::State::kInitiating, scanner()->state());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Scan should have started.
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kActive, last_scan_status());
@@ -255,7 +255,7 @@
   // StopScan() should terminate the scan session and the status should be
   // kStopped.
   EXPECT_TRUE(scanner()->StopScan());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kStopped, last_scan_status());
   EXPECT_FALSE(test_device()->le_scan_state().enabled);
@@ -275,7 +275,7 @@
   // StartScan() so that the it never completes. The HCI_LE_Set_Scan_Parameters
   // command *may* get sent but the scan should never get enabled.
   EXPECT_TRUE(scanner()->StopScan());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kStopped, last_scan_status());
   EXPECT_FALSE(test_device()->le_scan_state().enabled);
@@ -284,45 +284,45 @@
 }
 
 TEST_F(LegacyLowEnergyScannerTest, ScanResponseTimeout) {
-  constexpr zx::duration kHalfTimeout = kScanResponseTimeout / 2;
+  constexpr pw::chrono::SystemClock::duration kHalfTimeout = kScanResponseTimeout / 2;
 
   std::unordered_set<DeviceAddress> results;
   set_peer_found_callback(
       [&](const auto& result, const auto& data) { results.insert(result.address); });
 
   // Add a peer that sends a scan response and one that doesn't.
-  auto fake_peer = std::make_unique<FakePeer>(kRandomAddress1, pw_dispatcher(), false, true);
+  auto fake_peer = std::make_unique<FakePeer>(kRandomAddress1, dispatcher(), false, true);
   fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
   fake_peer->SetScanResponse(/*should_batch_reports=*/false, kPlainScanRspBytes);
   test_device()->AddPeer(std::move(fake_peer));
 
-  fake_peer = std::make_unique<FakePeer>(kRandomAddress2, pw_dispatcher(), true, false);
+  fake_peer = std::make_unique<FakePeer>(kRandomAddress2, dispatcher(), true, false);
   fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
   test_device()->AddPeer(std::move(fake_peer));
 
   EXPECT_TRUE(StartScan(true));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(1u, results.size());
   EXPECT_EQ(1u, results.count(kRandomAddress1));
 
   // Advance the time but do not expire the timeout.
-  RunLoopFor(kHalfTimeout);
+  RunFor(kHalfTimeout);
   ASSERT_EQ(1u, results.size());
 
   // Add another peer that doesn't send a scan response after the kHalfTimeout delay.
   // This is to test that a separate timeout is kept for every peer.
-  fake_peer = std::make_unique<FakePeer>(kRandomAddress3, pw_dispatcher(), true, false);
+  fake_peer = std::make_unique<FakePeer>(kRandomAddress3, dispatcher(), true, false);
   fake_peer->SetAdvertisingData(kPlainAdvDataBytes);
   test_device()->AddPeer(std::move(fake_peer));
 
   // Expire the first timeout.
-  RunLoopFor(kHalfTimeout);
+  RunFor(kHalfTimeout);
   ASSERT_EQ(2u, results.size());
   EXPECT_EQ(1u, results.count(kRandomAddress1));
   EXPECT_EQ(1u, results.count(kRandomAddress2));
 
   // Expire the second timeout.
-  RunLoopFor(kHalfTimeout);
+  RunFor(kHalfTimeout);
   ASSERT_EQ(3u, results.size());
   EXPECT_EQ(1u, results.count(kRandomAddress1));
   EXPECT_EQ(1u, results.count(kRandomAddress2));
@@ -345,12 +345,12 @@
   EXPECT_TRUE(StartScan(true, kPwScanPeriod));
   EXPECT_EQ(LowEnergyScanner::State::kInitiating, scanner()->state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(kExpectedResultCount, results.size());
 
   // Ending the scan period should notify Fake Peer #4.
-  RunLoopFor(kScanPeriod);
+  RunFor(kScanPeriod);
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kComplete, last_scan_status());
   ASSERT_EQ(kExpectedResultCount + 1, results.size());
 
@@ -447,21 +447,21 @@
   // never complete by itself.
   EXPECT_TRUE(StartScan(true));
   EXPECT_EQ(LowEnergyScanner::State::kInitiating, scanner()->state());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(LowEnergyScanner::State::kActiveScanning, scanner()->state());
 
   // Run the loop until we've seen an event for the last peer that we
   // added. Fake Peer 4 (i.e. kRandomAddress3) is scannable but it never sends
   // a scan response so we expect that to remain in the scanner's pending reports
   // list.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(5u, results.size());
   EXPECT_EQ(results.find(kRandomAddress3), results.end());
 
   // Stop the scan. Since we are terminating the scan period early,
   // LowEnergyScanner should not send a report for the pending peer.
   EXPECT_TRUE(scanner()->StopScan());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scanner()->IsIdle());
 
   EXPECT_EQ(5u, results.size());
@@ -482,7 +482,7 @@
 
   EXPECT_EQ(LowEnergyScanner::State::kInitiating, scanner()->state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(LowEnergyScanner::State::kPassiveScanning, scanner()->state());
   EXPECT_EQ(LowEnergyScanner::ScanStatus::kPassive, last_scan_status());
   ASSERT_EQ(kExpectedResultCount, results.size());
@@ -573,23 +573,23 @@
   constexpr size_t kExpectedResultCount = 4u;
 
   // Unresolved public.
-  auto fake_peer = std::make_unique<FakePeer>(kPublicUnresolved, pw_dispatcher(), true, false);
+  auto fake_peer = std::make_unique<FakePeer>(kPublicUnresolved, dispatcher(), true, false);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
 
   // Unresolved random.
-  fake_peer = std::make_unique<FakePeer>(kRandomUnresolved, pw_dispatcher(), true, false);
+  fake_peer = std::make_unique<FakePeer>(kRandomUnresolved, dispatcher(), true, false);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
 
   // Resolved public.
-  fake_peer = std::make_unique<FakePeer>(kPublicResolved, pw_dispatcher(), true, false);
+  fake_peer = std::make_unique<FakePeer>(kPublicResolved, dispatcher(), true, false);
   fake_peer->set_address_resolved(true);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
 
   // Resolved random.
-  fake_peer = std::make_unique<FakePeer>(kRandomResolved, pw_dispatcher(), true, false);
+  fake_peer = std::make_unique<FakePeer>(kRandomResolved, dispatcher(), true, false);
   fake_peer->set_address_resolved(true);
   fake_peer->enable_directed_advertising(true);
   test_device()->AddPeer(std::move(fake_peer));
@@ -600,7 +600,7 @@
   EXPECT_TRUE(StartScan(true));
   EXPECT_EQ(LowEnergyScanner::State::kInitiating, scanner()->state());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(LowEnergyScanner::ScanStatus::kActive, last_scan_status());
   ASSERT_EQ(kExpectedResultCount, results.size());
@@ -626,7 +626,7 @@
   EXPECT_TRUE(scanner()->IsInitiating());
   EXPECT_FALSE(scanner()->AllowsRandomAddressChange());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scanner()->IsPassiveScanning());
   EXPECT_FALSE(scanner()->AllowsRandomAddressChange());
 }
@@ -641,7 +641,7 @@
   EXPECT_TRUE(scanner()->IsInitiating());
   EXPECT_TRUE(scanner()->AllowsRandomAddressChange());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scanner()->IsPassiveScanning());
   EXPECT_FALSE(scanner()->AllowsRandomAddressChange());
 }
@@ -649,7 +649,7 @@
 TEST_F(LegacyLowEnergyScannerTest, ScanUsingPublicAddress) {
   fake_address_delegate()->set_local_address(kPublicAddress1);
   EXPECT_TRUE(StartScan(false));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scanner()->IsPassiveScanning());
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
             test_device()->le_scan_state().own_address_type);
@@ -658,7 +658,7 @@
 TEST_F(LegacyLowEnergyScannerTest, ScanUsingRandomAddress) {
   fake_address_delegate()->set_local_address(kRandomAddress1);
   EXPECT_TRUE(StartScan(false));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(scanner()->IsPassiveScanning());
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
             test_device()->le_scan_state().own_address_type);
@@ -673,7 +673,7 @@
   EXPECT_TRUE(scanner()->AllowsRandomAddressChange());
 
   EXPECT_TRUE(scanner()->StopScan());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Should end up not scanning.
   EXPECT_TRUE(scanner()->IsIdle());
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/low_energy_advertiser_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/low_energy_advertiser_unittest.cc
index b10e970..cb0cfcc 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/low_energy_advertiser_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/low_energy_advertiser_unittest.cc
@@ -29,7 +29,7 @@
 using bt::testing::FakePeer;
 
 using AdvertisingOptions = LowEnergyAdvertiser::AdvertisingOptions;
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 
 constexpr hci_spec::ConnectionHandle kConnectionHandle = 0x0001;
 constexpr AdvertisingIntervalRange kTestInterval(hci_spec::kLEAdvertisingIntervalMin,
@@ -241,7 +241,7 @@
   // Start advertising kPublicAddress
   this->advertiser()->StartAdvertising(kPublicAddress, adv_data, scan_data, options, conn_cb,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->advertiser()->IsAdvertising());
   EXPECT_TRUE(this->advertiser()->IsAdvertising(kPublicAddress));
@@ -254,7 +254,7 @@
   std::optional<hci_spec::AdvertisingHandle> handle = this->CurrentAdvertisingHandle();
   ASSERT_TRUE(handle);
   this->MaybeSendMultipleAdvertisingPostConnectionEvents(kConnectionHandle, handle.value());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   ASSERT_TRUE(link);
   EXPECT_EQ(kConnectionHandle, link->handle());
@@ -266,13 +266,13 @@
   // Advertising state should get cleared on a disconnection
   link->Disconnect(pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
   this->test_device()->SendDisconnectionCompleteEvent(link->handle());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_FALSE(this->GetControllerAdvertisingState().enabled);
 
   // Restart advertising using a different local address
   this->advertiser()->StartAdvertising(kRandomAddress, adv_data, scan_data, options, conn_cb,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
 
@@ -285,7 +285,7 @@
   handle = this->CurrentAdvertisingHandle();
   ASSERT_TRUE(handle);
   this->MaybeSendMultipleAdvertisingPostConnectionEvents(kConnectionHandle, handle.value());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   ASSERT_TRUE(link);
   EXPECT_EQ(kRandomAddress, link->local_address());
@@ -310,7 +310,7 @@
 
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, conn_cb,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
 
@@ -332,7 +332,7 @@
   this->MaybeSendMultipleAdvertisingPostConnectionEvents(kConnectionHandle, handle.value());
 
   // Advertising should get disabled and re-enabled.
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   ASSERT_EQ(2u, adv_states.size());
   EXPECT_FALSE(adv_states[0]);
   EXPECT_TRUE(adv_states[1]);
@@ -351,11 +351,11 @@
       });
 
   auto fake_peer =
-      std::make_unique<FakePeer>(kRandomAddress, TestFixture::pw_dispatcher(), true, true);
+      std::make_unique<FakePeer>(kRandomAddress, TestFixture::dispatcher(), true, true);
   this->test_device()->AddPeer(std::move(fake_peer));
   this->test_device()->ConnectLowEnergy(kRandomAddress,
                                         pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   ASSERT_EQ(1u, connection_states.size());
   auto [connection_state, handle] = connection_states[0];
@@ -367,7 +367,7 @@
                                            pw::bluetooth::emboss::ConnectionRole::PERIPHERAL,
                                            kRandomAddress, hci_spec::LEConnectionParameters());
   this->MaybeSendMultipleAdvertisingPostConnectionEvents(kConnectionHandle, 0);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   ASSERT_EQ(2u, connection_states.size());
   auto [connection_state_after_disconnect, disconnected_handle] = connection_states[1];
   EXPECT_EQ(handle, disconnected_handle);
@@ -382,7 +382,7 @@
                              /*include_tx_power_level=*/false);
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   ASSERT_TRUE(this->GetLastStatus());
 
   std::vector<std::pair<bool, hci_spec::ConnectionHandle>> connection_states;
@@ -394,11 +394,11 @@
       });
 
   auto fake_peer =
-      std::make_unique<FakePeer>(kRandomAddress, TestFixture::pw_dispatcher(), true, true);
+      std::make_unique<FakePeer>(kRandomAddress, TestFixture::dispatcher(), true, true);
   this->test_device()->AddPeer(std::move(fake_peer));
   this->test_device()->ConnectLowEnergy(kRandomAddress,
                                         pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   ASSERT_EQ(1u, connection_states.size());
   auto [connection_state, handle] = connection_states[0];
@@ -410,7 +410,7 @@
                                            pw::bluetooth::emboss::ConnectionRole::PERIPHERAL,
                                            kRandomAddress, hci_spec::LEConnectionParameters());
   this->MaybeSendMultipleAdvertisingPostConnectionEvents(kConnectionHandle, 0);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   ASSERT_EQ(2u, connection_states.size());
   auto [connection_state_after_disconnect, disconnected_handle] = connection_states[1];
   EXPECT_EQ(handle, disconnected_handle);
@@ -426,12 +426,12 @@
 
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
 
   this->advertiser()->StopAdvertising(kRandomAddress);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_FALSE(this->GetControllerAdvertisingState().enabled);
 }
 
@@ -445,7 +445,7 @@
 
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   // The expected advertisement including the Flags.
@@ -471,7 +471,7 @@
                                  /*include_tx_power_level=*/false);
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, new_options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   state = this->GetControllerAdvertisingState();
@@ -499,7 +499,7 @@
 
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   // new advertising data (with fewer fields filled in)
@@ -507,7 +507,7 @@
   AdvertisingData new_ad = this->GetExampleData();
   this->advertiser()->StartAdvertising(kRandomAddress, new_ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   DynamicByteBuffer expected_ad(new_ad.CalculateBlockSize(/*include_flags=*/true));
@@ -529,7 +529,7 @@
                              /*include_tx_power_level=*/false);
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   std::optional<FakeController::LEAdvertisingState> state = this->GetControllerAdvertisingState();
@@ -544,7 +544,7 @@
                                  /*include_tx_power_level=*/false);
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, new_options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   state = this->GetControllerAdvertisingState();
@@ -571,7 +571,7 @@
   // This call should override the previous call and succeed with the new parameters.
   this->advertiser()->StartAdvertising(addr, ad, scan_data, new_options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
   EXPECT_EQ(new_interval.max(), this->GetControllerAdvertisingState().interval_max);
@@ -587,7 +587,7 @@
   // Get to a started state.
   this->advertiser()->StartAdvertising(addr, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
 
@@ -609,7 +609,7 @@
   this->advertiser()->StopAdvertising(addr);
 
   // Advertising should have been momentarily disabled.
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(was_disabled);
   EXPECT_TRUE(enabled);
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
@@ -627,7 +627,7 @@
                                        this->MakeExpectErrorCallback());
   this->advertiser()->StopAdvertising();
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_FALSE(this->GetControllerAdvertisingState().enabled);
 }
@@ -644,7 +644,7 @@
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   EXPECT_TRUE(this->GetLastStatus());
 
@@ -654,7 +654,7 @@
   EXPECT_TRUE(
       ContainersEqual(this->GetControllerAdvertisingState().advertised_view(), expected_ad));
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   this->advertiser()->StopAdvertising(kPublicAddress);
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
   EXPECT_TRUE(
@@ -662,7 +662,7 @@
 
   this->advertiser()->StopAdvertising(kRandomAddress);
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_FALSE(this->GetControllerAdvertisingState().enabled);
   EXPECT_EQ(0u, this->GetControllerAdvertisingState().advertised_view().size());
   EXPECT_EQ(0u, this->GetControllerAdvertisingState().scan_rsp_view().size());
@@ -677,7 +677,7 @@
 
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
@@ -699,7 +699,7 @@
                                  /*include_tx_power_level=*/false);
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, new_options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   EXPECT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->GetControllerAdvertisingState().enabled);
@@ -723,7 +723,7 @@
                              /*include_tx_power_level=*/false);
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, options, nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   constexpr uint8_t blank[hci_spec::kMaxLEAdvertisingDataLength] = {0};
@@ -743,7 +743,7 @@
 
   // stop advertising the random address
   this->advertiser()->StopAdvertising(kPublicAddress);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   // check that advertiser and controller both report the same advertising state
   EXPECT_FALSE(this->advertiser()->IsAdvertising());
@@ -781,7 +781,7 @@
   // Advertising data too large.
   this->advertiser()->StartAdvertising(kRandomAddress, invalid_ad, valid_scan_rsp, options, nullptr,
                                        this->MakeExpectErrorCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   auto status = this->GetLastStatus();
   ASSERT_TRUE(status);
   EXPECT_EQ(ToResult(HostError::kAdvertisingDataTooLong), *status);
@@ -797,7 +797,7 @@
   // Advertising data too large.
   this->advertiser()->StartAdvertising(kRandomAddress, invalid_ad, valid_scan_rsp, options, nullptr,
                                        this->MakeExpectErrorCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   auto status = this->GetLastStatus();
   ASSERT_TRUE(status);
   EXPECT_EQ(ToResult(HostError::kAdvertisingDataTooLong), *status);
@@ -810,7 +810,7 @@
                              /*include_tx_power_level=*/false);
   this->advertiser()->StartAdvertising(kRandomAddress, valid_ad, invalid_scan_rsp, options, nullptr,
                                        this->MakeExpectErrorCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   auto status = this->GetLastStatus();
   ASSERT_TRUE(status);
   EXPECT_EQ(ToResult(HostError::kScanResponseTooLong), *status);
@@ -824,7 +824,7 @@
                              /*include_tx_power_level=*/true);
   this->advertiser()->StartAdvertising(kRandomAddress, valid_ad, invalid_scan_rsp, options, nullptr,
                                        this->MakeExpectErrorCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   auto status = this->GetLastStatus();
   ASSERT_TRUE(status);
   EXPECT_EQ(ToResult(HostError::kScanResponseTooLong), *status);
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/low_energy_connector_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/low_energy_connector_unittest.cc
index 17c5f86..acc883b 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/low_energy_connector_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/low_energy_connector_unittest.cc
@@ -4,8 +4,6 @@
 
 #include "src/connectivity/bluetooth/core/bt-host/hci/low_energy_connector.h"
 
-#include <lib/async/cpp/task.h>
-
 #include <vector>
 
 #include "pw_async/heap_dispatcher.h"
@@ -22,13 +20,13 @@
 
 using bt::testing::FakeController;
 using bt::testing::FakePeer;
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 
 const DeviceAddress kLocalAddress(DeviceAddress::Type::kLEPublic, {0xFF});
 const DeviceAddress kRandomAddress(DeviceAddress::Type::kLERandom, {0xFE});
 const DeviceAddress kTestAddress(DeviceAddress::Type::kLEPublic, {1});
 const hci_spec::LEPreferredConnectionParameters kTestParams(1, 1, 1, 1);
-constexpr zx::duration kConnectTimeout = zx::sec(10);
+constexpr pw::chrono::SystemClock::duration kConnectTimeout = std::chrono::seconds(10);
 constexpr pw::chrono::SystemClock::duration kPwConnectTimeout = std::chrono::seconds(10);
 
 class LowEnergyConnectorTest : public TestingBase {
@@ -48,7 +46,7 @@
 
     fake_address_delegate_.set_local_address(kLocalAddress);
     connector_ = std::make_unique<LowEnergyConnector>(
-        transport()->GetWeakPtr(), &fake_address_delegate_, pw_dispatcher(),
+        transport()->GetWeakPtr(), &fake_address_delegate_, dispatcher(),
         fit::bind_member<&LowEnergyConnectorTest::OnIncomingConnectionCreated>(this));
 
     test_device()->set_connection_state_callback(
@@ -88,12 +86,12 @@
     request_canceled = canceled;
   }
 
-  FakeLocalAddressDelegate fake_address_delegate_{pw_dispatcher()};
+  FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};
   std::unique_ptr<LowEnergyConnector> connector_;
 
   // Incoming connections.
   std::vector<std::unique_ptr<LowEnergyConnection>> in_connections_;
-  pw::async::HeapDispatcher heap_dispatcher_{pw_dispatcher()};
+  pw::async::HeapDispatcher heap_dispatcher_{dispatcher()};
 
   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyConnectorTest);
 };
@@ -101,7 +99,7 @@
 using HCI_LowEnergyConnectorTest = LowEnergyConnectorTest;
 
 TEST_F(LowEnergyConnectorTest, CreateConnection) {
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   test_device()->AddPeer(std::move(fake_peer));
 
   EXPECT_FALSE(connector()->request_pending());
@@ -129,7 +127,7 @@
       hci_spec::defaults::kLEScanWindow, kTestParams, callback, kPwConnectTimeout);
   EXPECT_FALSE(ret);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(connector()->request_pending());
   EXPECT_FALSE(connector()->pending_peer_address());
@@ -146,7 +144,7 @@
 
 // Controller reports error from HCI Command Status event.
 TEST_F(LowEnergyConnectorTest, CreateConnectionStatusError) {
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   fake_peer->set_connect_status(pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED);
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -168,7 +166,7 @@
   EXPECT_TRUE(ret);
   EXPECT_TRUE(connector()->request_pending());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(connector()->request_pending());
   EXPECT_TRUE(callback_called);
@@ -179,7 +177,7 @@
 
 // Controller reports error from HCI LE Connection Complete event
 TEST_F(LowEnergyConnectorTest, CreateConnectionEventError) {
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   fake_peer->set_connect_response(pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_SECURITY);
   test_device()->AddPeer(std::move(fake_peer));
 
@@ -201,7 +199,7 @@
   EXPECT_TRUE(ret);
   EXPECT_TRUE(connector()->request_pending());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(connector()->request_pending());
   EXPECT_TRUE(callback_called);
@@ -212,7 +210,7 @@
 
 // Controller reports error from HCI LE Connection Complete event
 TEST_F(LowEnergyConnectorTest, Cancel) {
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
 
   // Make sure the pending connect remains pending.
   fake_peer->set_force_pending_connect(true);
@@ -243,7 +241,7 @@
   // before.
   EXPECT_FALSE(connector()->timeout_posted());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(connector()->timeout_posted());
   EXPECT_FALSE(connector()->request_pending());
@@ -272,7 +270,7 @@
 
   test_device()->SendCommandChannelPacket(packet.data());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(1u, in_connections().size());
 
@@ -289,7 +287,7 @@
   EXPECT_TRUE(in_connections().empty());
   EXPECT_FALSE(connector()->request_pending());
 
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   test_device()->AddPeer(std::move(fake_peer));
 
   Result<> status = fit::ok();
@@ -326,7 +324,7 @@
     test_device()->SendCommandChannelPacket(packet.data());
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(fit::ok(), status);
   EXPECT_EQ(1u, callback_count);
@@ -365,7 +363,7 @@
   EXPECT_FALSE(request_canceled);
 
   // Make the connection attempt time out.
-  RunLoopFor(kConnectTimeout);
+  RunFor(kConnectTimeout);
 
   EXPECT_FALSE(connector()->request_pending());
   EXPECT_TRUE(callback_called);
@@ -376,7 +374,7 @@
 }
 
 TEST_F(LowEnergyConnectorTest, SendRequestAndDelete) {
-  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
 
   // Make sure the pending connect remains pending.
   fake_peer->set_force_pending_connect(true);
@@ -389,7 +387,7 @@
   EXPECT_TRUE(connector()->request_pending());
 
   DeleteConnector();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(request_canceled);
   EXPECT_TRUE(in_connections().empty());
@@ -398,7 +396,7 @@
 TEST_F(LowEnergyConnectorTest, AllowsRandomAddressChange) {
   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
 
-  auto fake_device = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_device = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   test_device()->AddPeer(std::move(fake_device));
 
   // Address change should not be allowed while the procedure is pending.
@@ -408,7 +406,7 @@
   EXPECT_TRUE(connector()->request_pending());
   EXPECT_FALSE(connector()->AllowsRandomAddressChange());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
 }
 
@@ -433,18 +431,18 @@
   // After the loop runs the request should remain pending (since we added no
   // fake device, the request would eventually timeout) but address change
   // should no longer be allowed.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(connector()->request_pending());
   EXPECT_FALSE(connector()->AllowsRandomAddressChange());
 }
 
 TEST_F(LowEnergyConnectorTest, ConnectUsingPublicAddress) {
-  auto fake_device = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_device = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   test_device()->AddPeer(std::move(fake_device));
   connector()->CreateConnection(
       /*use_accept_list=*/false, kTestAddress, hci_spec::defaults::kLEScanInterval,
       hci_spec::defaults::kLEScanWindow, kTestParams, [](auto, auto) {}, kPwConnectTimeout);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(test_device()->le_connect_params());
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
             test_device()->le_connect_params()->own_address_type);
@@ -453,12 +451,12 @@
 TEST_F(LowEnergyConnectorTest, ConnectUsingRandomAddress) {
   fake_address_delegate()->set_local_address(kRandomAddress);
 
-  auto fake_device = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_device = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   test_device()->AddPeer(std::move(fake_device));
   connector()->CreateConnection(
       /*use_accept_list=*/false, kTestAddress, hci_spec::defaults::kLEScanInterval,
       hci_spec::defaults::kLEScanWindow, kTestParams, [](auto, auto) {}, kPwConnectTimeout);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(test_device()->le_connect_params());
   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
             test_device()->le_connect_params()->own_address_type);
@@ -481,7 +479,7 @@
   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
 
   connector()->Cancel();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(connector()->request_pending());
   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
 
@@ -501,12 +499,12 @@
 
   connector()->UseLocalIdentityAddress();
 
-  auto fake_device = std::make_unique<FakePeer>(kTestAddress, pw_dispatcher(), true, true);
+  auto fake_device = std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
   test_device()->AddPeer(std::move(fake_device));
   connector()->CreateConnection(
       /*use_accept_list=*/false, kTestAddress, hci_spec::defaults::kLEScanInterval,
       hci_spec::defaults::kLEScanWindow, kTestParams, [](auto, auto) {}, kPwConnectTimeout);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(test_device()->le_connect_params());
 
   // The public address should have been used.
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/low_energy_multiple_advertising_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/low_energy_multiple_advertising_unittest.cc
index a79baf9..19c4303 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/low_energy_multiple_advertising_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/low_energy_multiple_advertising_unittest.cc
@@ -15,7 +15,7 @@
 namespace {
 
 using bt::testing::FakeController;
-using TestingBase = bt::testing::ControllerTest<FakeController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
 using AdvertisingOptions = LowEnergyAdvertiser::AdvertisingOptions;
 using LEAdvertisingState = FakeController::LEAdvertisingState;
 
@@ -129,7 +129,7 @@
     this->advertiser()->StartAdvertising(DeviceAddress(DeviceAddress::Type::kLEPublic, {i}), ad,
                                          scan_data, options, /*connect_callback=*/nullptr,
                                          this->MakeExpectSuccessCallback());
-    this->RunLoopUntilIdle();
+    this->RunUntilIdle();
   }
 
   ASSERT_TRUE(this->GetLastStatus());
@@ -140,7 +140,7 @@
       DeviceAddress(DeviceAddress::Type::kLEPublic, {hci_spec::kAdvertisingHandleMax + 1}), ad,
       scan_data, options, /*connect_callback=*/nullptr, this->MakeExpectErrorCallback());
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   ASSERT_TRUE(this->GetLastStatus());
   EXPECT_TRUE(this->advertiser()->IsAdvertising());
   EXPECT_EQ(this->max_advertisements(), this->advertiser()->NumAdvertisements());
@@ -158,7 +158,7 @@
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, public_options,
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   std::optional<hci_spec::AdvertisingHandle> handle_public_addr =
       this->advertiser()->LastUsedHandleForTesting();
   ASSERT_TRUE(handle_public_addr);
@@ -171,7 +171,7 @@
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, random_options,
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   std::optional<hci_spec::AdvertisingHandle> handle_random_addr =
       this->advertiser()->LastUsedHandleForTesting();
   ASSERT_TRUE(handle_random_addr);
@@ -209,7 +209,7 @@
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, public_options,
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   std::optional<hci_spec::AdvertisingHandle> handle_public_addr =
       this->advertiser()->LastUsedHandleForTesting();
   ASSERT_TRUE(handle_public_addr);
@@ -222,7 +222,7 @@
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, random_options,
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   std::optional<hci_spec::AdvertisingHandle> handle_random_addr =
       this->advertiser()->LastUsedHandleForTesting();
   ASSERT_TRUE(handle_random_addr);
@@ -235,7 +235,7 @@
 
   // Stop advertising
   this->advertiser()->StopAdvertising();
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   // Check that advertiser and controller both report not advertising
   EXPECT_EQ(0u, this->advertiser()->NumAdvertisements());
@@ -275,7 +275,7 @@
   this->advertiser()->StartAdvertising(kPublicAddress, ad, scan_data, public_options,
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   std::optional<hci_spec::AdvertisingHandle> handle_public_addr =
       this->advertiser()->LastUsedHandleForTesting();
   ASSERT_TRUE(handle_public_addr);
@@ -288,7 +288,7 @@
   this->advertiser()->StartAdvertising(kRandomAddress, ad, scan_data, random_options,
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   std::optional<hci_spec::AdvertisingHandle> handle_random_addr =
       this->advertiser()->LastUsedHandleForTesting();
   ASSERT_TRUE(handle_random_addr);
@@ -301,7 +301,7 @@
 
   // Stop advertising the random address
   this->advertiser()->StopAdvertising(kRandomAddress);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   // Check that advertiser and controller both report the same advertising state
   EXPECT_TRUE(this->advertiser()->IsAdvertising());
@@ -332,7 +332,7 @@
 
   // stop advertising the public address
   this->advertiser()->StopAdvertising(kPublicAddress);
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
 
   {
     const LEAdvertisingState& public_addr_state =
@@ -375,7 +375,7 @@
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->advertiser()->IsAdvertising());
   EXPECT_EQ(2u, this->advertiser()->NumAdvertisements());
   EXPECT_TRUE(this->advertiser()->IsAdvertising(kPublicAddress));
@@ -384,7 +384,7 @@
   this->advertiser()->StopAdvertising(kPublicAddress);
   this->advertiser()->StopAdvertising(kRandomAddress);
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_FALSE(this->advertiser()->IsAdvertising());
   EXPECT_EQ(0u, this->advertiser()->NumAdvertisements());
   EXPECT_FALSE(this->advertiser()->IsAdvertising(kPublicAddress));
@@ -407,7 +407,7 @@
                                        /*connect_callback=*/nullptr,
                                        this->MakeExpectSuccessCallback());
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->advertiser()->IsAdvertising());
   EXPECT_EQ(1u, this->advertiser()->NumAdvertisements());
   EXPECT_TRUE(this->advertiser()->IsAdvertising(kPublicAddress));
@@ -425,7 +425,7 @@
                                        this->MakeExpectSuccessCallback());
   this->advertiser()->StopAdvertising(kPublicAddress);
 
-  this->RunLoopUntilIdle();
+  this->RunUntilIdle();
   EXPECT_TRUE(this->GetLastStatus());
 
   std::optional<hci_spec::AdvertisingHandle> handle =
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/sequential_command_runner_unittest.cc b/src/connectivity/bluetooth/core/bt-host/hci/sequential_command_runner_unittest.cc
index 9577902..9db4808 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/sequential_command_runner_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/hci/sequential_command_runner_unittest.cc
@@ -19,7 +19,7 @@
 
 using bt::testing::CommandTransaction;
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 class SequentialCommandRunnerTest : public TestingBase {
  public:
@@ -101,7 +101,7 @@
 
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(1, cb_called);
@@ -119,7 +119,7 @@
 
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(1, cb_called);
@@ -138,7 +138,7 @@
 
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(2, cb_called);
@@ -155,7 +155,7 @@
 
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(2, cb_called);
@@ -173,7 +173,7 @@
 
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(0, cb_called);
@@ -233,7 +233,7 @@
   EXPECT_FALSE(cmd_runner.IsReady());
   cmd_runner.Cancel();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(0, cb_called);
@@ -260,7 +260,7 @@
   EXPECT_FALSE(cmd_runner.IsReady());
 
   // |status_cb| is expected to get called with kCanceled
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
 
@@ -297,7 +297,7 @@
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
@@ -388,14 +388,14 @@
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // The first two commands should have been sent but no responses are back yet.
   EXPECT_EQ(0, cb_called);
 
   // It should not matter if they get answered in opposite order.
   test_device()->SendCommandChannelPacket(command2_cmpl_success_bytes);
   test_device()->SendCommandChannelPacket(command_cmpl_success_bytes);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(5, cb_called);
   EXPECT_EQ(fit::ok(), status);
@@ -422,7 +422,7 @@
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // The first two commands should have been sent but no responses are back yet.
   EXPECT_EQ(0, cb_0_called);
   EXPECT_EQ(0, cb_1_called);
@@ -430,7 +430,7 @@
 
   test_device()->SendCommandChannelPacket(command_status_error_bytes);
   test_device()->SendCommandChannelPacket(command2_cmpl_success_bytes);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Only the first command's callback should be called, as further callbacks will be canceled due
   // to the error status.
@@ -475,7 +475,7 @@
 
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(2, cb_called);
@@ -532,7 +532,7 @@
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Command 2 should wait on command 0 & command 1 complete events.
   EXPECT_FALSE(cmd_runner.IsReady());
   EXPECT_TRUE(cmd_runner.HasQueuedCommands());
@@ -541,7 +541,7 @@
   test_device()->SendCommandChannelPacket(command0_cmpl_event);
 
   EXPECT_CMD_PACKET_OUT(test_device(), command2, &command2_status_event, &command2_cmpl_event);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(3, cb_called);
@@ -588,7 +588,7 @@
 
   cmd_runner.RunCommands(status_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(cmd_runner.IsReady());
   // Command 1 is "sent" but queued in CommandChannel.
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
@@ -596,7 +596,7 @@
   test_device()->SendCommandChannelPacket(command0_cmpl_event);
 
   EXPECT_CMD_PACKET_OUT(test_device(), command1, &command1_status_event, &command1_cmpl_event);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_EQ(2, cb_called);
   EXPECT_EQ(1, status_cb_called);
@@ -650,7 +650,7 @@
   cmd_runner->RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner->IsReady());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(cmd_runner.has_value());
   EXPECT_EQ(1, cb_called);
   EXPECT_EQ(0, status_cb_called);
@@ -679,7 +679,7 @@
   EXPECT_FALSE(cmd_runner->IsReady());
   cmd_runner->Cancel();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(cmd_runner);
   EXPECT_EQ(0, cb_called);
   EXPECT_EQ(1, status_cb_called);
@@ -741,7 +741,7 @@
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(1, name_cb_called);
@@ -781,7 +781,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), command_bytes, &command_cmpl_success_bytes);
   cmd_runner.RunCommands(status_cb);
   EXPECT_FALSE(cmd_runner.IsReady());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(cmd_runner.IsReady());
   EXPECT_FALSE(cmd_runner.HasQueuedCommands());
   EXPECT_EQ(1, cb_called);
diff --git a/src/connectivity/bluetooth/core/bt-host/l2cap/a2dp_offload_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/l2cap/a2dp_offload_manager_unittest.cc
index 6201bd85..02ad20b 100644
--- a/src/connectivity/bluetooth/core/bt-host/l2cap/a2dp_offload_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/l2cap/a2dp_offload_manager_unittest.cc
@@ -7,7 +7,8 @@
 #include <memory>
 
 #include "src/connectivity/bluetooth/core/bt-host/common/host_error.h"
-#include "src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_mock_controller_test_fixture.h"
+#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
+#include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/test_packets.h"
 
 namespace bt::l2cap {
@@ -64,7 +65,7 @@
   return config;
 }
 
-using TestingBase = ControllerTest<MockController>;
+using TestingBase = FakeDispatcherControllerTest<MockController>;
 
 class A2dpOffloadTest : public TestingBase {
  public:
@@ -106,7 +107,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
         start_result = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -135,7 +136,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::INVALID_HCI_COMMAND_PARAMETERS), res);
         start_result = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
   EXPECT_TRUE(start_result->is_error());
@@ -156,7 +157,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
         start_result = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -169,7 +170,7 @@
     EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
     stop_result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(stop_result.has_value());
@@ -191,7 +192,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
         start_result = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -203,7 +204,7 @@
                                     EXPECT_EQ(ToResult(HostError::kInProgress), res);
                                     start_result = res;
                                   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   ASSERT_TRUE(start_result.has_value());
   EXPECT_TRUE(start_result->is_error());
@@ -231,7 +232,7 @@
                                     EXPECT_EQ(ToResult(HostError::kInProgress), res);
                                     start_result = res;
                                   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -253,7 +254,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
         start_result = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -274,7 +275,7 @@
                                     EXPECT_EQ(ToResult(HostError::kInProgress), res);
                                     start_result = res;
                                   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -307,7 +308,7 @@
     EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
     stop_result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -331,7 +332,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
         start_result = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -350,7 +351,7 @@
     EXPECT_EQ(ToResult(HostError::kInProgress), res);
     stop_result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(stop_result.has_value());
@@ -363,7 +364,7 @@
     EXPECT_EQ(ToResult(HostError::kFailed), res);
     stop_result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   ASSERT_TRUE(stop_result.has_value());
   EXPECT_TRUE(stop_result->is_error());
@@ -384,7 +385,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
         start_result_0 = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result_0.has_value());
@@ -396,7 +397,7 @@
                                     EXPECT_EQ(ToResult(HostError::kInProgress), res);
                                     start_result_1 = res;
                                   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_FALSE(offload_mgr()->IsChannelOffloaded(kLocalId + 1, kTestHandle1));
   ASSERT_TRUE(start_result_1.has_value());
@@ -418,7 +419,7 @@
         EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
         start_result = res;
       });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(start_result.has_value());
@@ -429,7 +430,7 @@
     EXPECT_EQ(ToResult(HostError::kFailed), res);
     stop_result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(offload_mgr()->IsChannelOffloaded(kLocalId, kTestHandle1));
   ASSERT_TRUE(stop_result.has_value());
   EXPECT_TRUE(stop_result->is_error());
diff --git a/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_mock_controller_test_fixture.h b/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_mock_controller_test_fixture.h
index a0f2a4d..a8a30e2 100644
--- a/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_mock_controller_test_fixture.h
+++ b/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_mock_controller_test_fixture.h
@@ -13,10 +13,11 @@
 
 namespace bt::l2cap {
 
+using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+
 // ChannelManager test fixture that uses a real AclDataChannel and uses MockController
 // for HCI packet expectations.
-class ChannelManagerMockControllerTest
-    : public bt::testing::ControllerTest<bt::testing::MockController> {
+class ChannelManagerMockControllerTest : public TestingBase {
  public:
   static constexpr size_t kMaxDataPacketLength = 64;
   // High enough so that most tests don't need to worry about HCI flow control.
@@ -31,42 +32,39 @@
   static void DoNothing() {}
   static void NopRxCallback(ByteBufferPtr) {}
 
-  ChannelManagerMockControllerTest() = default;
-  ~ChannelManagerMockControllerTest() override = default;
+  ChannelManagerMockControllerTest(pw::async::Dispatcher& dispatcher)
+      : TestingBase(dispatcher), dispatcher_(dispatcher) {}
+  ~ChannelManagerMockControllerTest() = default;
 
  protected:
-  void SetUp() override {
-    bt::testing::ControllerTest<bt::testing::MockController>::SetUp();
+  void Initialize() {
+    TestingBase::Initialize(pw::bluetooth::Controller::FeaturesBits::kHciSco);
     const auto bredr_buffer_info = hci::DataBufferInfo(kMaxDataPacketLength, kBufferMaxNumPackets);
     InitializeACLDataChannel(bredr_buffer_info);
 
     // TODO(63074): Remove assumptions about channel ordering so we can turn random ids on.
     channel_manager_ =
         ChannelManager::Create(transport()->acl_data_channel(), transport()->command_channel(),
-                               /*random_channel_ids=*/false, pw_dispatcher());
+                               /*random_channel_ids=*/false, dispatcher_);
 
     next_command_id_ = 1;
   }
 
-  void SetUp(size_t max_acl_payload_size, size_t max_le_payload_size,
-             size_t max_acl_packets = kBufferMaxNumPackets,
-             size_t max_le_packets = kBufferMaxNumPackets) {
-    bt::testing::ControllerTest<bt::testing::MockController>::SetUp();
+  void Initialize(size_t max_acl_payload_size, size_t max_le_payload_size, size_t max_acl_packets,
+                  size_t max_le_packets) {
+    TestingBase::Initialize(pw::bluetooth::Controller::FeaturesBits::kHciSco);
 
     InitializeACLDataChannel(hci::DataBufferInfo(max_acl_payload_size, max_acl_packets),
                              hci::DataBufferInfo(max_le_payload_size, max_le_packets));
 
     channel_manager_ =
         ChannelManager::Create(transport()->acl_data_channel(), transport()->command_channel(),
-                               /*random_channel_ids=*/false, pw_dispatcher());
+                               /*random_channel_ids=*/false, dispatcher_);
 
     next_command_id_ = 1;
   }
 
-  void TearDown() override {
-    channel_manager_ = nullptr;
-    bt::testing::ControllerTest<bt::testing::MockController>::TearDown();
-  }
+  void DeleteChannelManager() { channel_manager_ = nullptr; }
 
   l2cap::CommandId NextCommandId() { return next_command_id_++; }
 
@@ -175,10 +173,33 @@
  private:
   std::unique_ptr<ChannelManager> channel_manager_;
   l2cap::CommandId next_command_id_;
+  pw::async::Dispatcher& dispatcher_;
 
   BT_DISALLOW_COPY_ASSIGN_AND_MOVE(ChannelManagerMockControllerTest);
 };
 
+class FakeDispatcherChannelManagerMockControllerTest
+    : public pw::async::test::FakeDispatcherFixture,
+      public ChannelManagerMockControllerTest {
+ protected:
+  FakeDispatcherChannelManagerMockControllerTest()
+      : ChannelManagerMockControllerTest(dispatcher()) {}
+
+  void SetUp() override { Initialize(); }
+
+  void SetUp(size_t max_acl_payload_size, size_t max_le_payload_size,
+             size_t max_acl_packets = kBufferMaxNumPackets,
+             size_t max_le_packets = kBufferMaxNumPackets) {
+    Initialize(max_acl_payload_size, max_le_payload_size, max_acl_packets, max_le_packets);
+  }
+
+  void TearDown() override {
+    DeleteChannelManager();
+    RunUntilIdle();
+    DeleteTransport();
+  }
+};
+
 }  // namespace bt::l2cap
 
 #endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_MANAGER_MOCK_CONTROLLER_TEST_FIXTURE_H_
diff --git a/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_unittest.cc
index 4dbef09..4ef29d4 100644
--- a/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_unittest.cc
@@ -273,7 +273,7 @@
   return config;
 }
 
-using TestingBase = ControllerTest<MockController>;
+using TestingBase = FakeDispatcherControllerTest<MockController>;
 
 // ChannelManager test fixture that uses MockAclDataChannel to inject inbound data and test outbound
 // data. Unexpected outbound packets will cause test failures.
@@ -296,7 +296,7 @@
 
     // TODO(63074): Make these tests not depend on strict channel ID ordering.
     chanmgr_ = ChannelManager::Create(&acl_data_channel_, transport()->command_channel(),
-                                      /*random_channel_ids=*/false, pw_dispatcher());
+                                      /*random_channel_ids=*/false, dispatcher());
 
     packet_rx_handler_ = [this](std::unique_ptr<hci::ACLDataPacket> packet) {
       acl_data_channel_.ReceivePacket(std::move(packet));
@@ -414,7 +414,7 @@
 
     ActivateOutboundChannel(kTestPsm, channel_params, std::move(channel_cb), kTestHandle1,
                             std::move(closed_cb));
-    RunLoopUntilIdle();
+    RunUntilIdle();
 
     ReceiveAclDataPacket(testing::AclConnectionRsp(conn_req_id, kTestHandle1, local_id, remote_id));
     ReceiveAclDataPacket(
@@ -422,7 +422,7 @@
     ReceiveAclDataPacket(
         testing::AclConfigRsp(config_req_id, kTestHandle1, local_id, kChannelParams));
 
-    RunLoopUntilIdle();
+    RunUntilIdle();
     EXPECT_TRUE(AllExpectedPacketsSent());
   }
 
@@ -532,7 +532,7 @@
 
 // ChannelManager test fixture that uses a real AclDataChannel and uses MockController for HCI
 // packet expectations
-using ChannelManagerRealAclChannelTest = ChannelManagerMockControllerTest;
+using ChannelManagerRealAclChannelTest = FakeDispatcherChannelManagerMockControllerTest;
 
 TEST_F(ChannelManagerRealAclChannelTest, OpenFixedChannelErrorNoConn) {
   // This should fail as the ChannelManager has no entry for |kTestHandle1|.
@@ -550,7 +550,7 @@
 
   // ACL-U link
   QueueAclConnection(kTestHandle2);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   // This should fail as kSMPChannelId is ACL-U only.
@@ -562,7 +562,7 @@
 
 TEST_F(ChannelManagerRealAclChannelTest, DeactivateDynamicChannelInvalidatesChannelPointer) {
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   Channel::WeakPtr channel;
@@ -572,7 +572,7 @@
   };
   QueueOutboundL2capConnection(kTestHandle1, kTestPsm, kLocalId, kRemoteId, std::move(chan_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   EXPECT_TRUE(channel.is_alive());
   ASSERT_TRUE(channel->Activate(NopRxCallback, DoNothing));
@@ -581,7 +581,7 @@
                                            NextCommandId(), kTestHandle1, kLocalId, kRemoteId));
 
   channel->Deactivate();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_FALSE(channel.is_alive());
 }
 
@@ -607,7 +607,7 @@
   // This should notify the channel.
   chanmgr()->RemoveConnection(kTestHandle1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // |closed_cb| will be called synchronously since it was registered using the current thread's
   // task runner.
@@ -628,7 +628,7 @@
   fixed_channels.att->Deactivate();
   chanmgr()->RemoveConnection(kTestHandle1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(closed_called);
 }
@@ -656,7 +656,7 @@
   fixed_channels.smp->Deactivate();
   chanmgr()->RemoveConnection(kTestHandle1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(att_closed);
   EXPECT_FALSE(smp_closed);
@@ -682,7 +682,7 @@
                          0x02, 0x00, LowerBits(kATTChannelId), UpperBits(kATTChannelId), 'h', 'i'));
 
   EXPECT_TRUE(chan->Send(NewBuffer('h', 'i')));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   chanmgr()->RemoveConnection(kTestHandle1);
@@ -690,7 +690,7 @@
   // The L2CAP channel should have been notified of closure immediately.
   EXPECT_TRUE(closed_called);
   EXPECT_FALSE(chan.is_alive());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // Tests that destroying the ChannelManager cleanly shuts down all channels.
@@ -714,7 +714,7 @@
 
   // Send a packet. This should be processed immediately.
   EXPECT_TRUE(chan->Send(NewBuffer('h', 'i')));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   TearDown();
@@ -722,7 +722,7 @@
   EXPECT_TRUE(closed_called);
   EXPECT_FALSE(chan.is_alive());
   // No outbound packet expectations were set, so this test will fail if it sends any data.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerRealAclChannelTest, DeactivateDoesNotCrashOrHang) {
@@ -735,18 +735,18 @@
   fixed_channels.att->Deactivate();
 
   // Loop until the clean up task runs.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerRealAclChannelTest, CallingDeactivateFromClosedCallbackDoesNotCrashOrHang) {
   BrEdrFixedChannels fixed_channels = QueueAclConnection(kTestHandle1).fixed_channels;
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   auto chan = std::move(fixed_channels.smp);
   chan->Activate(NopRxCallback, [chan] { chan->Deactivate(); });
   chanmgr()->RemoveConnection(kTestHandle1);  // Triggers ClosedCallback.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, ReceiveData) {
@@ -799,7 +799,7 @@
       // L2CAP B-frame (empty)
       0x00, 0x00, 0x06, 0x00));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(smp_cb_called);
   ASSERT_EQ(2u, sdus.size());
@@ -842,14 +842,14 @@
   Channel::WeakPtr att_chan, smp_chan;
 
   // Run the loop so all packets are received.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   LEFixedChannels fixed_channels =
       RegisterLE(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
   ASSERT_TRUE(fixed_channels.att->Activate(att_rx_cb, DoNothing));
   ASSERT_TRUE(fixed_channels.smp->Activate(smp_rx_cb, DoNothing));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(smp_cb_called);
   EXPECT_EQ(kPacketCount, packet_count);
 }
@@ -860,7 +860,7 @@
 
   // Register an ACL connection because LE connections create fixed channels immediately.
   QueueAclConnection(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   StaticByteBuffer<255> buffer;
 
@@ -874,12 +874,12 @@
         0x00, 0x00, LowerBits(kConnectionlessChannelId), UpperBits(kConnectionlessChannelId)));
   }
   // Run the loop so all packets are received.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto chan =
       ActivateNewFixedChannel(kConnectionlessChannelId, kTestHandle1, DoNothing, std::move(rx_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(kPacketCount, packet_count);
 }
 
@@ -921,12 +921,12 @@
       0x00, 0x00, LowerBits(kLESMPChannelId), UpperBits(kLESMPChannelId)));
 
   // Run the loop so all packets are received.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   fixed_channels.att->Activate(att_rx_cb, DoNothing);
   fixed_channels.smp->Activate(smp_rx_cb, DoNothing);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(smp_cb_called);
   EXPECT_EQ(kPacketCount, packet_count);
@@ -974,7 +974,7 @@
   // already routed the data to the Channels.
   EXPECT_EQ(1, att_rx_cb_count);
   EXPECT_EQ(1, smp_rx_cb_count);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1, att_rx_cb_count);
   EXPECT_EQ(1, smp_rx_cb_count);
 
@@ -1004,7 +1004,7 @@
                                            0x04, 0x00, 0x04, 0x00, 'T', 'e', 's', 't'));
 
   EXPECT_TRUE(fixed_channels.att->Send(NewBuffer('T', 'e', 's', 't')));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // Tests that fragmentation of BR/EDR packets uses the BR/EDR buffer size
@@ -1076,7 +1076,7 @@
   // Due to the BR/EDR buffer size, this should be sent over a 6-byte then a 5-byte fragment.
   EXPECT_TRUE(sm_chan->Send(NewBuffer('G', 'o', 'o', 'd', 'b', 'y', 'e')));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerRealAclChannelTest, SendBREDRFragmentedSDUsOverTwoDynamicChannels) {
@@ -1096,7 +1096,7 @@
   constexpr size_t kChannelCreationPacketCount = 3;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   l2cap::Channel::WeakPtr channel0;
@@ -1106,7 +1106,7 @@
   };
   QueueOutboundL2capConnection(kTestHandle1, kPSM0, kLocalId0, kRemoteId0, std::move(chan_cb0));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   ASSERT_TRUE(channel0.is_alive());
   ASSERT_TRUE(channel0->Activate(NopRxCallback, DoNothing));
@@ -1121,7 +1121,7 @@
   // Free up the buffer space from packets sent while creating |channel0|
   test_device()->SendCommandChannelPacket(
       NumberOfCompletedPacketsPacket(kTestHandle1, kChannelCreationPacketCount));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   EXPECT_TRUE(channel1.is_alive());
@@ -1130,7 +1130,7 @@
   // Free up the buffer space from packets sent while creating |channel1|
   test_device()->SendCommandChannelPacket(NumberOfCompletedPacketsPacket(
       kTestHandle1, kConnectionCreationPacketCount + kChannelCreationPacketCount));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Queue size should be equal to or larger than |num_queued_packets| to ensure that all packets
   // get queued and sent
@@ -1163,14 +1163,14 @@
     // Due to the BR/EDR buffer size, this should be sent over a 18-byte then a 6-byte fragment.
     EXPECT_TRUE(channel->Send(NewBuffer('G', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o',
                                         'o', 'o', 'o', 'o', 'd', 'b', 'y', 'e')));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_FALSE(test_device()->AllExpectedDataPacketsSent());
 
   // Notify the processed packets with a Number Of Completed Packet HCI event
   // This should cause the remaining 6 fragmented packets to be sent
   test_device()->SendCommandChannelPacket(NumberOfCompletedPacketsPacket(kTestHandle1, 6));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 }
 
@@ -1201,7 +1201,7 @@
   // 4-byte fragment.
   EXPECT_TRUE(fixed_channels.att->Send(NewBuffer('H', 'e', 'l', 'l', 'o')));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, ACLChannelSignalLinkError) {
@@ -1211,7 +1211,7 @@
       QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL, link_error_cb);
   acl.fixed_channels.smp->Activate(NopRxCallback, DoNothing);
   acl.fixed_channels.smp->SignalLinkError();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(link_error);
 }
 
@@ -1225,7 +1225,7 @@
   fixed_channels.att->Activate(NopRxCallback, DoNothing);
   fixed_channels.att->SignalLinkError();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(link_error);
 }
@@ -1263,7 +1263,7 @@
   ReceiveAclDataPacket(InboundConfigurationRequest(kPeerConfigRequestId));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
   EXPECT_TRUE(AllExpectedPacketsSent());
 
   // The channel on kTestHandle1 should be open.
@@ -1281,7 +1281,7 @@
   ASSERT_FALSE(link_error);
   acl.fixed_channels.smp->SignalLinkError();
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   // link_error_cb is not called until Disconnection Response is received for each dynamic channel
   EXPECT_FALSE(link_error);
@@ -1295,7 +1295,7 @@
       testing::AclDisconnectionRsp(disconn_req_id, kTestHandle1, kLocalId, kRemoteId);
   ReceiveAclDataPacket(disconnection_rsp);
 
-  RETURN_IF_FATAL(RunLoopUntilIdle());
+  RETURN_IF_FATAL(RunUntilIdle());
 
   EXPECT_TRUE(link_error);
 }
@@ -1336,12 +1336,12 @@
       0x80, 0x0C));
   // clang-format on
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, ACLOutboundDynamicChannelLocalDisconnect) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   Channel::WeakPtr channel;
   auto channel_cb = [&channel](l2cap::Channel::WeakPtr activated_chan) {
@@ -1359,13 +1359,13 @@
 
   ActivateOutboundChannel(kTestPsm, kChannelParams, std::move(channel_cb), kTestHandle1,
                           std::move(closed_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ReceiveAclDataPacket(InboundConnectionResponse(conn_req_id));
   ReceiveAclDataPacket(InboundConfigurationRequest(kPeerConfigRequestId));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(AllExpectedPacketsSent());
   ASSERT_TRUE(channel.is_alive());
@@ -1386,7 +1386,7 @@
 
   EXPECT_TRUE(channel->Send(NewBuffer('T', 'e', 's', 't')));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
 
   const auto disconn_req_id = NextCommandId();
@@ -1395,7 +1395,7 @@
   // Explicit deactivation should not res in |closed_cb| being called.
   channel->Deactivate();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
 
   // Ensure callback is not called after the channel has disconnected
@@ -1413,14 +1413,14 @@
       LowerBits(kRemoteId), UpperBits(kRemoteId), LowerBits(kLocalId), UpperBits(kLocalId)));
   // clang-format on
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(closed_cb_called);
 }
 
 TEST_F(ChannelManagerRealAclChannelTest, ACLOutboundDynamicChannelRemoteDisconnect) {
   QueueAclConnection(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   Channel::WeakPtr channel;
@@ -1430,7 +1430,7 @@
   };
   QueueOutboundL2capConnection(kTestHandle1, kTestPsm, kLocalId, kRemoteId, std::move(chan_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   EXPECT_TRUE(channel.is_alive());
   bool dynamic_channel_closed = false;
@@ -1449,7 +1449,7 @@
       // L2CAP B-frame: (length: 4, channel-id)
       0x04, 0x00, LowerBits(kLocalId), UpperBits(kLocalId), 'T', 'e', 's', 't'));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_ACL_PACKET_OUT(test_device(), OutboundDisconnectionResponse(7));
 
@@ -1472,7 +1472,7 @@
       // L2CAP B-frame: (length: 1, channel-id: 0x0040)
       0x01, 0x00, 0x40, 0x00, '!'));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(dynamic_channel_closed);
 }
@@ -1505,7 +1505,7 @@
 
   ActivateOutboundChannel(kTestPsm, kChannelParams, std::move(channel_cb), kTestHandle1,
                           std::move(closed_cb), std::move(data_rx_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ReceiveAclDataPacket(InboundConnectionResponse(conn_req_id));
 
@@ -1522,7 +1522,7 @@
   ReceiveAclDataPacket(InboundConfigurationRequest(kPeerConfigRequestId));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(channel.is_alive());
@@ -1542,7 +1542,7 @@
       LowerBits(kLocalId), UpperBits(kLocalId), LowerBits(kRemoteId), UpperBits(kRemoteId)));
   // clang-format on
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, ACLOutboundDynamicChannelRemoteRefused) {
@@ -1572,7 +1572,7 @@
       0x04, 0x00, 0x00, 0x00));
   // clang-format on
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(channel_cb_called);
 }
@@ -1621,7 +1621,7 @@
       LowerBits(kRemoteId), UpperBits(kRemoteId), LowerBits(kLocalId), UpperBits(kLocalId)));
   // clang-format on
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(channel_cb_called);
 }
@@ -1655,7 +1655,7 @@
   ReceiveAclDataPacket(InboundConfigurationRequest(kPeerConfigRequestId));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(AllExpectedPacketsSent());
   ASSERT_TRUE(channel.is_alive());
@@ -1675,7 +1675,7 @@
 
   EXPECT_TRUE(channel->Send(NewBuffer('T', 'e', 's', 't')));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
 
   const auto disconn_req_id = NextCommandId();
@@ -1684,7 +1684,7 @@
   // Explicit deactivation should not res in |closed_cb| being called.
   channel->Deactivate();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
 
   // clang-format off
@@ -1698,7 +1698,7 @@
       LowerBits(kRemoteId), UpperBits(kRemoteId), LowerBits(kLocalId), UpperBits(kLocalId)));
   // clang-format on
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_FALSE(dynamic_channel_closed);
 }
@@ -1734,7 +1734,7 @@
   ASSERT_TRUE(fixed_channels.att->Activate(NopRxCallback, DoNothing));
 
   chanmgr()->RemoveConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(fixed_channels.att.is_alive());
 
   // Assign a new security level.
@@ -1773,7 +1773,7 @@
 
   // Requesting security at or below the current level should succeed without doing anything.
   att->UpgradeSecurity(sm::SecurityLevel::kNoSecurity, status_callback);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0, security_request_count);
   EXPECT_EQ(1, security_status_count);
   EXPECT_EQ(fit::ok(), received_status);
@@ -1781,14 +1781,14 @@
   // Test reporting an error.
   delivered_status = ToResult(HostError::kNotSupported);
   att->UpgradeSecurity(sm::SecurityLevel::kEncrypted, status_callback);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1, security_request_count);
   EXPECT_EQ(2, security_status_count);
   EXPECT_EQ(delivered_status, received_status);
   EXPECT_EQ(sm::SecurityLevel::kEncrypted, last_requested_level);
 
   chanmgr()->RemoveConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(att.is_alive());
   EXPECT_EQ(1, security_request_count);
   EXPECT_EQ(2, security_status_count);
@@ -1820,7 +1820,7 @@
   ReceiveAclDataPacket(InboundConfigurationRequest(kPeerConfigRequestId, kRemoteMtu));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(channel.is_alive());
@@ -1854,7 +1854,7 @@
   ReceiveAclDataPacket(InboundConfigurationRequest(kPeerConfigRequestId, kRemoteMtu));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(channel.is_alive());
   EXPECT_EQ(kRemoteMtu, channel->max_tx_sdu_size());
@@ -1894,7 +1894,7 @@
       InboundConfigurationRequest(kPeerConfigRequestId, kInboundMtu, chan_params.mode));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(channel.is_alive());
@@ -1911,7 +1911,7 @@
                                                        /*is_poll_request=*/true,
                                                        /*is_poll_response=*/false));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
 }
 
@@ -1949,7 +1949,7 @@
       InboundConfigurationRequest(kPeerConfigRequestId, kInboundMtu, chan_params.mode));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(channel.is_alive());
   EXPECT_EQ(*chan_params.max_rx_sdu_size, channel->max_rx_sdu_size());
@@ -1965,7 +1965,7 @@
                                                        /*is_poll_request=*/true,
                                                        /*is_poll_response=*/false));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
 }
 
@@ -1977,7 +1977,7 @@
 
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
   // Since pending connection request packet was cleared, no response should be sent.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest,
@@ -2028,7 +2028,7 @@
   // Handler should check for res and not crash from reading mask or type.
   ReceiveAclDataPacket(testing::AclNotSupportedInformationResponse(
       cmd_ids.fixed_channels_supported_id, kTestHandle1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, ReceiveFixedChannelsInformationResponseWithInvalidResult) {
@@ -2048,7 +2048,7 @@
       // Invalid Result
       0xFF, 0xFF);
   ReceiveAclDataPacket(kPacket);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, ReceiveFixedChannelsInformationResponseWithIncorrectType) {
@@ -2057,7 +2057,7 @@
   // Handler should check type and not attempt to read fixed channel mask.
   ReceiveAclDataPacket(
       testing::AclExtFeaturesInfoRsp(cmd_ids.fixed_channels_supported_id, kTestHandle1, 0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, ReceiveFixedChannelsInformationResponseWithRejectStatus) {
@@ -2066,7 +2066,7 @@
   // Handler should check status and not attempt to read fields.
   ReceiveAclDataPacket(
       testing::AclCommandRejectNotUnderstoodRsp(cmd_ids.fixed_channels_supported_id, kTestHandle1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest,
@@ -2093,7 +2093,7 @@
 
   ReceiveAclDataPacket(testing::AclConnectionParameterUpdateReq(
       kParamReqId, kTestHandle1, kIntervalMin, kIntervalMax, kPeripheralLatency, kTimeoutMult));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(params.has_value());
   EXPECT_EQ(kIntervalMin, params->min_interval());
@@ -2127,7 +2127,7 @@
 
   ReceiveAclDataPacket(testing::AclConnectionParameterUpdateReq(
       kParamReqId, kTestHandle1, kIntervalMin, kIntervalMax, kPeripheralLatency, kTimeoutMult));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_FALSE(params.has_value());
 }
@@ -2180,14 +2180,14 @@
                          kHighPriority);
     ReceiveAclDataPacket(req);
   }
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, RequestConnParamUpdateForUnknownLinkIsNoOp) {
   auto update_cb = [](auto) { ADD_FAILURE(); };
   chanmgr()->RequestConnectionParameterUpdate(
       kTestHandle1, hci_spec::LEPreferredConnectionParameters(), std::move(update_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerMockAclChannelTest,
@@ -2214,12 +2214,12 @@
                                                kIntervalMax, kPeripheralLatency, kTimeoutMult),
       kHighPriority);
   chanmgr()->RequestConnectionParameterUpdate(kTestHandle1, kParams, request_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(accepted.has_value());
 
   ReceiveAclDataPacket(testing::AclConnectionParameterUpdateRsp(
       param_update_req_id, kTestHandle1, ConnectionParameterUpdateResult::kAccepted));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(accepted.has_value());
   EXPECT_TRUE(accepted.value());
   accepted.reset();
@@ -2232,12 +2232,12 @@
                                                kIntervalMax, kPeripheralLatency, kTimeoutMult),
       kHighPriority);
   chanmgr()->RequestConnectionParameterUpdate(kTestHandle1, kParams, std::move(request_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(accepted.has_value());
 
   ReceiveAclDataPacket(testing::AclConnectionParameterUpdateRsp(
       param_update_req_id, kTestHandle1, ConnectionParameterUpdateResult::kRejected));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(accepted.has_value());
   EXPECT_FALSE(accepted.value());
 }
@@ -2263,12 +2263,12 @@
                                                kIntervalMax, kPeripheralLatency, kTimeoutMult),
       kHighPriority);
   chanmgr()->RequestConnectionParameterUpdate(kTestHandle1, kParams, request_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(accepted.has_value());
 
   ReceiveAclDataPacket(testing::AclCommandRejectNotUnderstoodRsp(kParamUpdateReqId, kTestHandle1,
                                                                  kLESignalingChannelId));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(accepted.has_value());
   EXPECT_FALSE(accepted.value());
 }
@@ -2276,7 +2276,7 @@
 TEST_F(ChannelManagerRealAclChannelTest,
        DestroyingChannelManagerReleasesLogicalLinkAndClosesChannels) {
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   auto link = chanmgr()->LogicalLinkForTesting(kTestHandle1);
@@ -2290,21 +2290,21 @@
   ASSERT_FALSE(closed);
 
   TearDown();  // Destroys channel manager
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(closed);
   // If link is still valid, there may be a memory leak.
   EXPECT_FALSE(link.is_alive());
 
   // If the above fails, check if the channel was holding a strong reference to the link.
   chan = Channel::WeakPtr();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(closed);
   EXPECT_FALSE(link.is_alive());
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, RequestAclPriorityNormal) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto channel = SetUpOutboundChannel();
 
@@ -2334,7 +2334,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, RequestAclPrioritySinkThenNormal) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto channel = SetUpOutboundChannel();
 
@@ -2377,7 +2377,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, RequestAclPrioritySinkThenDeactivateChannelAfterResult) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto channel = SetUpOutboundChannel();
 
@@ -2409,7 +2409,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, RequestAclPrioritySinkThenReceiveDisconnectRequest) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto channel = SetUpOutboundChannel();
 
@@ -2438,7 +2438,7 @@
   EXPECT_ACL_PACKET_OUT_(OutboundDisconnectionResponse(kPeerDisconReqId), kHighPriority);
   ReceiveAclDataPacket(
       testing::AclDisconnectionReq(kPeerDisconReqId, kTestHandle1, kRemoteId, kLocalId));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(requested_priority.has_value());
   EXPECT_EQ(*requested_priority, AclPriority::kNormal);
 }
@@ -2446,7 +2446,7 @@
 TEST_F(ChannelManagerMockAclChannelTest,
        RequestAclPrioritySinkThenDeactivateChannelBeforeResultShouldResetPriorityOnDeactivate) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto channel = SetUpOutboundChannel();
 
@@ -2480,7 +2480,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, RequestAclPrioritySinkFails) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto channel = SetUpOutboundChannel();
 
@@ -2504,7 +2504,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, TwoChannelsRequestAclPrioritySinkAndDeactivate) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   const auto kChannelIds0 = std::make_pair(ChannelId(0x40), ChannelId(0x41));
   const auto kChannelIds1 = std::make_pair(ChannelId(0x41), ChannelId(0x42));
@@ -2556,7 +2556,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, TwoChannelsRequestConflictingAclPriorities) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   const auto kChannelIds0 = std::make_pair(ChannelId(0x40), ChannelId(0x41));
   const auto kChannelIds1 = std::make_pair(ChannelId(0x41), ChannelId(0x42));
@@ -2609,7 +2609,7 @@
 // responses as if they were handled strictly sequentially.
 TEST_F(ChannelManagerMockAclChannelTest, TwoChannelsRequestAclPrioritiesAtSameTime) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   const auto kChannelIds0 = std::make_pair(ChannelId(0x40), ChannelId(0x41));
   const auto kChannelIds1 = std::make_pair(ChannelId(0x41), ChannelId(0x42));
@@ -2654,7 +2654,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, QueuedSinkAclPriorityForClosedChannelIsIgnored) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   auto channel = SetUpOutboundChannel();
 
@@ -2719,7 +2719,7 @@
                 NameMatches("service_0x0"), PropertyList(ElementsAre(StringIs("psm", "SDP"))))))));
 
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   const auto conn_req_id = NextCommandId();
   const auto config_req_id = NextCommandId();
@@ -2774,7 +2774,7 @@
 TEST_F(ChannelManagerMockAclChannelTest,
        OutboundChannelWithFlushTimeoutInChannelParametersAndDelayedFlushTimeoutCallback) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_CMD_PACKET_OUT(test_device(),
                         WriteAutomaticFlushTimeoutPacket(kTestHandle1, kExpectedFlushTimeoutParam));
@@ -2788,7 +2788,7 @@
   };
   SetUpOutboundChannelWithCallback(kLocalId, kRemoteId, /*closed_cb=*/DoNothing, chan_params,
                                    channel_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   // Channel should not be returned yet because setting flush timeout has not completed yet.
   EXPECT_FALSE(channel.is_alive());
@@ -2797,7 +2797,7 @@
   const auto kCommandComplete = CommandCompletePacket(hci_spec::kWriteAutomaticFlushTimeout,
                                                       pw::bluetooth::emboss::StatusCode::SUCCESS);
   test_device()->SendCommandChannelPacket(kCommandComplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(channel.is_alive());
   ASSERT_TRUE(channel->info().flush_timeout.has_value());
   EXPECT_EQ(channel->info().flush_timeout.value(), kFlushTimeout);
@@ -2817,7 +2817,7 @@
 TEST_F(ChannelManagerMockAclChannelTest,
        OutboundChannelWithFlushTimeoutInChannelParametersFailure) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   const auto kCommandCompleteError = CommandCompletePacket(
       hci_spec::kWriteAutomaticFlushTimeout, pw::bluetooth::emboss::StatusCode::UNSPECIFIED_ERROR);
@@ -2829,7 +2829,7 @@
   chan_params.flush_timeout = kFlushTimeout;
 
   auto channel = SetUpOutboundChannel(kLocalId, kRemoteId, /*closed_cb=*/DoNothing, chan_params);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   // Flush timeout should not be set in channel info because setting a flush timeout failed.
   EXPECT_FALSE(channel->info().flush_timeout.has_value());
@@ -2849,7 +2849,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, InboundChannelWithFlushTimeoutInChannelParameters) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   const auto kCommandComplete = CommandCompletePacket(hci_spec::kWriteAutomaticFlushTimeout,
                                                       pw::bluetooth::emboss::StatusCode::SUCCESS);
@@ -2879,7 +2879,7 @@
   ReceiveAclDataPacket(InboundConfigurationRequest(kPeerConfigRequestId));
   ReceiveAclDataPacket(InboundConfigurationResponse(config_req_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(AllExpectedPacketsSent());
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(channel.is_alive());
@@ -2901,7 +2901,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, FlushableChannelAndNonFlushableChannelOnSameLink) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto nonflushable_channel = SetUpOutboundChannel();
   auto flushable_channel = SetUpOutboundChannel(kLocalId + 1, kRemoteId + 1);
 
@@ -2913,7 +2913,7 @@
 
   flushable_channel->SetBrEdrAutomaticFlushTimeout(kFlushTimeout,
                                                    [](auto res) { EXPECT_EQ(fit::ok(), res); });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   EXPECT_FALSE(nonflushable_channel->info().flush_timeout.has_value());
   ASSERT_TRUE(flushable_channel->info().flush_timeout.has_value());
@@ -2946,7 +2946,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, SettingFlushTimeoutFails) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   auto channel = SetUpOutboundChannel();
 
   const auto kCommandComplete =
@@ -2959,7 +2959,7 @@
   channel->SetBrEdrAutomaticFlushTimeout(kFlushTimeout, [](auto res) {
     EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::UNKNOWN_CONNECTION_ID), res);
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
 
   EXPECT_ACL_PACKET_OUT_(
@@ -2976,7 +2976,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, StartAndStopA2dpOffloadSuccess) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   A2dpOffloadManager::Configuration config = BuildConfiguration();
   Channel::WeakPtr channel = SetUpOutboundChannel();
@@ -2993,7 +2993,7 @@
     EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
     result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(result.has_value());
   EXPECT_TRUE(result->is_ok());
@@ -3005,7 +3005,7 @@
     EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
     result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(result.has_value());
   EXPECT_TRUE(result->is_ok());
@@ -3020,7 +3020,7 @@
     EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
     result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(result.has_value());
   EXPECT_TRUE(result->is_ok());
@@ -3031,7 +3031,7 @@
 
 TEST_F(ChannelManagerMockAclChannelTest, DisconnectChannelAfterA2dpOffloadStarted) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   A2dpOffloadManager::Configuration config = BuildConfiguration();
   Channel::WeakPtr channel = SetUpOutboundChannel();
@@ -3048,7 +3048,7 @@
     EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::SUCCESS), res);
     result = res;
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
   ASSERT_TRUE(result.has_value());
   EXPECT_TRUE(result->is_ok());
@@ -3061,13 +3061,13 @@
   channel->Deactivate();
   ASSERT_FALSE(channel.is_alive());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
 }
 
 TEST_F(ChannelManagerMockAclChannelTest, DisconnectChannelWhileA2dpOffloadStarting) {
   QueueRegisterACL(kTestHandle1, pw::bluetooth::emboss::ConnectionRole::CENTRAL);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   A2dpOffloadManager::Configuration config = BuildConfiguration();
   Channel::WeakPtr channel = SetUpOutboundChannel();
@@ -3094,7 +3094,7 @@
   channel->Deactivate();
   ASSERT_FALSE(channel.is_alive());
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedCommandPacketsSent());
 }
 
@@ -3123,7 +3123,7 @@
       LowerBits(kATTChannelId), UpperBits(kATTChannelId),
       // Payload
       0x01));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   bool closed_called = false;
   auto closed_cb = [&closed_called] { closed_called = true; };
@@ -3139,13 +3139,13 @@
     }
   };
   ASSERT_TRUE(fixed_channels.att->Activate(std::move(rx_callback), closed_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(rx_count, 1);
   EXPECT_TRUE(closed_called);
 
   // Ensure the link is removed.
   chanmgr()->RemoveConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerRealAclChannelTest, InboundRfcommChannelFailsWithPsmNotSupported) {
@@ -3153,7 +3153,7 @@
   constexpr l2cap::ChannelId kRemoteId = 0x9042;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   const l2cap::CommandId kPeerConnReqId = 1;
@@ -3167,7 +3167,7 @@
   test_device()->SendACLDataChannelPacket(
       l2cap::testing::AclConnectionReq(kPeerConnReqId, kTestHandle1, kRemoteId, kPSM));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ChannelManagerRealAclChannelTest, InboundPacketQueuedAfterChannelOpenIsNotDropped) {
@@ -3176,7 +3176,7 @@
   constexpr l2cap::ChannelId kRemoteId = 0x9042;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   Channel::WeakPtr channel;
@@ -3186,7 +3186,7 @@
   };
 
   chanmgr()->RegisterService(kPSM, kChannelParameters, std::move(chan_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   constexpr l2cap::CommandId kConnectionReqId = 1;
   constexpr l2cap::CommandId kPeerConfigReqId = 6;
@@ -3199,7 +3199,7 @@
       l2cap::testing::AclConnectionReq(kConnectionReqId, kTestHandle1, kRemoteId, kPSM));
 
   // Config negotiation will not complete yet.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Remaining config negotiation will be added to dispatch loop.
   EXPECT_ACL_PACKET_OUT(test_device(), l2cap::testing::AclConfigRsp(kPeerConfigReqId, kTestHandle1,
@@ -3220,13 +3220,13 @@
       0x04, 0x00, 0x40, 0x00, 0xf0, 0x9f, 0x94, 0xb0));
 
   // Run until the channel opens and the packet is written to the socket buffer.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(channel.is_alive());
 
   std::vector<ByteBufferPtr> rx_packets;
   auto rx_cb = [&rx_packets](ByteBufferPtr sdu) { rx_packets.push_back(std::move(sdu)); };
   ASSERT_TRUE(channel->Activate(rx_cb, DoNothing));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(rx_packets.size(), 1u);
   ASSERT_EQ(rx_packets[0]->size(), 4u);
   EXPECT_EQ("🔰", rx_packets[0]->view(0, 4u).AsString());
@@ -3243,7 +3243,7 @@
   chan_params.max_rx_sdu_size = kMtu;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   Channel::WeakPtr channel;
@@ -3255,7 +3255,7 @@
   QueueOutboundL2capConnection(kTestHandle1, kPSM, kLocalId, kRemoteId, chan_cb, chan_params,
                                chan_params);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   ASSERT_TRUE(channel.is_alive());
   EXPECT_EQ(kTestHandle1, channel->link_handle());
@@ -3273,7 +3273,7 @@
   chan_params.max_rx_sdu_size = l2cap::kMinACLMTU;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   Channel::WeakPtr channel;
@@ -3285,7 +3285,7 @@
 
   QueueInboundL2capConnection(kTestHandle1, kPSM, kLocalId, kRemoteId, chan_params, chan_params);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   ASSERT_TRUE(channel.is_alive());
   EXPECT_EQ(*chan_params.max_rx_sdu_size, channel->max_rx_sdu_size());
@@ -3312,12 +3312,12 @@
                                            param_update_req_id, kTestHandle1, kIntervalMin,
                                            kIntervalMax, kPeripheralLatency, kTimeoutMult));
   chanmgr()->RequestConnectionParameterUpdate(kTestHandle1, kParams, request_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(accepted.has_value());
 
   test_device()->SendACLDataChannelPacket(l2cap::testing::AclConnectionParameterUpdateRsp(
       param_update_req_id, kTestHandle1, l2cap::ConnectionParameterUpdateResult::kAccepted));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(accepted.has_value());
   EXPECT_TRUE(accepted.value());
   accepted.reset();
@@ -3344,7 +3344,7 @@
 
   chanmgr()->OpenL2capChannel(kTestHandle1, kPSM, kChannelParameters, std::move(chan_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(chan_cb_called);
 }
@@ -3358,7 +3358,7 @@
   constexpr size_t kChannelCreationPacketCount = 3;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   l2cap::Channel::WeakPtr channel;
@@ -3368,7 +3368,7 @@
   };
   QueueOutboundL2capConnection(kTestHandle1, kPSM, kLocalId, kRemoteId, std::move(chan_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   EXPECT_TRUE(channel.is_alive());
   channel->Activate(NopRxCallback, DoNothing);
@@ -3392,7 +3392,7 @@
     }
     // Create PDU to send on dynamic channel
     EXPECT_TRUE(channel->Send(NewBuffer(0x01)));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
@@ -3406,7 +3406,7 @@
                                            0x01));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kTestHandle1, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 }
@@ -3424,7 +3424,7 @@
   constexpr size_t kChannelCreationPacketCount = 3;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   l2cap::Channel::WeakPtr channel0;
@@ -3434,7 +3434,7 @@
   };
   QueueOutboundL2capConnection(kTestHandle1, kPSM0, kLocalId0, kRemoteId0, std::move(chan_cb0));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   ASSERT_TRUE(channel0.is_alive());
   ASSERT_TRUE(channel0->Activate(NopRxCallback, DoNothing));
@@ -3449,7 +3449,7 @@
   // Free up the buffer space from packets sent while creating |channel0|
   test_device()->SendCommandChannelPacket(
       NumberOfCompletedPacketsPacket(kTestHandle1, kChannelCreationPacketCount));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   EXPECT_TRUE(channel1.is_alive());
@@ -3458,7 +3458,7 @@
   // Free up the buffer space from packets sent while creating |channel1|
   test_device()->SendCommandChannelPacket(NumberOfCompletedPacketsPacket(
       kTestHandle1, kConnectionCreationPacketCount + kChannelCreationPacketCount));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Queue size should be equal to or larger than |num_queued_packets| to ensure that all packets
   // get queued and sent
@@ -3482,14 +3482,14 @@
 
     // Create PDU to send on dynamic channel
     EXPECT_TRUE(channel->Send(NewBuffer(0x01)));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_FALSE(test_device()->AllExpectedDataPacketsSent());
 
   // Notify the processed packets with a Number Of Completed Packet HCI event
   // This should cause the remaining 5 packets to be sent
   test_device()->SendCommandChannelPacket(NumberOfCompletedPacketsPacket(kTestHandle1, 5));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 }
 
@@ -3502,7 +3502,7 @@
   constexpr size_t kChannelCreationPacketCount = 3;
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   l2cap::Channel::WeakPtr channel;
@@ -3512,7 +3512,7 @@
   };
   QueueOutboundL2capConnection(kTestHandle1, kPSM, kLocalId, kRemoteId, std::move(chan_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   EXPECT_TRUE(channel.is_alive());
   channel->Activate(NopRxCallback, DoNothing);
@@ -3544,7 +3544,7 @@
 
     // Create PDU to send on dynamic channel
     EXPECT_TRUE(channel->Send(NewBuffer(0x01)));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_FALSE(test_device()->AllExpectedDataPacketsSent());
 
@@ -3552,7 +3552,7 @@
   // This should cause the remaining 10 packets to be sent
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kTestHandle1, 10));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 }
 
@@ -3587,7 +3587,7 @@
       });
 
   QueueAclConnection(kTestHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   Channel::WeakPtr channel;
@@ -3598,7 +3598,7 @@
 
   QueueOutboundL2capConnection(kTestHandle1, kPSM, kLocalId, kRemoteId, std::move(chan_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   // We should have opened a channel successfully.
   ASSERT_TRUE(channel.is_alive());
@@ -3617,7 +3617,7 @@
     EXPECT_EQ(kExpectSuccess, res.is_ok());
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(request_cb_count, 1u);
   if (kPriority == AclPriority::kNormal) {
     EXPECT_FALSE(connection_handle_from_encode_cb);
@@ -3641,7 +3641,7 @@
   // Deactivating channel should send priority command to revert priority back to normal if it was
   // changed.
   channel->Deactivate();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   if (kPriority != AclPriority::kNormal && kExpectSuccess) {
diff --git a/src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_fuzztest.cc b/src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_fuzztest.cc
index bcea1e5..df83e26 100644
--- a/src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_fuzztest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_fuzztest.cc
@@ -42,7 +42,7 @@
 };
 
 // Reuse ControllerTest test fixture code even though we're not using gtest.
-using TestingBase = ControllerTest<FuzzerController>;
+using TestingBase = FakeDispatcherControllerTest<FuzzerController>;
 class DataFuzzTest : public TestingBase {
  public:
   DataFuzzTest(const uint8_t* data, size_t size) : data_(data, size), rng_(&data_) {
@@ -53,7 +53,7 @@
 
     channel_manager_ = l2cap::ChannelManager::Create(transport()->acl_data_channel(),
                                                      transport()->command_channel(),
-                                                     /*random_channel_ids=*/true, pw_dispatcher());
+                                                     /*random_channel_ids=*/true, dispatcher());
   }
 
   ~DataFuzzTest() override {
@@ -67,7 +67,7 @@
     while (data_.remaining_bytes() > 0) {
       bool run_loop = data_.ConsumeBool();
       if (run_loop) {
-        RunLoopUntilIdle();
+        RunUntilIdle();
       }
 
       if (!SendAclPacket()) {
@@ -79,7 +79,7 @@
       }
     }
 
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   bool SendAclPacket() {
diff --git a/src/connectivity/bluetooth/core/bt-host/l2cap/logical_link_unittest.cc b/src/connectivity/bluetooth/core/bt-host/l2cap/logical_link_unittest.cc
index 3dcf45f..f42c0b3 100644
--- a/src/connectivity/bluetooth/core/bt-host/l2cap/logical_link_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/l2cap/logical_link_unittest.cc
@@ -20,7 +20,7 @@
 namespace {
 using Conn = hci::Connection;
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 const hci_spec::ConnectionHandle kConnHandle = 0x0001;
 
@@ -56,7 +56,7 @@
         kConnHandle, type, pw::bluetooth::emboss::ConnectionRole::CENTRAL, kMaxPayload,
         std::move(query_service_cb), transport()->acl_data_channel(),
         transport()->command_channel(),
-        /*random_channel_ids=*/true, *a2dp_offload_manager_, pw_dispatcher());
+        /*random_channel_ids=*/true, *a2dp_offload_manager_, dispatcher());
   }
   void ResetAndCreateNewLogicalLink(LinkType type = LinkType::kACL) {
     link()->Close();
@@ -176,7 +176,7 @@
                         bt::testing::WriteAutomaticFlushTimeoutPacket(link()->handle(), 0),
                         &kCommandCompleteError);
   link()->SetBrEdrAutomaticFlushTimeout(zx::duration::infinite(), result_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(cb_status.has_value());
   ASSERT_TRUE(cb_status->is_error());
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::UNKNOWN_CONNECTION_ID), *cb_status);
@@ -184,7 +184,7 @@
 
   // Test flush timeout = 0 (no command should be sent)
   link()->SetBrEdrAutomaticFlushTimeout(zx::msec(0), result_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(cb_status.has_value());
   EXPECT_TRUE(cb_status->is_error());
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::INVALID_HCI_COMMAND_PARAMETERS),
@@ -197,7 +197,7 @@
                         bt::testing::WriteAutomaticFlushTimeoutPacket(link()->handle(), 0),
                         &kCommandComplete);
   link()->SetBrEdrAutomaticFlushTimeout(zx::duration::infinite(), result_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(cb_status.has_value());
   EXPECT_EQ(fit::ok(), *cb_status);
   cb_status.reset();
@@ -208,7 +208,7 @@
                         bt::testing::WriteAutomaticFlushTimeoutPacket(link()->handle(), 2046),
                         &kCommandComplete);
   link()->SetBrEdrAutomaticFlushTimeout(hci_spec::kMaxAutomaticFlushTimeoutDuration, result_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(cb_status.has_value());
   EXPECT_EQ(fit::ok(), *cb_status);
   cb_status.reset();
@@ -216,7 +216,7 @@
   // Test too large flush timeout (no command should be sent).
   link()->SetBrEdrAutomaticFlushTimeout(hci_spec::kMaxAutomaticFlushTimeoutDuration + zx::msec(1),
                                         result_cb);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(cb_status.has_value());
   EXPECT_TRUE(cb_status->is_error());
   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::INVALID_HCI_COMMAND_PARAMETERS),
diff --git a/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_manager_unittest.cc
index 7a77a41..6c65896 100644
--- a/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_manager_unittest.cc
@@ -78,7 +78,7 @@
   return params;
 }
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 // Activate a SCO connection and set the close handler to call Deactivate()
 void activate_connection(OpenConnectionResult& result) {
@@ -105,7 +105,7 @@
 
   void TearDown() override {
     manager_.reset();
-    RunLoopUntilIdle();
+    RunUntilIdle();
     TestingBase::TearDown();
   }
 
@@ -138,7 +138,7 @@
 
   auto req_handle = manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   ASSERT_TRUE(conn_result->value().is_alive());
@@ -146,7 +146,7 @@
 
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kScoConnectionHandle));
   conn_result->value()->Close();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest, OpenConnectionAndReceiveFailureStatusEvent) {
@@ -166,7 +166,7 @@
 
   auto req_handle = manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn.has_value());
   ASSERT_TRUE(conn->is_error());
   EXPECT_EQ(conn->error_value(), HostError::kFailed);
@@ -191,7 +191,7 @@
 
   auto req_handle = manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn.has_value());
   ASSERT_TRUE(conn->is_error());
   EXPECT_EQ(conn->error_value(), HostError::kFailed);
@@ -222,7 +222,7 @@
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, kConnectionParams),
       &accept_status_packet, &conn_complete_packet);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn.has_value());
   ASSERT_TRUE(conn->is_error());
   EXPECT_EQ(conn->error_value(), HostError::kParametersRejected);
@@ -249,7 +249,7 @@
 
   auto req_handle = manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   // Ensure subsequent correct complete packet completes request.
@@ -257,7 +257,7 @@
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS);
   test_device()->SendCommandChannelPacket(conn_complete_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kScoConnectionHandle));
@@ -269,7 +269,7 @@
       pw::bluetooth::emboss::StatusCode::SUCCESS);
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kScoConnectionHandle));
   test_device()->SendCommandChannelPacket(conn_complete_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest, DestroyingManagerClosesConnections) {
@@ -291,14 +291,14 @@
 
   auto req_handle = manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_TRUE(conn_result->value().is_alive());
 
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kScoConnectionHandle));
   DestroyManager();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // WeakPtr should become invalid.
   EXPECT_FALSE(conn_result->value().is_alive());
 }
@@ -336,7 +336,7 @@
   };
   auto req_handle_2 = manager()->OpenConnection(kConnectionParams, std::move(conn_cb_2));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_0.has_value());
   EXPECT_FALSE(conn_result_2.has_value());
   ASSERT_TRUE(conn_result_1.has_value());
@@ -352,7 +352,7 @@
       handle_0, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS);
   test_device()->SendCommandChannelPacket(conn_complete_packet_0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_0.has_value());
   ASSERT_TRUE(conn_result_0->is_ok());
   EXPECT_FALSE(conn_result_2.has_value());
@@ -361,7 +361,7 @@
       handle_2, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS);
   test_device()->SendCommandChannelPacket(conn_complete_packet_2);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_2.has_value());
   ASSERT_TRUE(conn_result_2->is_ok());
 
@@ -374,7 +374,7 @@
   conn_result_0.value()->Deactivate();
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(handle_2));
   conn_result_2.value()->Deactivate();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest, HandleReuse) {
@@ -396,7 +396,7 @@
 
   auto req_handle_0 = manager()->OpenConnection(kConnectionParams, conn_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   ScoConnection::WeakPtr conn = conn_result->value();
@@ -417,7 +417,7 @@
 
   auto req_handle_1 = manager()->OpenConnection(kConnectionParams, conn_cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value()->handle(), kScoConnectionHandle);
@@ -443,14 +443,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, kConnectionParams),
       &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
@@ -474,14 +474,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, kConnectionParams),
       &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::CONNECTION_ACCEPT_TIMEOUT_EXCEEDED));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_error());
   EXPECT_EQ(conn_result->error_value(), HostError::kParametersRejected);
@@ -503,14 +503,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, kConnectionParams),
       &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_error());
   EXPECT_EQ(conn_result->error_value(), HostError::kParametersRejected);
@@ -542,7 +542,7 @@
       testing::RejectSynchronousConnectionRequest(
           kPeerAddress, pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
       &reject_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(conn_cb_count, 0u);
   // Destroy manager so that callback gets called before callback reference is invalid.
   DestroyManager();
@@ -560,20 +560,20 @@
       testing::RejectSynchronousConnectionRequest(
           kPeerAddress, pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
       &reject_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest, IgnoreInboundAclRequest) {
   auto conn_req_packet = testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kACL);
   test_device()->SendCommandChannelPacket(conn_req_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest, IgnoreInboundRequestWrongPeerAddress) {
   const DeviceAddress address(DeviceAddress::Type::kBREDR, {0x00, 0x00, 0x00, 0x00, 0x00, 0x05});
   auto conn_req_packet = testing::ConnectionRequestPacket(address, hci_spec::LinkType::kACL);
   test_device()->SendCommandChannelPacket(conn_req_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest, QueueTwoAcceptConnectionRequestsCancelsFirstRequest) {
@@ -602,14 +602,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, second_conn_params),
       &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_1.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_1.has_value());
   ASSERT_TRUE(conn_result_1->is_ok());
   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
@@ -649,14 +649,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, second_conn_params),
       &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_1.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_1.has_value());
   ASSERT_TRUE(conn_result_1->is_ok());
   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
@@ -674,7 +674,7 @@
 
   EXPECT_CMD_PACKET_OUT(test_device(), testing::EnhancedAcceptSynchronousConnectionRequestPacket(
                                            kPeerAddress, kConnectionParams));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   std::optional<AcceptConnectionResult> conn_result_1;
   auto req_handle_1 = manager()->AcceptConnection(
@@ -690,7 +690,7 @@
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::CONNECTION_ACCEPT_TIMEOUT_EXCEEDED));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_0.has_value());
   ASSERT_TRUE(conn_result_0->is_error());
   EXPECT_EQ(conn_result_0->error_value(), HostError::kParametersRejected);
@@ -705,14 +705,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, kConnectionParams),
       &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_1.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_1.has_value());
   ASSERT_TRUE(conn_result_1->is_ok());
   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
@@ -742,7 +742,7 @@
   };
   auto req_handle_1 = manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   DestroyManager();
   ASSERT_TRUE(conn_result_0.has_value());
@@ -773,7 +773,7 @@
       testing::RejectSynchronousConnectionRequest(
           kPeerAddress, pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
       &reject_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result->is_error());
   EXPECT_EQ(conn_result->error_value(), HostError::kCanceled);
 }
@@ -798,7 +798,7 @@
       testing::RejectSynchronousConnectionRequest(
           kPeerAddress, pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
       &reject_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result->is_error());
   EXPECT_EQ(conn_result->error_value(), HostError::kCanceled);
 }
@@ -823,18 +823,18 @@
   auto req_handle = manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
   req_handle.Cancel();
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
   test_device()->SendCommandChannelPacket(conn_complete_packet);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value()->handle(), kScoConnectionHandle);
 
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kScoConnectionHandle));
   conn_result.value()->Close();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest, QueueTwoRequestsAndCancelSecond) {
@@ -863,7 +863,7 @@
   };
   auto req_handle_1 = manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_0.has_value());
 
   req_handle_1.Cancel();
@@ -876,7 +876,7 @@
       handle_0, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS);
   test_device()->SendCommandChannelPacket(conn_complete_packet_0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_0.has_value());
   ASSERT_TRUE(conn_result_0->is_ok());
   EXPECT_EQ(cb_count_1, 1u);
@@ -887,7 +887,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(handle_0),
                         &disconn_status_packet_0, &disconn_complete_0);
   conn_result_0.value()->Deactivate();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest,
@@ -922,7 +922,7 @@
   };
   auto req_handle_2 = manager()->OpenConnection(kConnectionParams, std::move(conn_cb_2));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_0.has_value());
   EXPECT_FALSE(conn_result_2.has_value());
   ASSERT_TRUE(conn_result_1.has_value());
@@ -930,7 +930,7 @@
   EXPECT_EQ(conn_result_1->error_value(), HostError::kCanceled);
 
   DestroyManager();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest,
@@ -953,7 +953,7 @@
 
   auto req_handle_0 = manager()->OpenConnection(kConnectionParams, std::move(conn_cb_0));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_0.has_value());
   ASSERT_TRUE(conn_result_0->is_ok());
   ASSERT_TRUE(conn_result_0->value().is_alive());
@@ -961,7 +961,7 @@
 
   test_device()->SendCommandChannelPacket(testing::DisconnectionCompletePacket(
       kScoConnectionHandle, pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_CMD_PACKET_OUT(
       test_device(),
@@ -976,7 +976,7 @@
 
   auto req_handle_1 = manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_1.has_value());
   ASSERT_TRUE(conn_result_1->is_ok());
   ASSERT_TRUE(conn_result_1->value().is_alive());
@@ -984,7 +984,7 @@
 
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kScoConnectionHandle));
   conn_result_1.value()->Close();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoConnectionManagerTest,
@@ -997,10 +997,10 @@
   };
 
   req_handle = manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   DestroyManager();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_TRUE(conn.has_value());
   ASSERT_TRUE(conn->is_error());
@@ -1032,7 +1032,7 @@
   };
   req_handle_1 = manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_0.has_value());
 
   DestroyManager();
@@ -1067,14 +1067,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, esco_params_0),
       &accept_status_packet_0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   auto conn_req_packet_1 =
@@ -1088,14 +1088,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, esco_params_1),
       &accept_status_packet_1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
@@ -1123,14 +1123,14 @@
                         testing::EnhancedAcceptSynchronousConnectionRequestPacket(
                             kPeerAddress, ScoConnectionParams()),
                         &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
@@ -1162,14 +1162,14 @@
                         testing::EnhancedAcceptSynchronousConnectionRequestPacket(
                             kPeerAddress, EscoConnectionParams()),
                         &accept_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_ok());
   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
@@ -1199,13 +1199,13 @@
       testing::RejectSynchronousConnectionRequest(
           kPeerAddress, pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_LIMITED_RESOURCES),
       &reject_status_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // The AcceptConnection request should not be completed until the connection complete event is
   // received.
   EXPECT_FALSE(conn_result.has_value());
 
   test_device()->SendCommandChannelPacket(conn_complete_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result.has_value());
   ASSERT_TRUE(conn_result->is_error());
   EXPECT_EQ(conn_result->error_value(), HostError::kParametersRejected);
@@ -1242,7 +1242,7 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, kConnectionParams),
       &accept_status_packet_0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_0.has_value());
 
   // Second request should cancel first request when connection complete event is received.
@@ -1255,7 +1255,7 @@
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_0.has_value());
   ASSERT_TRUE(conn_result_0->is_error());
   EXPECT_EQ(conn_result_0->error_value(), HostError::kCanceled);
@@ -1272,14 +1272,14 @@
       test_device(),
       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress, kConnectionParams),
       &accept_status_packet_1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_FALSE(conn_result_1.has_value());
 
   test_device()->SendCommandChannelPacket(testing::SynchronousConnectionCompletePacket(
       kScoConnectionHandle, kPeerAddress, hci_spec::LinkType::kExtendedSCO,
       pw::bluetooth::emboss::StatusCode::SUCCESS));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_TRUE(conn_result_1.has_value());
   ASSERT_TRUE(conn_result_1->is_ok());
   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
diff --git a/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_unittest.cc b/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_unittest.cc
index d15832b..5200d69 100644
--- a/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/sco/sco_connection_unittest.cc
@@ -27,7 +27,7 @@
 static constexpr size_t kMaxScoPacketCount = 1;
 const hci::DataBufferInfo kDataBufferInfo(kMaxScoPacketLength, kMaxScoPacketCount);
 
-using TestingBase = testing::ControllerTest<testing::MockController>;
+using TestingBase = testing::FakeDispatcherControllerTest<testing::MockController>;
 class ScoConnectionTest : public TestingBase {
  public:
   ScoConnectionTest() = default;
@@ -211,7 +211,7 @@
 
   test_device()->SendCommandChannelPacket(
       bt::testing::DisconnectionCompletePacket(kConnectionHandle));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(close_count, 1u);
   EXPECT_EQ(deactivated_count(), 0u);
   EXPECT_FALSE(hci_conn().is_alive());
@@ -355,7 +355,7 @@
       packet_buffer_0.view(/*pos=*/sizeof(hci_spec::SynchronousDataHeader));
   EXPECT_SCO_PACKET_OUT(test_device(), packet_buffer_0);
   sco_conn()->Send(std::make_unique<DynamicByteBuffer>(packet_0_payload));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 
   // Queue a packet on a second connection.
@@ -373,21 +373,21 @@
   const BufferView packet_1_payload =
       packet_buffer_1.view(/*pos=*/sizeof(hci_spec::SynchronousDataHeader));
   sco_conn_1->Send(std::make_unique<DynamicByteBuffer>(packet_1_payload));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Disconnecting the first connection should clear the controller packet count and allow
   // packet_buffer_1 to be sent.
   test_device()->SendCommandChannelPacket(
       bt::testing::DisconnectionCompletePacket(kConnectionHandle));
   EXPECT_SCO_PACKET_OUT(test_device(), packet_buffer_1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(close_count_0, 1u);
   EXPECT_FALSE(hci_conn().is_alive());
   EXPECT_EQ(close_count_1, 0u);
 
   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(kConnectionHandle2));
   sco_conn_1.reset();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(close_count_1, 0u);
 }
 
diff --git a/src/connectivity/bluetooth/core/bt-host/socket/socket_factory_l2cap_integration_unittest.cc b/src/connectivity/bluetooth/core/bt-host/socket/socket_factory_l2cap_integration_unittest.cc
index e8c334b..3ca52ac 100644
--- a/src/connectivity/bluetooth/core/bt-host/socket/socket_factory_l2cap_integration_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/socket/socket_factory_l2cap_integration_unittest.cc
@@ -10,8 +10,8 @@
 #include "src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager_mock_controller_test_fixture.h"
 #include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"
 #include "src/connectivity/bluetooth/core/bt-host/l2cap/test_packets.h"
-#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"
+#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
 
 namespace bt::socket {
 namespace {
@@ -21,20 +21,22 @@
 using TestingBase = l2cap::ChannelManagerMockControllerTest;
 
 // This test harness provides test cases for interations between SocketFactory and the L2cap layer.
-class SocketFactoryL2capIntegrationTest : public TestingBase {
+class SocketFactoryL2capIntegrationTest : public ::gtest::TestLoopFixture, public TestingBase {
  public:
-  SocketFactoryL2capIntegrationTest() = default;
+  SocketFactoryL2capIntegrationTest() : TestingBase(dispatcher_), dispatcher_(dispatcher()) {}
   ~SocketFactoryL2capIntegrationTest() override = default;
 
  protected:
   void SetUp() override {
-    TestingBase::SetUp();
+    TestingBase::Initialize();
     socket_factory_ = std::make_unique<socket::SocketFactory<l2cap::Channel>>();
   }
 
   void TearDown() override {
     socket_factory_.reset();
-    TestingBase::TearDown();
+    TestingBase::DeleteChannelManager();
+    RunLoopUntilIdle();
+    DeleteTransport();
   }
 
   zx::socket MakeSocketForChannel(l2cap::Channel::WeakPtr channel) {
@@ -43,6 +45,7 @@
 
  private:
   std::unique_ptr<socket::SocketFactory<l2cap::Channel>> socket_factory_;
+  pw::async::fuchsia::FuchsiaDispatcher dispatcher_;
 
   BT_DISALLOW_COPY_ASSIGN_AND_MOVE(SocketFactoryL2capIntegrationTest);
 };
diff --git a/src/connectivity/bluetooth/core/bt-host/testing/controller_test.h b/src/connectivity/bluetooth/core/bt-host/testing/controller_test.h
index d17af94..53a27f2 100644
--- a/src/connectivity/bluetooth/core/bt-host/testing/controller_test.h
+++ b/src/connectivity/bluetooth/core/bt-host/testing/controller_test.h
@@ -5,20 +5,18 @@
 #ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_TESTING_CONTROLLER_TEST_H_
 #define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_TESTING_CONTROLLER_TEST_H_
 
-#include <lib/async/cpp/task.h>
-
 #include <memory>
 
 #include <pw_async/heap_dispatcher.h>
 #include <pw_async_fuchsia/dispatcher.h>
 
+#include "pw_async/fake_dispatcher_fixture.h"
 #include "pw_bluetooth/controller.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/macros.h"
 #include "src/connectivity/bluetooth/core/bt-host/transport/acl_data_channel.h"
 #include "src/connectivity/bluetooth/core/bt-host/transport/acl_data_packet.h"
 #include "src/connectivity/bluetooth/core/bt-host/transport/sco_data_channel.h"
 #include "src/connectivity/bluetooth/core/bt-host/transport/transport.h"
-#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
 
 namespace bt::testing {
 
@@ -39,7 +37,7 @@
 //     can respond to HCI commands the way a real controller would (albeit in a
 //     contrived fashion), emulate discovery and connection events, etc.
 template <class ControllerTestDoubleType>
-class ControllerTest : public ::gtest::TestLoopFixture {
+class ControllerTest {
  public:
   // Default data buffer information used by ACLDataChannel.
   static constexpr size_t kDefaultMaxAclDataPacketLength = 1024;
@@ -49,38 +47,25 @@
   static constexpr size_t kDefaultMaxScoPacketLength = 255;
   static constexpr size_t kDefaultMaxScoPacketCount = 5;
 
-  ControllerTest() = default;
-  ~ControllerTest() override = default;
-
-  pw::async::Dispatcher& pw_dispatcher() { return pw_dispatcher_; }
+  ControllerTest(pw::async::Dispatcher& dispatcher) : dispatcher_(dispatcher) {}
+  ~ControllerTest() = default;
 
  protected:
-  void SetUp(pw::bluetooth::Controller::FeaturesBits features, bool initialize_transport = true) {
+  void Initialize(pw::bluetooth::Controller::FeaturesBits features,
+                  bool initialize_transport = true) {
     std::unique_ptr<pw::bluetooth::Controller> controller =
         ControllerTest<ControllerTestDoubleType>::SetUpTestController();
     test_device_->set_features(features);
-    transport_ = std::make_unique<hci::Transport>(std::move(controller), pw_dispatcher_);
+    transport_ = std::make_unique<hci::Transport>(std::move(controller), dispatcher_);
 
     if (initialize_transport) {
       std::optional<bool> init_result;
       transport_->Initialize([&init_result](bool success) { init_result = success; });
-      RunLoopUntilIdle();
       ASSERT_TRUE(init_result.has_value());
       ASSERT_TRUE(init_result.value());
     }
   }
 
-  void SetUp() override { SetUp(pw::bluetooth::Controller::FeaturesBits::kHciSco); }
-
-  void TearDown() override {
-    if (!transport_) {
-      return;
-    }
-
-    RunLoopUntilIdle();
-    transport_ = nullptr;
-  }
-
   // Directly initializes the ACL data channel and wires up its data rx
   // callback. It is OK to override the data rx callback after this is called.
   //
@@ -123,7 +108,6 @@
 
   // Deletes |test_device_| and resets the pointer.
   void DeleteTestDevice() { test_device_ = nullptr; }
-
   void DeleteTransport() { transport_ = nullptr; }
 
   // Getters for internal fields frequently used by tests.
@@ -132,7 +116,7 @@
  private:
   std::unique_ptr<pw::bluetooth::Controller> SetUpTestController() {
     std::unique_ptr<ControllerTestDoubleType> controller =
-        std::make_unique<ControllerTestDoubleType>(pw_dispatcher());
+        std::make_unique<ControllerTestDoubleType>(dispatcher_);
     test_device_ = controller->GetWeakPtr();
     return controller;
   }
@@ -151,8 +135,8 @@
     });
   }
 
-  pw::async::fuchsia::FuchsiaDispatcher pw_dispatcher_{dispatcher()};
-  pw::async::HeapDispatcher heap_dispatcher_{pw_dispatcher_};
+  pw::async::Dispatcher& dispatcher_;
+  pw::async::HeapDispatcher heap_dispatcher_{dispatcher_};
   typename ControllerTestDoubleType::WeakPtr test_device_;
   std::unique_ptr<hci::Transport> transport_;
   hci::ACLPacketHandler data_received_callback_;
@@ -162,6 +146,32 @@
                 "TestBase must be used with a derivative of ControllerTestDoubleBase");
 };
 
+// FakeDispatcherControllerTest is a convenience test fixture that initializes ControllerTest with a
+// pw_async FakeDispatcherFixture backend. Only if a different underlying dispatcher is desired
+// (e.g. Zircon TestLoopFixture) should ControllerTest be referenced directly and passed the desired
+// dispatcher, which must implement the pw_async Dispatcher interface.
+//
+// To properly "TearDown" ControllerTest, the Dispatcher must be driven, then DeleteTransport()
+// called.
+template <typename ControllerTestDoubleType>
+class FakeDispatcherControllerTest : public pw::async::test::FakeDispatcherFixture,
+                                     public ControllerTest<ControllerTestDoubleType> {
+ protected:
+  FakeDispatcherControllerTest() : ControllerTest<ControllerTestDoubleType>(dispatcher()) {}
+
+  void SetUp(pw::bluetooth::Controller::FeaturesBits features, bool initialize_transport = true) {
+    ControllerTest<ControllerTestDoubleType>::Initialize(features, initialize_transport);
+    RunUntilIdle();
+  }
+
+  void SetUp() override { SetUp(pw::bluetooth::Controller::FeaturesBits::kHciSco); }
+
+  void TearDown() override {
+    RunUntilIdle();
+    ControllerTest<ControllerTestDoubleType>::DeleteTransport();
+  }
+};
+
 }  // namespace bt::testing
 
 #endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_TESTING_CONTROLLER_TEST_H_
diff --git a/src/connectivity/bluetooth/core/bt-host/transport/acl_data_channel_unittest.cc b/src/connectivity/bluetooth/core/bt-host/transport/acl_data_channel_unittest.cc
index d31db28..a7bc027 100644
--- a/src/connectivity/bluetooth/core/bt-host/transport/acl_data_channel_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/transport/acl_data_channel_unittest.cc
@@ -10,7 +10,6 @@
 
 #include <gmock/gmock.h>
 
-#include "gtest/gtest.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/assert.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci-spec/constants.h"
@@ -51,7 +50,7 @@
 }};
 
 using pw::bluetooth::AclPriority;
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 class AclDataChannelTest : public TestingBase {
  public:
@@ -82,7 +81,7 @@
           /*payload_size=*/1);
       packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
       connection.QueuePacket(std::move(packet));
-      RunLoopUntilIdle();
+      RunUntilIdle();
     }
   }
 
@@ -160,7 +159,7 @@
           /*payload_size=*/1);
       packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
       connection->QueuePacket(std::move(packet));
-      RunLoopUntilIdle();
+      RunUntilIdle();
     }
   }
 
@@ -220,7 +219,7 @@
     EXPECT_EQ(kExpectSuccess, result.is_ok());
   });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(request_cb_count, 1u);
   ASSERT_TRUE(connection);
   EXPECT_EQ(connection.value(), kConnectionHandle1);
@@ -246,7 +245,7 @@
                                            EXPECT_TRUE(result.is_error());
                                          });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(request_cb_count, 1u);
 }
 
@@ -266,7 +265,7 @@
                                            EXPECT_TRUE(result.is_error());
                                          });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(request_cb_count, 1u);
 }
 
@@ -308,7 +307,7 @@
                             static_cast<uint8_t>(kBufferMaxNumPackets)));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, kBufferMaxNumPackets + 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -339,7 +338,7 @@
                          /*payload_size=*/1);
   packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
   connection_0.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -348,7 +347,7 @@
 
   // Attempt to send packet on an unregistered link
   connection_0.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Second packet should not have been sent
   EXPECT_EQ(connection_0.queued_packets().size(), 1u);
@@ -380,7 +379,7 @@
                          /*payload_size=*/1);
   packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
   connection_0.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -389,7 +388,7 @@
 
   // Attempt to send packet on an unregistered link
   connection_0.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Second packet should not have been sent
   EXPECT_EQ(connection_0.queued_packets().size(), 1u);
@@ -409,7 +408,7 @@
   // |kConnectionHandle1| is not registered so this event is ignored (no packets should be sent)
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 1u);
 }
@@ -427,7 +426,7 @@
   // |kConnectionHandle1| is not registered so this event is ignored (no packets should be sent)
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 1u);
 }
@@ -454,7 +453,7 @@
                             static_cast<uint8_t>(kBufferMaxNumPackets)));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -472,7 +471,7 @@
                          /*payload_size=*/1);
   packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
   connection_0.QueuePacket(std::move(packet));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // No packet should be sent since the controller's BR/EDR buffer has no availabity
   EXPECT_EQ(connection_0.queued_packets().size(), 1u);
@@ -501,7 +500,7 @@
                             static_cast<uint8_t>(kBufferMaxNumPackets)));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -541,14 +540,14 @@
   out_packet_0->mutable_view()->mutable_data().Write(kPacket0);
   out_packet_0->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   // Sending a NumberOfCompletedPackets event is necessary because since |kBufferMaxNumPackets| is
   // 2, the controller buffer is full and we won't be able to send any more packets until at least
   // 1 is ACKed by the controller to free up the buffer space
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_ACL_PACKET_OUT(test_device(), kPacket1);
   // Create packet to send
@@ -556,14 +555,14 @@
   out_packet_1->mutable_view()->mutable_data().Write(kPacket1);
   out_packet_1->InitializeFromBuffer();
   connection_1.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   acl_data_channel()->UnregisterConnection(kConnectionHandle0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_ACL_PACKET_OUT(test_device(), kPacket1);
   // Create packet to send
@@ -571,7 +570,7 @@
   out_packet_1->mutable_view()->mutable_data().Write(kPacket1);
   out_packet_1->InitializeFromBuffer();
   connection_1.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   acl_data_channel()->UnregisterConnection(kConnectionHandle1);
@@ -616,7 +615,7 @@
   out_packet_0->mutable_view()->mutable_data().Write(kPacket0);
   out_packet_0->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   // The second packet should fill up the controller buffer (kBufferMaxNumPackets)
@@ -626,33 +625,33 @@
   out_packet_1->mutable_view()->mutable_data().Write(kPacket1);
   out_packet_1->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   ACLDataPacketPtr out_packet_2 = ACLDataPacket::New(/*payload_size=*/1);
   out_packet_2->mutable_view()->mutable_data().Write(kPacket2);
   out_packet_2->InitializeFromBuffer();
   connection_1.QueuePacket(std::move(out_packet_2));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // |out_packet_2| should not be sent because the controller buffer is full
   EXPECT_EQ(connection_1.queued_packets().size(), 1u);
 
   // |UnregisterConnection| should not free up any buffer space, so next packet should not be sent
   acl_data_channel()->UnregisterConnection(kConnectionHandle0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Clearing the pending packet count for |connection_0| should result in |out_packet_2| being
   // sent
   EXPECT_ACL_PACKET_OUT(test_device(), kPacket2);
   acl_data_channel()->ClearControllerPacketCount(kConnectionHandle0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   // There are no active connections now
   acl_data_channel()->UnregisterConnection(kConnectionHandle1);
   acl_data_channel()->ClearControllerPacketCount(kConnectionHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_P(AclDataChannelAllBufferCombinations, RegisterTwoLEConnectionsAndUnregisterFirstConnection) {
@@ -686,14 +685,14 @@
   out_packet_0->mutable_view()->mutable_data().Write(kPacket0);
   out_packet_0->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   // Sending a NumberOfCompletedPackets event is necessary because since |kBufferMaxNumPackets| is
   // 2, the controller buffer is full and we won't be able to send any more packets until at least
   // 1 is ACKed by the controller to free up the buffer space
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_ACL_PACKET_OUT(test_device(), kPacket1);
   // Create packet to send
@@ -701,14 +700,14 @@
   out_packet_1->mutable_view()->mutable_data().Write(kPacket1);
   out_packet_1->InitializeFromBuffer();
   connection_1.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   acl_data_channel()->UnregisterConnection(kConnectionHandle0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_ACL_PACKET_OUT(test_device(), kPacket1);
   // Create packet to send
@@ -716,7 +715,7 @@
   out_packet_1->mutable_view()->mutable_data().Write(kPacket1);
   out_packet_1->InitializeFromBuffer();
   connection_1.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   acl_data_channel()->UnregisterConnection(kConnectionHandle1);
@@ -761,7 +760,7 @@
   out_packet_0->mutable_view()->mutable_data().Write(kPacket0);
   out_packet_0->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   // The second packet should fill up the controller buffer (kBufferMaxNumPackets)
@@ -771,33 +770,33 @@
   out_packet_1->mutable_view()->mutable_data().Write(kPacket1);
   out_packet_1->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   ACLDataPacketPtr out_packet_2 = ACLDataPacket::New(/*payload_size=*/1);
   out_packet_2->mutable_view()->mutable_data().Write(kPacket2);
   out_packet_2->InitializeFromBuffer();
   connection_1.QueuePacket(std::move(out_packet_2));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // |out_packet_2| should not be sent because the controller buffer is full
   EXPECT_EQ(connection_1.queued_packets().size(), 1u);
 
   // |UnregisterConnection| should not free up any buffer space, so next packet should not be sent
   acl_data_channel()->UnregisterConnection(kConnectionHandle0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Clearing the pending packet count for |connection_0| should result in |out_packet_2| being
   // sent
   EXPECT_ACL_PACKET_OUT(test_device(), kPacket2);
   acl_data_channel()->ClearControllerPacketCount(kConnectionHandle0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
 
   // There are no active connections now
   acl_data_channel()->UnregisterConnection(kConnectionHandle1);
   acl_data_channel()->ClearControllerPacketCount(kConnectionHandle1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(AclDataChannelTest, SendMoreBREDRAndLEPacketsThanMaximumBREDRBufferSpace) {
@@ -834,7 +833,7 @@
         /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     connection->QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   // Since |kBufferMaxNumPackets| is 5, the controller should have received 3 packets on
@@ -849,7 +848,7 @@
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 3));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 2));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Since we're alternating between |connection_0| and |connection_1|, the controller should have
   // received 2 more packets on |connection_0| and 3 more packets on |connection_1|
@@ -863,7 +862,7 @@
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 2));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 3));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_EQ(connection_1.queued_packets().size(), 0u);
@@ -904,7 +903,7 @@
         /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     connection->QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   // Since |kBufferMaxNumPackets| is 3 and no BR/EDR packets should have been sent, the controller
@@ -915,7 +914,7 @@
 
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 3));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_EQ(connection_1.queued_packets().size(), 6u);
@@ -952,7 +951,7 @@
                            /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     connection_0.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_EQ(connection_0.queued_packets().size(), 1u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -977,7 +976,7 @@
                            /*payload_size=*/1);
     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
     connection_1.QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_EQ(connection_1.queued_packets().size(), 1u);
   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
@@ -993,7 +992,7 @@
                             static_cast<uint8_t>(kBufferMaxNumPackets)));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Send out last packet on LE link
   EXPECT_ACL_PACKET_OUT(test_device(),
@@ -1006,7 +1005,7 @@
                             static_cast<uint8_t>(kBufferMaxNumPackets)));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(connection_0.queued_packets().size(), 0u);
   EXPECT_EQ(connection_1.queued_packets().size(), 0u);
diff --git a/src/connectivity/bluetooth/core/bt-host/transport/command_channel_unittest.cc b/src/connectivity/bluetooth/core/bt-host/transport/command_channel_unittest.cc
index 3519ea0..f080bf3 100644
--- a/src/connectivity/bluetooth/core/bt-host/transport/command_channel_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/transport/command_channel_unittest.cc
@@ -4,8 +4,6 @@
 
 #include "src/connectivity/bluetooth/core/bt-host/transport/command_channel.h"
 
-#include <lib/async/cpp/task.h>
-
 #include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci-spec/protocol.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
@@ -27,9 +25,9 @@
 using bt::UpperBits;
 using EventCallbackResult = CommandChannel::EventCallbackResult;
 
-constexpr zx::duration kCommandTimeout = zx::sec(12);
+constexpr pw::chrono::SystemClock::duration kCommandTimeout = std::chrono::seconds(12);
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 
 // A reference counted object used to verify that HCI command completion and
 // status callbacks are properly cleaned up after the end of a transaction.
@@ -54,7 +52,7 @@
   inspect::Inspector inspector_;
 
  private:
-  pw::async::HeapDispatcher heap_dispatcher_{pw_dispatcher()};
+  pw::async::HeapDispatcher heap_dispatcher_{dispatcher()};
 };
 
 EmbossCommandPacket MakeReadRemoteSupportedFeatures(uint16_t connection_handle) {
@@ -109,7 +107,7 @@
 
   test_obj = nullptr;
   EXPECT_FALSE(test_obj_deleted);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Make sure that the I/O thread is no longer holding on to |test_obj|.
   TearDown();
@@ -168,7 +166,7 @@
   view.num_responses().Write(0);
 
   id = cmd_channel()->SendCommand(std::move(packet), cb, hci_spec::kInquiryCompleteEventCode);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2, cb_count);
 }
 
@@ -206,7 +204,7 @@
   auto reset =
       hci::EmbossCommandPacket::New<pw::bluetooth::emboss::ResetCommandWriter>(hci_spec::kReset);
   id = cmd_channel()->SendCommand(std::move(reset), complete_cb, hci_spec::kCommandStatusEventCode);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 // Tests:
@@ -270,14 +268,14 @@
   auto inquiry = CommandPacket::New(hci_spec::kInquiryCancel);
   [[maybe_unused]] auto inquiry_id = cmd_channel()->SendCommand(std::move(inquiry), cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, transaction_count);
   EXPECT_EQ(1u, cb_event_count);
 
   test_device()->SendCommandChannelPacket(rsp_commandsavail);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, transaction_count);
   EXPECT_EQ(2u, cb_event_count);
@@ -356,14 +354,14 @@
       hci::EmbossCommandPacket::New<pw::bluetooth::emboss::ResetCommandWriter>(hci_spec::kReset);
   cmd_channel()->SendCommand(std::move(reset), cb);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Different opcodes can be sent without a reply
   EXPECT_EQ(2u, transaction_count);
 
   // Even if we get a response to one, the duplicate opcode is still queued.
   test_device()->SendCommandChannelPacket(rsp_inqcancel);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2u, transaction_count);
   EXPECT_EQ(1u, cancel_count);
@@ -371,7 +369,7 @@
 
   // Once we get a reset back, the second can be sent (and replied to)
   test_device()->SendCommandChannelPacket(rsp_reset);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(3u, transaction_count);
   EXPECT_EQ(1u, cancel_count);
@@ -442,7 +440,7 @@
       hci::EmbossCommandPacket::New<pw::bluetooth::emboss::ResetCommandWriter>(hci_spec::kReset);
   id1 = cmd_channel()->SendCommand(std::move(packet), cb, kTestEventCode0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Should have received the Status but not the result.
   EXPECT_EQ(1u, cb_count);
@@ -452,13 +450,13 @@
   packet = hci::EmbossCommandPacket::New<pw::bluetooth::emboss::InquiryCancelCommandWriter>(
       hci_spec::kInquiryCancel);
   id2 = cmd_channel()->SendCommand(std::move(packet), cb, kTestEventCode0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1u, cb_count);
 
   // Sending the complete will release the queue and send the next command.
   test_device()->SendCommandChannelPacket(rsp_bogocomplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(3u, cb_count);
 
@@ -470,7 +468,7 @@
 
   // Finish out the commands.
   test_device()->SendCommandChannelPacket(rsp_bogocomplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(4u, cb_count);
 }
@@ -520,7 +518,7 @@
 
   test_device()->SendCommandChannelPacket(rsp_nocommandsavail);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   CommandChannel::TransactionId id;
   size_t cb_count = 0;
@@ -542,7 +540,7 @@
       hci::EmbossCommandPacket::New<pw::bluetooth::emboss::ResetCommandWriter>(hci_spec::kReset);
   id = cmd_channel()->SendCommand(std::move(packet), cb, kTestEventCode0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_NE(0u, id);
   ASSERT_EQ(0u, transaction_count);
@@ -551,14 +549,14 @@
   auto invalid_id = cmd_channel()->AddEventHandler(
       kTestEventCode0, [](const EventPacket&) { return EventCallbackResult::kContinue; });
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(0u, invalid_id);
 
   // Commands become available and the whole transaction finishes.
   test_device()->SendCommandChannelPacket(rsp_commandsavail);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   ASSERT_EQ(1u, transaction_count);
   ASSERT_EQ(2u, cb_count);
@@ -624,7 +622,7 @@
   test_device()->SendCommandChannelPacket(cmd_status);
   test_device()->SendCommandChannelPacket(event1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(3, event_count0);
   EXPECT_EQ(3, event_count1);
@@ -646,7 +644,7 @@
   test_device()->SendCommandChannelPacket(event0);
   test_device()->SendCommandChannelPacket(event1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(0, event_count0);
   EXPECT_EQ(7, event_count1);
@@ -665,7 +663,7 @@
   test_device()->SendCommandChannelPacket(event1);
   test_device()->SendCommandChannelPacket(event1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(0, event_count0);
   EXPECT_EQ(0, event_count1);
@@ -721,7 +719,7 @@
   id = cmd_channel()->SendCommand(std::move(reset), nullptr);
   EXPECT_NE(0u, id);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2, event_count);
 }
@@ -753,13 +751,13 @@
   auto cmd_id = cmd_channel()->SendCommand(std::move(cmd), std::move(cmd_cb));
   EXPECT_NE(0u, cmd_id);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count);
   EXPECT_FALSE(cmd_channel()->RemoveQueuedCommand(cmd_id));
   test_device()->SendCommandChannelPacket(rsp_reset);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count);
   EXPECT_EQ(1, cmd_cb_count);
@@ -804,17 +802,17 @@
       cmd_channel()->SendCommand(std::move(reset), std::bind(event_cb, _1, _2, &event_count1));
   EXPECT_NE(0u, id1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count);
   EXPECT_TRUE(cmd_channel()->RemoveQueuedCommand(id1));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(0, event_count0);
   test_device()->SendCommandChannelPacket(rsp_reset);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Only one command should have been sent.
   EXPECT_EQ(1, transaction_count);
@@ -881,18 +879,18 @@
                                  hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode);
   EXPECT_NE(0u, id1);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count);
   EXPECT_TRUE(cmd_channel()->RemoveQueuedCommand(id1));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(0, event_count0);
   test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesRsp);
   test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Only one command should have been sent.
   EXPECT_EQ(1, transaction_count);
@@ -923,12 +921,12 @@
                                        hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode);
   EXPECT_NE(0u, id);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(2, event_count);
   EXPECT_FALSE(cmd_channel()->RemoveQueuedCommand(id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Only one command should have been sent.
   EXPECT_EQ(1, transaction_count);
@@ -961,17 +959,17 @@
                                       hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode);
   EXPECT_NE(0u, cmd_id);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(0, cmd_events);
   EXPECT_FALSE(cmd_channel()->RemoveQueuedCommand(cmd_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesRsp);
   test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count);
   // The command should have gotten update and complete events.
@@ -1004,16 +1002,16 @@
                                       hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode);
   EXPECT_NE(0u, cmd_id);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, cmd_events);
   EXPECT_FALSE(cmd_channel()->RemoveQueuedCommand(cmd_id));
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   test_device()->SendCommandChannelPacket(kReadRemoteSupportedFeaturesComplete);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(1, transaction_count);
   // The command should have gotten update and complete events.
@@ -1058,17 +1056,17 @@
   EXPECT_NE(0u, id2);
 
   test_device()->SendCommandChannelPacket(vendor_event_bytes0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2, event_count0);
   EXPECT_EQ(0, event_count1);
 
   test_device()->SendCommandChannelPacket(vendor_event_bytes0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(4, event_count0);
   EXPECT_EQ(0, event_count1);
 
   test_device()->SendCommandChannelPacket(vendor_event_bytes1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(4, event_count0);
   EXPECT_EQ(1, event_count1);
 
@@ -1076,7 +1074,7 @@
   cmd_channel()->RemoveEventHandler(id0);
   test_device()->SendCommandChannelPacket(vendor_event_bytes0);
   test_device()->SendCommandChannelPacket(vendor_event_bytes1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(5, event_count0);
   EXPECT_EQ(2, event_count1);
 }
@@ -1118,17 +1116,17 @@
   EXPECT_NE(0u, id2);
 
   test_device()->SendCommandChannelPacket(le_meta_event_bytes0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2, event_count0);
   EXPECT_EQ(0, event_count1);
 
   test_device()->SendCommandChannelPacket(le_meta_event_bytes0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(4, event_count0);
   EXPECT_EQ(0, event_count1);
 
   test_device()->SendCommandChannelPacket(le_meta_event_bytes1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(4, event_count0);
   EXPECT_EQ(1, event_count1);
 
@@ -1136,7 +1134,7 @@
   cmd_channel()->RemoveEventHandler(id0);
   test_device()->SendCommandChannelPacket(le_meta_event_bytes0);
   test_device()->SendCommandChannelPacket(le_meta_event_bytes1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(5, event_count0);
   EXPECT_EQ(2, event_count1);
 }
@@ -1229,7 +1227,7 @@
   test_device()->SendCommandChannelPacket(le_event_bytes);
 
   // Process the async command expectation.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // End the asynchronous transaction. This should NOT unregister the LE event handler.
   test_device()->SendCommandChannelPacket(event_bytes);
@@ -1238,7 +1236,7 @@
   test_device()->SendCommandChannelPacket(le_event_bytes);
   test_device()->SendCommandChannelPacket(le_event_bytes);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Should have received 3 LE events.
   EXPECT_EQ(3, le_event_count);
@@ -1258,7 +1256,7 @@
       test_device()->Stop();
     }
   });
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(error_cb_called);
 }
 
@@ -1289,11 +1287,11 @@
   ASSERT_NE(0u, id2);
 
   // Run the loop until the command timeout task gets scheduled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, timeout_cb_count);
   EXPECT_EQ(0u, cmd_cb_count);
 
-  RunLoopFor(kCommandTimeout);
+  RunFor(kCommandTimeout);
 
   EXPECT_EQ(1u, timeout_cb_count);
   EXPECT_EQ(0u, cmd_cb_count);
@@ -1331,7 +1329,7 @@
   CommandChannel::TransactionId id2 = cmd_channel()->SendCommand(std::move(packet), cb);
   ASSERT_NE(0u, id2);
 
-  RunLoopFor(kCommandTimeout);
+  RunFor(kCommandTimeout);
   EXPECT_EQ(1u, timeout_cb_count);
 }
 
@@ -1355,9 +1353,9 @@
   ASSERT_NE(0u, id1);
 
   // Run the loop until the command timeout task gets scheduled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, timeout_cb_count);
-  RunLoopFor(kCommandTimeout);
+  RunFor(kCommandTimeout);
   EXPECT_EQ(1u, timeout_cb_count);
   EXPECT_EQ(0u, cmd_cb_count);
 
@@ -1367,12 +1365,12 @@
   CommandChannel::TransactionId id2 = cmd_channel()->SendCommand(std::move(packet), cb);
   EXPECT_EQ(0u, id2);
   // No command should be sent.
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Events should be ignored.
   test_device()->SendCommandChannelPacket(bt::testing::CommandCompletePacket(
       hci_spec::kReset, pw::bluetooth::emboss::StatusCode::SUCCESS));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, cmd_cb_count);
 }
 
@@ -1447,20 +1445,20 @@
       hci::EmbossCommandPacket::New<pw::bluetooth::emboss::ResetCommandWriter>(hci_spec::kReset);
   id1 = cmd_channel()->SendCommand(std::move(packet), cb.share(), kTestEventCode0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Should have received the Status but not the result.
   EXPECT_EQ(1u, cb_count);
 
   // Sending the complete will finish the command and add the next command.
   test_device()->SendCommandChannelPacket(rsp_bogocomplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(3u, cb_count);
 
   // Finish out the command.
   test_device()->SendCommandChannelPacket(rsp_bogocomplete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   EXPECT_EQ(4u, cb_count);
 }
@@ -1610,7 +1608,7 @@
   id1 = cmd_channel()->SendExclusiveCommand(CommandPacket::New(kExclusiveOne), exclusive_cb.share(),
                                             kExclOneCompleteEvent, {kExclusiveTwo});
   cmd_channel()->SendCommand(CommandPacket::New(kNonExclusive), nonexclusive_cb.share());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Should have received the ExclusiveOne status but not the complete. ExclusiveTwo should be
   // queued.
   EXPECT_EQ(1u, exclusive_cb_count);
@@ -1622,7 +1620,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), excl_two_cmd, &rsp_excl_two_status);
   EXPECT_CMD_PACKET_OUT(test_device(), nonexclusive_cmd, &nonexclusive_complete);
   test_device()->SendCommandChannelPacket(rsp_one_complete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(3u, exclusive_cb_count);     // +2: rsp_one_complete, rsp_excl_two_status
   EXPECT_EQ(2u, nonexclusive_cb_count);  // +1: nonexclusive_complete
 
@@ -1631,13 +1629,13 @@
   EXPECT_CMD_PACKET_OUT(test_device(), excl_one_cmd, &rsp_excl_one_status);
   test_device()->SendCommandChannelPacket(rsp_two_complete);
   cmd_channel()->SendCommand(CommandPacket::New(kNonExclusive), nonexclusive_cb.share());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(5u, exclusive_cb_count);     // +2: rsp_two_complete, rsp_excl_one_status
   EXPECT_EQ(3u, nonexclusive_cb_count);  // +1: nonexclusive_complete
 
   // Finish the second ExclusiveOne
   test_device()->SendCommandChannelPacket(rsp_one_complete);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(6u, exclusive_cb_count);  // +1: rsp_one_complete
   EXPECT_EQ(3u, nonexclusive_cb_count);
 }
@@ -1682,7 +1680,7 @@
   test_device()->SendCommandChannelPacket(event0);
   test_device()->SendCommandChannelPacket(event0);
   test_device()->SendCommandChannelPacket(event0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2, event_count);
 }
 
@@ -1730,17 +1728,17 @@
       cmd_channel()->SendLeAsyncCommand(std::move(cmd_packet), std::move(event_cb), kSubeventCode);
   EXPECT_NE(0u, id);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, event_count);
 
   // Handler should be removed when subevent received.
   test_device()->SendCommandChannelPacket(cmd_complete_subevent);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2u, event_count);
 
   // This seconod complete event should be ignored because the handler should have been removed.
   test_device()->SendCommandChannelPacket(cmd_complete_subevent);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2u, event_count);
 }
 
@@ -1762,7 +1760,7 @@
   EXPECT_CMD_PACKET_OUT(test_device(), std::move(cmd), );
   EXPECT_NE(0u, cmd_channel()->SendLeAsyncCommand(
                     CommandPacket::New(kOpCode), [](auto, const auto&) {}, kSubeventCode + 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(CommandChannelTest, SendingSecondLECommandWithSameSubeventShouldWaitForFirstToComplete) {
@@ -1820,7 +1818,7 @@
                                                 kSubeventCode);
   EXPECT_NE(0u, id_0);
 
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, event_count_0);
 
   size_t event_count_1 = 0;
@@ -1844,19 +1842,19 @@
   auto id_1 = cmd_channel()->SendLeAsyncCommand(CommandPacket::New(kOpCode1), std::move(event_cb_1),
                                                 kSubeventCode);
   EXPECT_NE(0u, id_1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(0u, event_count_1);
 
   // When first command complete event is received, second command should be sent.
   EXPECT_CMD_PACKET_OUT(test_device(), cmd1, &cmd1_status_event);
   test_device()->SendCommandChannelPacket(cmd_complete_subevent);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2u, event_count_0);
   EXPECT_EQ(1u, event_count_1);
 
   // Second complete event should be received by second command event handler only.
   test_device()->SendCommandChannelPacket(cmd_complete_subevent);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(2u, event_count_0);
   EXPECT_EQ(2u, event_count_1);
 }
@@ -1889,7 +1887,7 @@
   auto id = cmd_channel()->SendLeAsyncCommand(CommandPacket::New(kOpCode), std::move(event_cb),
                                               kSubeventCode);
   EXPECT_NE(0u, id);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(1u, event_count);
 
   // Async LE command for subevent is already pending, so registering event handler should fail by
diff --git a/src/connectivity/bluetooth/core/bt-host/transport/sco_data_channel_unittest.cc b/src/connectivity/bluetooth/core/bt-host/transport/sco_data_channel_unittest.cc
index 4df1799..553fe83 100644
--- a/src/connectivity/bluetooth/core/bt-host/transport/sco_data_channel_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/transport/sco_data_channel_unittest.cc
@@ -4,14 +4,11 @@
 
 #include "src/connectivity/bluetooth/core/bt-host/transport/sco_data_channel.h"
 
-#include <gtest/gtest.h>
-
 #include "pw_bluetooth/controller.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/test_helpers.h"
 #include "src/connectivity/bluetooth/core/bt-host/testing/test_packets.h"
-#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
 
 namespace bt::hci {
 namespace {
@@ -164,7 +161,7 @@
   WeakSelf<ConnectionInterface> weak_interface_;
 };
 
-using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
+using TestingBase = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 class ScoDataChannelTest : public TestingBase {
  public:
   void SetUp() override {
@@ -234,7 +231,7 @@
                                                             static_cast<uint8_t>(i)));
     }
     connection()->QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
@@ -245,7 +242,7 @@
                                       static_cast<uint8_t>(kBufferMaxNumPackets)));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 }
 
@@ -257,7 +254,7 @@
                             i      // payload
     );
     test_device()->SendScoDataChannelPacket(packet);
-    RunLoopUntilIdle();
+    RunUntilIdle();
     ASSERT_EQ(connection()->received_packets().size(), static_cast<size_t>(i) + 1);
     EXPECT_TRUE(ContainersEqual(connection()->received_packets()[i]->view().data(), packet));
   }
@@ -292,7 +289,7 @@
                             0x00   // payload
   );
   test_device()->SendScoDataChannelPacket(packet_0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(connection_0.received_packets().size(), 1u);
   ASSERT_EQ(connection_1.received_packets().size(), 0u);
 
@@ -301,7 +298,7 @@
                             0x01   // payload
   );
   test_device()->SendScoDataChannelPacket(packet_1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(connection_0.received_packets().size(), 1u);
   // The packet should be received even though connection_1 isn't the active connection.
   ASSERT_EQ(connection_1.received_packets().size(), 1u);
@@ -311,7 +308,7 @@
   out_packet_0->mutable_view()->mutable_data().Write(packet_0);
   out_packet_0->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, 1));
@@ -322,7 +319,7 @@
   // The packet should be sent even though connection_1 isn't the active connection.
   EXPECT_SCO_PACKET_OUT(test_device(), packet_1);
   connection_1.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
   // This is necessary because kBufferMaxNumPackets is 2, so we won't be able to send
   // any more packets until at least 1 is ACKed by the controller.
@@ -333,7 +330,7 @@
   sco_data_channel()->UnregisterConnection(connection_0.handle());
   EXPECT_EQ(config_count, 2);
   EXPECT_EQ(reset_count, 0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   out_packet_1 = ScoDataPacket::New(/*payload_size=*/1);
   out_packet_1->mutable_view()->mutable_data().Write(packet_1);
@@ -341,7 +338,7 @@
   // Now that connection_1 is the active connection, packets should still be sent.
   EXPECT_SCO_PACKET_OUT(test_device(), packet_1);
   connection_1.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 
   // There are no active connections now (+1 to reset_count).
@@ -379,7 +376,7 @@
   out_packet_0->mutable_view()->mutable_data().Write(packet_0);
   out_packet_0->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_0));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 
   // The second packet should fill up the controller buffer (kBufferMaxNumPackets).
@@ -389,7 +386,7 @@
   out_packet_1->mutable_view()->mutable_data().Write(packet_1);
   out_packet_1->InitializeFromBuffer();
   connection_0.QueuePacket(std::move(out_packet_1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 
   std::unique_ptr<ScoDataPacket> out_packet_2 = ScoDataPacket::New(/*payload_size=*/1);
@@ -397,23 +394,23 @@
   out_packet_2->InitializeFromBuffer();
   // The packet should NOT be sent because the controller buffer is full.
   connection_1.QueuePacket(std::move(out_packet_2));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // connection_1 should become the active connection, but out_packet_2 can't be sent yet.
   sco_data_channel()->UnregisterConnection(connection_0.handle());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connection_1.queued_packets().size(), 1u);
 
   // Clearing the pending packet count for connection_0 should result in packet_2 being sent.
   EXPECT_SCO_PACKET_OUT(test_device(), packet_2);
   sco_data_channel()->ClearControllerPacketCount(connection_0.handle());
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 
   // There are no active connections now.
   sco_data_channel()->UnregisterConnection(connection_1.handle());
   sco_data_channel()->ClearControllerPacketCount(connection_1.handle());
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoDataChannelSingleConnectionTest, IgnoreInboundPacketForUnknownConnectionHandle) {
@@ -423,7 +420,7 @@
                                  0x07   // payload
   );
   test_device()->SendScoDataChannelPacket(packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connection()->received_packets().size(), 0u);
 }
 
@@ -443,7 +440,7 @@
                                                             static_cast<uint8_t>(i)));
     }
     connection()->QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_EQ(connection()->queued_packets().size(), 1u);
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
@@ -452,14 +449,14 @@
   // sent).
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle1, 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connection()->queued_packets().size(), 1u);
 }
 
 TEST_F(ScoDataChannelSingleConnectionTest, ReceiveTooSmallPacket) {
   StaticByteBuffer invalid_packet(LowerBits(kConnectionHandle0), UpperBits(kConnectionHandle0));
   test_device()->SendScoDataChannelPacket(invalid_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Packet should be ignored.
   EXPECT_EQ(connection()->received_packets().size(), 0u);
 
@@ -469,7 +466,7 @@
                                        0x01   // payload
   );
   test_device()->SendScoDataChannelPacket(valid_packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connection()->received_packets().size(), 1u);
 }
 
@@ -479,7 +476,7 @@
                                  0x00   // payload
   );
   test_device()->SendScoDataChannelPacket(packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // Packet should be ignored.
   EXPECT_EQ(connection()->received_packets().size(), 0u);
 
@@ -489,7 +486,7 @@
                             0x01   // payload
   );
   test_device()->SendScoDataChannelPacket(packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connection()->received_packets().size(), 1u);
 }
 
@@ -633,11 +630,11 @@
   EXPECT_EQ(reset_count, 0);
 
   DeleteTransport();
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   // Callback should not use-after-free.
   config_cb(PW_STATUS_OK);
-  RunLoopUntilIdle();
+  RunUntilIdle();
 }
 
 TEST_F(ScoDataChannelTest,
@@ -673,16 +670,16 @@
   sco_data_channel()->RegisterConnection(connection_1.GetWeakPtr());
   EXPECT_EQ(config_callbacks.size(), 2u);
   // sco_packet should not be sent yet.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // The first callback completing should not complete the second connection configuration.
   config_callbacks[0](PW_STATUS_OK);
   // sco_packet should not be sent yet.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connection_1.queued_packets().size(), 1u);
   // Queued packet should be sent after second callback called.
   config_callbacks[1](PW_STATUS_OK);
   EXPECT_SCO_PACKET_OUT(test_device(), packet);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 }
 
@@ -702,7 +699,7 @@
                                                             static_cast<uint8_t>(i)));
     }
     connection()->QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 
@@ -721,7 +718,7 @@
                          LowerBits(num_packets),
                          UpperBits(num_packets)};
   test_device()->SendCommandChannelPacket(event);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 }
 
@@ -757,7 +754,7 @@
 
   // The first configuration error should be processed & the configuration of connection_1 should
   // succeed.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(connection_0.hci_error_count(), 1);
   EXPECT_EQ(config_count, 2);
   EXPECT_EQ(reset_count, 0);
@@ -767,7 +764,7 @@
                                    0x00   // payload
   );
   test_device()->SendScoDataChannelPacket(packet_0);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   // packet_0 should not be received since connection_0 failed configuration and was unregistered.
   ASSERT_EQ(connection_0.received_packets().size(), 0u);
 
@@ -776,7 +773,7 @@
                                    0x01   // payload
   );
   test_device()->SendScoDataChannelPacket(packet_1);
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(connection_1.received_packets().size(), 1u);
 
   // There are no active connections now (+1 to reset_count).
@@ -827,7 +824,7 @@
                                                             static_cast<uint8_t>(i)));
     }
     connection()->QueuePacket(std::move(packet));
-    RunLoopUntilIdle();
+    RunUntilIdle();
   }
 
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
@@ -838,7 +835,7 @@
                                       static_cast<uint8_t>(kBufferMaxNumPackets)));
   test_device()->SendCommandChannelPacket(
       bt::testing::NumberOfCompletedPacketsPacket(kConnectionHandle0, kBufferMaxNumPackets + 1));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_TRUE(test_device()->AllExpectedScoPacketsSent());
 }
 
diff --git a/src/connectivity/bluetooth/core/bt-host/transport/transport_unittest.cc b/src/connectivity/bluetooth/core/bt-host/transport/transport_unittest.cc
index 5004e68..2d37655 100644
--- a/src/connectivity/bluetooth/core/bt-host/transport/transport_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/transport/transport_unittest.cc
@@ -15,7 +15,7 @@
 
 namespace {
 
-using TransportTest = bt::testing::ControllerTest<bt::testing::MockController>;
+using TransportTest = bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
 using TransportDeathTest = TransportTest;
 
 TEST_F(TransportTest, CommandChannelTimeoutShutsDownChannelAndNotifiesClosedCallback) {
@@ -24,7 +24,7 @@
   size_t closed_cb_count = 0;
   transport()->SetTransportErrorCallback([&] { closed_cb_count++; });
 
-  constexpr zx::duration kCommandTimeout = zx::sec(12);
+  constexpr pw::chrono::SystemClock::duration kCommandTimeout = std::chrono::seconds(12);
 
   StaticByteBuffer req_reset(LowerBits(hci_spec::kReset),
                              UpperBits(hci_spec::kReset),  // HCI_Reset opcode
@@ -52,11 +52,11 @@
   ASSERT_NE(0u, id2);
 
   // Run the loop until the command timeout task gets scheduled.
-  RunLoopUntilIdle();
+  RunUntilIdle();
   ASSERT_EQ(0u, cb_count);
   EXPECT_EQ(0u, closed_cb_count);
 
-  RunLoopFor(kCommandTimeout);
+  RunFor(kCommandTimeout);
   EXPECT_EQ(0u, cb_count);
   EXPECT_EQ(1u, closed_cb_count);
   EXPECT_TRUE(cmd_chan_weak.is_alive());
@@ -73,10 +73,10 @@
 
   EXPECT_TRUE(transport()->InitializeScoDataChannel(
       DataBufferInfo(/*max_data_length=*/1, /*max_num_packets=*/1)));
-  RunLoopUntilIdle();
+  RunUntilIdle();
 
   test_device()->Stop();
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(closed_cb_count, 1u);
 }
 
@@ -93,7 +93,7 @@
   transport()->SetTransportErrorCallback([&] { closed_cb_count++; });
   EXPECT_FALSE(transport()->InitializeScoDataChannel(
       DataBufferInfo(/*max_data_length=*/1, /*max_num_packets=*/1)));
-  RunLoopUntilIdle();
+  RunUntilIdle();
   EXPECT_EQ(closed_cb_count, 0u);
 }