[Bluetooth] Combine BluetoothDevice::Pair() callbacks.

Combine the callback/error_callback parameters for
BluetoothDevice::Pair() and BluetoothDevice::Connect(). This
eliminates the need to call SplitOnceCallback(...) as well
as reducing (slightly) memory use, program size, and
code complexity.

Bug: 730593
Change-Id: If2fae37564aede38f7eaae87202e0ab2bb8b3922
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2935767
Commit-Queue: Chris Mumford <cmumford@google.com>
Reviewed-by: Tetsui Ohkubo <tetsui@chromium.org>
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Reviewed-by: Matt Reynolds <mattreynolds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#894944}
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc b/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc
index fdd14f29..10996d8 100644
--- a/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc
+++ b/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc
@@ -61,25 +61,21 @@
   LOG(ERROR) << "BluetoothSetDiscovering failed.";
 }
 
-void OnBluetoothDeviceConnect(bool was_device_already_paired) {
+void OnBluetoothDeviceConnect(
+    bool was_device_already_paired,
+    absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
   if (was_device_already_paired) {
     device::RecordUserInitiatedReconnectionAttemptResult(
-        absl::nullopt /* failure_reason */,
+        error_code
+            ? absl::make_optional(GetConnectionFailureReason(*error_code))
+            : absl::nullopt,
         device::BluetoothUiSurface::kSystemTray);
   }
-}
-
-void OnBluetoothDeviceConnectError(
-    bool was_device_already_paired,
-    device::BluetoothDevice::ConnectErrorCode error_code) {
-  LOG(ERROR) << "Failed to connect to device, error code [" << error_code
-             << "]. The attempted device was previously ["
-             << (was_device_already_paired ? "paired" : "not paired") << "].";
-
-  if (was_device_already_paired) {
-    device::RecordUserInitiatedReconnectionAttemptResult(
-        GetConnectionFailureReason(error_code),
-        device::BluetoothUiSurface::kSystemTray);
+  if (error_code) {
+    LOG(ERROR) << "Failed to connect to device, error code ["
+               << error_code.value()
+               << "]. The attempted device was previously ["
+               << (was_device_already_paired ? "paired" : "not paired") << "].";
   }
 }
 
@@ -251,19 +247,17 @@
       return;
     }
 
-    device->Connect(nullptr /* pairing_delegate */,
+    device->Connect(/*pairing_delegate=*/nullptr,
                     base::BindOnce(&OnBluetoothDeviceConnect,
-                                   true /* was_device_already_paired */),
-                    base::BindOnce(&OnBluetoothDeviceConnectError,
-                                   true /* was_device_already_paired */));
+                                   /*was_device_already_paired=*/true));
     return;
   }
 
   // Simply connect without pairing for devices which do not support pairing.
   if (!device->IsPairable()) {
-    device->Connect(nullptr /* pairing_delegate */, base::DoNothing(),
-                    base::BindOnce(&OnBluetoothDeviceConnectError,
-                                   false /* was_device_already_paired */));
+    device->Connect(/*pairing_delegate=*/nullptr,
+                    base::BindOnce(&OnBluetoothDeviceConnect,
+                                   /*was_device_already_paired=*/false));
     return;
   }
 
diff --git a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc
index 710d8d4..64618ba 100644
--- a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc
+++ b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -1461,9 +1461,15 @@
   btle_instance->OnLEConnectionStateChange(std::move(addr), connected);
 }
 
-void ArcBluetoothBridge::OnGattConnected(
+void ArcBluetoothBridge::OnGattConnect(
     mojom::BluetoothAddressPtr addr,
-    std::unique_ptr<BluetoothGattConnection> connection) {
+    std::unique_ptr<BluetoothGattConnection> connection,
+    absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
+  if (error_code.has_value()) {
+    LOG(WARNING) << "GattConnectError: error_code = " << error_code.value();
+    OnGattDisconnected(std::move(addr));
+    return;
+  }
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   const std::string addr_str = addr->To<std::string>();
   GattConnection& conn = gatt_connections_[addr_str];
@@ -1473,13 +1479,6 @@
   OnGattConnectStateChanged(std::move(addr), true);
 }
 
-void ArcBluetoothBridge::OnGattConnectError(
-    mojom::BluetoothAddressPtr addr,
-    BluetoothDevice::ConnectErrorCode error_code) {
-  LOG(WARNING) << "GattConnectError: error_code = " << error_code;
-  OnGattDisconnected(std::move(addr));
-}
-
 void ArcBluetoothBridge::OnGattDisconnected(mojom::BluetoothAddressPtr addr) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (gatt_connections_.erase(addr->To<std::string>()) == 0) {
@@ -1502,8 +1501,9 @@
 
   if (!device) {
     LOG(ERROR) << "Unknown device " << addr;
-    OnGattConnectError(std::move(remote_addr),
-                       BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    OnGattConnect(std::move(remote_addr),
+                  /*connection=*/nullptr,
+                  BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
@@ -1513,8 +1513,9 @@
       bluetooth_instance->OnLEConnectionStateChange(std::move(remote_addr),
                                                     true);
     } else {
-      OnGattConnectError(std::move(remote_addr),
-                         BluetoothDevice::ConnectErrorCode::ERROR_INPROGRESS);
+      OnGattConnect(std::move(remote_addr),
+                    /*connection=*/nullptr,
+                    BluetoothDevice::ConnectErrorCode::ERROR_INPROGRESS);
     }
     return;
   }
@@ -1528,12 +1529,9 @@
   gatt_connections_.emplace(
       addr, GattConnection(GattConnection::ConnectionState::CONNECTING, nullptr,
                            need_hard_disconnect));
-  mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
   device->CreateGattConnection(
-      base::BindOnce(&ArcBluetoothBridge::OnGattConnected,
-                     weak_factory_.GetWeakPtr(), std::move(remote_addr)),
-      base::BindOnce(&ArcBluetoothBridge::OnGattConnectError,
-                     weak_factory_.GetWeakPtr(), std::move(remote_addr_clone)));
+      base::BindOnce(&ArcBluetoothBridge::OnGattConnect,
+                     weak_factory_.GetWeakPtr(), std::move(remote_addr)));
 }
 
 void ArcBluetoothBridge::DisconnectLEDevice(
diff --git a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.h b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.h
index 6ce5a52..76866ab 100644
--- a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.h
+++ b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.h
@@ -38,6 +38,7 @@
 #include "device/bluetooth/bluetooth_remote_gatt_service.h"
 #include "device/bluetooth/bluez/bluetooth_adapter_bluez.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 class BrowserContext;
@@ -394,11 +395,10 @@
 
   void OnGattConnectStateChanged(mojom::BluetoothAddressPtr addr,
                                  bool connected) const;
-  void OnGattConnected(
+  void OnGattConnect(
       mojom::BluetoothAddressPtr addr,
-      std::unique_ptr<device::BluetoothGattConnection> connection);
-  void OnGattConnectError(mojom::BluetoothAddressPtr addr,
-                          device::BluetoothDevice::ConnectErrorCode error_code);
+      std::unique_ptr<device::BluetoothGattConnection> connection,
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
   void OnGattDisconnected(mojom::BluetoothAddressPtr addr);
 
   void OnGattNotifyStartDone(
diff --git a/chrome/browser/ash/login/screens/hid_detection_screen.cc b/chrome/browser/ash/login/screens/hid_detection_screen.cc
index b018c49..bc6430c 100644
--- a/chrome/browser/ash/login/screens/hid_detection_screen.cc
+++ b/chrome/browser/ash/login/screens/hid_detection_screen.cc
@@ -337,29 +337,15 @@
     mouse_is_pairing_ = true;
     keyboard_is_pairing_ = true;
   }
-  device->Connect(this,
-                  base::BindOnce(&HIDDetectionScreen::BTConnected,
-                                 weak_ptr_factory_.GetWeakPtr(), device_type),
-                  base::BindOnce(&HIDDetectionScreen::BTConnectError,
-                                 weak_ptr_factory_.GetWeakPtr(),
-                                 device->GetAddress(), device_type));
+  device->Connect(this, base::BindOnce(&HIDDetectionScreen::OnConnect,
+                                       weak_ptr_factory_.GetWeakPtr(),
+                                       device->GetAddress(), device_type));
 }
 
-void HIDDetectionScreen::BTConnected(device::BluetoothDeviceType device_type) {
-  if (DeviceIsPointing(device_type))
-    mouse_is_pairing_ = false;
-  if (DeviceIsKeyboard(device_type)) {
-    keyboard_is_pairing_ = false;
-    SendKeyboardDeviceNotification();
-  }
-}
-
-void HIDDetectionScreen::BTConnectError(
+void HIDDetectionScreen::OnConnect(
     const std::string& address,
     device::BluetoothDeviceType device_type,
-    device::BluetoothDevice::ConnectErrorCode error_code) {
-  LOG(WARNING) << "BTConnectError while connecting " << address
-               << " error code = " << error_code;
+    absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
   if (DeviceIsPointing(device_type))
     mouse_is_pairing_ = false;
   if (DeviceIsKeyboard(device_type)) {
@@ -367,8 +353,12 @@
     SendKeyboardDeviceNotification();
   }
 
-  if (pointing_device_id_.empty() || keyboard_device_id_.empty())
-    UpdateDevices();
+  if (error_code) {
+    LOG(WARNING) << "BTConnectError while connecting " << address
+                 << " error code = " << error_code.value();
+    if (pointing_device_id_.empty() || keyboard_device_id_.empty())
+      UpdateDevices();
+  }
 }
 
 void HIDDetectionScreen::SendPointingDeviceNotification() {
diff --git a/chrome/browser/ash/login/screens/hid_detection_screen.h b/chrome/browser/ash/login/screens/hid_detection_screen.h
index 76b9db7..79ff0351 100644
--- a/chrome/browser/ash/login/screens/hid_detection_screen.h
+++ b/chrome/browser/ash/login/screens/hid_detection_screen.h
@@ -29,6 +29,7 @@
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/device/public/mojom/input_service.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 
@@ -197,16 +198,11 @@
   // Tries to connect given BT device.
   void ConnectBTDevice(device::BluetoothDevice* device);
 
-  // Called by device::BluetoothDevice on a successful pairing and connection
-  // to a device.
-  void BTConnected(device::BluetoothDeviceType device_type);
-
-  // Called by device::BluetoothDevice in response to a failure to
-  // connect to the device with bluetooth address `address` due to an error
-  // encoded in `error_code`.
-  void BTConnectError(const std::string& address,
-                      device::BluetoothDeviceType device_type,
-                      device::BluetoothDevice::ConnectErrorCode error_code);
+  // Response callback for device::BluetoothDevice::Connect().
+  void OnConnect(
+      const std::string& address,
+      device::BluetoothDeviceType device_type,
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
 
   // Sends a notification to the Web UI of the status of available Bluetooth/USB
   // pointing device.
diff --git a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
index b3a4a5b2..efaa30bc 100644
--- a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
+++ b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
@@ -162,15 +162,14 @@
                                                        /*connected=*/true) {}
 
   void CreateGattConnection(
-      base::OnceCallback<void(std::unique_ptr<device::BluetoothGattConnection>)>
-          callback,
-      base::OnceCallback<void(enum ConnectErrorCode)> error_callback,
+      device::BluetoothDevice::GattConnectionCallback callback,
       absl::optional<device::BluetoothUUID> service_uuid =
           absl::nullopt) override {
     SetConnected(true);
     gatt_services_discovery_complete_ = true;
     std::move(callback).Run(
-        std::make_unique<FakeBluetoothGattConnection>(adapter_, GetAddress()));
+        std::make_unique<FakeBluetoothGattConnection>(adapter_, GetAddress()),
+        /*error_code=*/absl::nullopt);
   }
 
   bool IsGattServicesDiscoveryComplete() const override {
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc
index eeb14b2..ae60ab1d 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc
@@ -237,6 +237,12 @@
   std::move(std::get<k>(args)).Run(std::unique_ptr<T>(p0));
 }
 
+ACTION_TEMPLATE(InvokeCallbackWithScopedPtrArg,
+                HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
+                AND_2_VALUE_PARAMS(p0, p1)) {
+  std::move(std::get<k>(args)).Run(std::unique_ptr<T>(p0), p1);
+}
+
 BluetoothGattConnection* CreateGattConnection(
     scoped_refptr<device::BluetoothAdapter> adapter,
     const std::string& device_address,
@@ -1153,27 +1159,36 @@
   static_assert(
       BluetoothDevice::NUM_CONNECT_ERROR_CODES == 8,
       "Update required if the number of BluetoothDevice enums changes.");
-  EXPECT_CALL(*device0_, CreateGattConnection_(_, _))
+  EXPECT_CALL(*device0_, CreateGattConnection_(_))
       .Times(9)
-      .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_FAILED))
-      .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_INPROGRESS))
-      .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_AUTH_FAILED))
-      .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_AUTH_REJECTED))
-      .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_AUTH_CANCELED))
-      .WillOnce(InvokeCallbackArgument<1>(BluetoothDevice::ERROR_AUTH_TIMEOUT))
-      .WillOnce(
-          InvokeCallbackArgument<1>(BluetoothDevice::ERROR_UNSUPPORTED_DEVICE))
+      .WillOnce(InvokeCallbackArgument<0>(/*connection=*/nullptr,
+                                          BluetoothDevice::ERROR_FAILED))
+      .WillOnce(InvokeCallbackArgument<0>(/*connection=*/nullptr,
+                                          BluetoothDevice::ERROR_INPROGRESS))
+      .WillOnce(InvokeCallbackArgument<0>(/*connection=*/nullptr,
+                                          BluetoothDevice::ERROR_AUTH_FAILED))
+      .WillOnce(InvokeCallbackArgument<0>(/*connection=*/nullptr,
+                                          BluetoothDevice::ERROR_AUTH_REJECTED))
+      .WillOnce(InvokeCallbackArgument<0>(/*connection=*/nullptr,
+                                          BluetoothDevice::ERROR_AUTH_CANCELED))
+      .WillOnce(InvokeCallbackArgument<0>(/*connection=*/nullptr,
+                                          BluetoothDevice::ERROR_AUTH_TIMEOUT))
+      .WillOnce(InvokeCallbackArgument<0>(
+          /*connection=*/nullptr, BluetoothDevice::ERROR_UNSUPPORTED_DEVICE))
       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
           CreateGattConnection(mock_adapter_, kTestLeDeviceAddress0,
-                               true /* expect_disconnect */)))
+                               true /* expect_disconnect */),
+          /*error_code=*/absl::nullopt))
       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
           CreateGattConnection(mock_adapter_, kTestLeDeviceAddress0,
-                               false /* expect_disconnect */)));
-  EXPECT_CALL(*device1_, CreateGattConnection_(_, _))
+                               false /* expect_disconnect */),
+          /*error_code=*/absl::nullopt));
+  EXPECT_CALL(*device1_, CreateGattConnection_(_))
       .Times(1)
       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
           CreateGattConnection(mock_adapter_, kTestLeDeviceAddress1,
-                               true /* expect_disconnect */)));
+                               true /* expect_disconnect */),
+          /*error_code=*/absl::nullopt));
 
   ASSERT_TRUE(LoadExtension(
       test_data_dir_.AppendASCII("bluetooth_low_energy/gatt_connection")));
@@ -1195,13 +1210,14 @@
       .WillOnce(Return(true))
       .WillOnce(Return(false));
 
-  EXPECT_CALL(*device0_, CreateGattConnection_(_, _))
+  EXPECT_CALL(*device0_, CreateGattConnection_(_))
       .Times(2)
       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
-          first_conn))
+          first_conn, /*error_code=*/absl::nullopt))
       .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattConnection>(
           CreateGattConnection(mock_adapter_, kTestLeDeviceAddress0,
-                               false /* expect_disconnect */)));
+                               false /* expect_disconnect */),
+          /*error_code=*/absl::nullopt));
 
   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
       "bluetooth_low_energy/reconnect_after_disconnected")));
@@ -1223,7 +1239,7 @@
   std::unique_ptr<BluetoothGattConnection> conn_ptr(conn);
   EXPECT_CALL(*conn, Disconnect()).Times(1);
 
-  EXPECT_CALL(*device0_, CreateGattConnection_(_, _))
+  EXPECT_CALL(*device0_, CreateGattConnection_(_))
       .Times(1)
       .WillOnce(MoveArg<0>(&connect_callback));
 
@@ -1237,7 +1253,8 @@
       << listener.message();
   listener.Reset();
 
-  std::move(connect_callback).Run(std::move(conn_ptr));
+  std::move(connect_callback)
+      .Run(std::move(conn_ptr), /*error_code=*/absl::nullopt);
   EXPECT_TRUE(listener.WaitUntilSatisfied());
   ASSERT_EQ("After 2nd call to disconnect.", listener.message())
       << listener.message();
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
index 0cb8a562f..bb83638e 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -629,7 +629,7 @@
         device->IsConnected());
   } else {
     // Attempt to connect to the device.
-    device->Connect(nullptr, base::DoNothing(), base::DoNothing());
+    device->Connect(nullptr, base::DoNothing());
   }
 }
 
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection.cc b/chromeos/services/secure_channel/ble_weave_client_connection.cc
index 9c8dfa4..630f963 100644
--- a/chromeos/services/secure_channel/ble_weave_client_connection.cc
+++ b/chromeos/services/secure_channel/ble_weave_client_connection.cc
@@ -227,13 +227,9 @@
 
   PA_LOG(INFO) << "Creating GATT connection with " << GetDeviceInfoLogString()
                << ".";
-  bluetooth_device->CreateGattConnection(
-      base::BindOnce(
-          &BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated,
-          weak_ptr_factory_.GetWeakPtr()),
-      base::BindOnce(
-          &BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError,
-          weak_ptr_factory_.GetWeakPtr()));
+  bluetooth_device->CreateGattConnection(base::BindOnce(
+      &BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated,
+      weak_ptr_factory_.GetWeakPtr()));
 }
 
 void BluetoothLowEnergyWeaveClientConnection::Disconnect() {
@@ -511,21 +507,22 @@
   CreateGattConnection();
 }
 
-void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError(
-    device::BluetoothDevice::ConnectErrorCode error_code) {
-  DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION);
-  RecordGattConnectionResult(
-      BluetoothDeviceConnectErrorCodeToGattConnectionResult(error_code));
-  PA_LOG(WARNING) << "Error creating GATT connection to "
-                  << GetDeviceInfoLogString() << ". Error code: " << error_code;
-  DestroyConnection(
-      BleWeaveConnectionResult::
-          BLE_WEAVE_CONNECTION_RESULT_ERROR_CREATING_GATT_CONNECTION);
-}
-
 void BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated(
-    std::unique_ptr<device::BluetoothGattConnection> gatt_connection) {
+    std::unique_ptr<device::BluetoothGattConnection> gatt_connection,
+    absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
   DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
+  if (error_code.has_value()) {
+    RecordGattConnectionResult(
+        BluetoothDeviceConnectErrorCodeToGattConnectionResult(
+            error_code.value()));
+    PA_LOG(WARNING) << "Error creating GATT connection to "
+                    << GetDeviceInfoLogString()
+                    << ". Error code: " << error_code.value();
+    DestroyConnection(
+        BleWeaveConnectionResult::
+            BLE_WEAVE_CONNECTION_RESULT_ERROR_CREATING_GATT_CONNECTION);
+    return;
+  }
   RecordGattConnectionResult(
       GattConnectionResult::GATT_CONNECTION_RESULT_SUCCESS);
 
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection.h b/chromeos/services/secure_channel/ble_weave_client_connection.h
index f47fc7f..d5e334e 100644
--- a/chromeos/services/secure_channel/ble_weave_client_connection.h
+++ b/chromeos/services/secure_channel/ble_weave_client_connection.h
@@ -341,11 +341,10 @@
   void SetConnectionLatency();
   void CreateGattConnection();
   void OnGattConnectionCreated(
-      std::unique_ptr<device::BluetoothGattConnection> gatt_connection);
+      std::unique_ptr<device::BluetoothGattConnection> gatt_connection,
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
   void OnSetConnectionLatencySuccess();
   void OnSetConnectionLatencyErrorOrTimeout();
-  void OnCreateGattConnectionError(
-      device::BluetoothDevice::ConnectErrorCode error_code);
   void OnCharacteristicsFound(const RemoteAttribute& service,
                               const RemoteAttribute& tx_characteristic,
                               const RemoteAttribute& rx_characteristic);
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc
index 6d2ff8b..2ad662d 100644
--- a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc
+++ b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc
@@ -432,9 +432,8 @@
     }
 
     // Preparing |connection| for a CreateGattConnection call.
-    EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_, _))
-        .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_success_callback_),
-                        MoveArg<1>(&create_gatt_connection_error_callback_)));
+    EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_))
+        .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_callback_)));
 
     connection->Connect();
 
@@ -451,9 +450,8 @@
     EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_GATT_CONNECTION);
     EXPECT_EQ(connection->status(), Connection::Status::IN_PROGRESS);
 
-    // Preparing |connection| to run |create_gatt_connection_success_callback_|.
-    EXPECT_FALSE(create_gatt_connection_error_callback_.is_null());
-    ASSERT_FALSE(create_gatt_connection_success_callback_.is_null());
+    // Preparing |connection| to run |create_gatt_connection_callback_|.
+    ASSERT_FALSE(create_gatt_connection_callback_.is_null());
     EXPECT_CALL(*connection, CreateCharacteristicsFinder_(_, _))
         .WillOnce(DoAll(
             MoveArg<0>(&characteristics_finder_success_callback_),
@@ -461,9 +459,10 @@
             Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>(
                 remote_device_))));
 
-    std::move(create_gatt_connection_success_callback_)
+    std::move(create_gatt_connection_callback_)
         .Run(std::make_unique<NiceMock<device::MockBluetoothGattConnection>>(
-            adapter_, kTestRemoteDeviceBluetoothAddress));
+                 adapter_, kTestRemoteDeviceBluetoothAddress),
+             /*error_code=*/absl::nullopt);
 
     EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_CHARACTERISTICS);
     EXPECT_EQ(connection->status(), Connection::Status::IN_PROGRESS);
@@ -681,9 +680,7 @@
   base::OnceClosure connection_latency_callback_;
   device::BluetoothDevice::ErrorCallback connection_latency_error_callback_;
   device::BluetoothDevice::GattConnectionCallback
-      create_gatt_connection_success_callback_;
-  device::BluetoothDevice::ConnectErrorCallback
-      create_gatt_connection_error_callback_;
+      create_gatt_connection_callback_;
 
   BluetoothLowEnergyCharacteristicsFinder::SuccessCallback
       characteristics_finder_success_callback_;
@@ -1368,16 +1365,14 @@
                   device::BluetoothDevice::CONNECTION_LATENCY_LOW, _, _))
       .WillOnce(DoAll(MoveArg<1>(&connection_latency_callback_),
                       MoveArg<2>(&connection_latency_error_callback_)));
-  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_, _))
-      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_success_callback_),
-                      MoveArg<1>(&create_gatt_connection_error_callback_)));
+  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_))
+      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_callback_)));
 
   // No GATT connection should be created before the delay.
   connection->Connect();
   EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_CONNECTION_LATENCY);
   EXPECT_EQ(connection->status(), Connection::Status::IN_PROGRESS);
-  EXPECT_TRUE(create_gatt_connection_error_callback_.is_null());
-  EXPECT_TRUE(create_gatt_connection_success_callback_.is_null());
+  EXPECT_TRUE(create_gatt_connection_callback_.is_null());
 
   // A GATT connection should be created after the delay and after setting the
   // connection latency.
@@ -1385,10 +1380,9 @@
   ASSERT_FALSE(connection_latency_callback_.is_null());
   std::move(connection_latency_callback_).Run();
 
-  EXPECT_FALSE(create_gatt_connection_error_callback_.is_null());
-  ASSERT_FALSE(create_gatt_connection_success_callback_.is_null());
+  ASSERT_FALSE(create_gatt_connection_callback_.is_null());
 
-  // Preparing |connection| to run |create_gatt_connection_success_callback_|.
+  // Preparing |connection| to run |create_gatt_connection_callback_|.
   EXPECT_CALL(*connection, CreateCharacteristicsFinder_(_, _))
       .WillOnce(DoAll(
           MoveArg<0>(&characteristics_finder_success_callback_),
@@ -1396,9 +1390,10 @@
           Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>(
               remote_device_))));
 
-  std::move(create_gatt_connection_success_callback_)
+  std::move(create_gatt_connection_callback_)
       .Run(std::make_unique<NiceMock<device::MockBluetoothGattConnection>>(
-          adapter_, kTestRemoteDeviceBluetoothAddress));
+               adapter_, kTestRemoteDeviceBluetoothAddress),
+           /*error_code=*/absl::nullopt);
 
   CharacteristicsFound(connection.get());
   NotifySessionStarted(connection.get());
@@ -1427,14 +1422,12 @@
   connection->Connect();
   ASSERT_FALSE(connection_latency_error_callback_.is_null());
 
-  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_, _))
-      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_success_callback_),
-                      MoveArg<1>(&create_gatt_connection_error_callback_)));
+  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_))
+      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_callback_)));
   std::move(connection_latency_error_callback_).Run();
-  EXPECT_FALSE(create_gatt_connection_error_callback_.is_null());
-  ASSERT_FALSE(create_gatt_connection_success_callback_.is_null());
+  ASSERT_FALSE(create_gatt_connection_callback_.is_null());
 
-  // Preparing |connection| to run |create_gatt_connection_success_callback_|.
+  // Preparing |connection| to run |create_gatt_connection_callback_|.
   EXPECT_CALL(*connection, CreateCharacteristicsFinder_(_, _))
       .WillOnce(DoAll(
           MoveArg<0>(&characteristics_finder_success_callback_),
@@ -1442,9 +1435,10 @@
           Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>(
               remote_device_))));
 
-  std::move(create_gatt_connection_success_callback_)
+  std::move(create_gatt_connection_callback_)
       .Run(std::make_unique<NiceMock<device::MockBluetoothGattConnection>>(
-          adapter_, kTestRemoteDeviceBluetoothAddress));
+               adapter_, kTestRemoteDeviceBluetoothAddress),
+           /*error_code=*/absl::nullopt);
 
   CharacteristicsFound(connection.get());
   NotifySessionStarted(connection.get());
@@ -1476,22 +1470,20 @@
   ASSERT_FALSE(connection_latency_callback_.is_null());
   ASSERT_FALSE(connection_latency_error_callback_.is_null());
 
-  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_, _))
-      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_success_callback_),
-                      MoveArg<1>(&create_gatt_connection_error_callback_)));
+  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_))
+      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_callback_)));
 
   // Simulate a timeout.
   test_timer_->Fire();
 
-  EXPECT_FALSE(create_gatt_connection_error_callback_.is_null());
-  ASSERT_FALSE(create_gatt_connection_success_callback_.is_null());
+  ASSERT_FALSE(create_gatt_connection_callback_.is_null());
 
   // Robustness check: simulate the SetConnectionLatency success callback firing
   // while a GATT connection is in progress. It should recognize that a GATT
   // connection is in progress and not call CreateGattConnection a 2nd time.
   std::move(connection_latency_callback_).Run();
 
-  // Preparing |connection| to run |create_gatt_connection_success_callback_|.
+  // Preparing |connection| to run |create_gatt_connection_callback_|.
   EXPECT_CALL(*connection, CreateCharacteristicsFinder_(_, _))
       .WillOnce(DoAll(
           MoveArg<0>(&characteristics_finder_success_callback_),
@@ -1499,9 +1491,10 @@
           Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>(
               remote_device_))));
 
-  std::move(create_gatt_connection_success_callback_)
+  std::move(create_gatt_connection_callback_)
       .Run(std::make_unique<NiceMock<device::MockBluetoothGattConnection>>(
-          adapter_, kTestRemoteDeviceBluetoothAddress));
+               adapter_, kTestRemoteDeviceBluetoothAddress),
+           /*error_code=*/absl::nullopt);
 
   CharacteristicsFound(connection.get());
   NotifySessionStarted(connection.get());
@@ -1527,9 +1520,8 @@
                       MoveArg<2>(&connection_latency_error_callback_)));
 
   // Preparing |connection| for a CreateGattConnection call.
-  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_, _))
-      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_success_callback_),
-                      MoveArg<1>(&create_gatt_connection_error_callback_)));
+  EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection_(_))
+      .WillOnce(DoAll(MoveArg<0>(&create_gatt_connection_callback_)));
 
   connection->Connect();
 
diff --git a/content/browser/bluetooth/web_bluetooth_pairing_manager.cc b/content/browser/bluetooth/web_bluetooth_pairing_manager.cc
index 8f504f55..9f15ed7 100644
--- a/content/browser/bluetooth/web_bluetooth_pairing_manager.cc
+++ b/content/browser/bluetooth/web_bluetooth_pairing_manager.cc
@@ -62,36 +62,28 @@
   }
 
   pending_pair_device_ids_.insert(device_id);
-  auto split_read_callback = base::SplitOnceCallback(std::move(read_callback));
   pairing_manager_delegate_->PairDevice(
       device_id, this,
-      base::BindOnce(
-          &WebBluetoothPairingManager::OnReadCharacteristicValuePairSuccess,
-          weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, device_id,
-          std::move(split_read_callback.first)),
-      base::BindOnce(
-          &WebBluetoothPairingManager::OnReadCharacteristicValuePairFailure,
-          weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, device_id,
-          num_pair_attempts + 1, std::move(split_read_callback.second)));
+      base::BindOnce(&WebBluetoothPairingManager::OnReadCharacteristicValuePair,
+                     weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id,
+                     std::move(device_id), num_pair_attempts + 1,
+                     std::move(read_callback)));
 }
 
-void WebBluetoothPairingManager::OnReadCharacteristicValuePairSuccess(
-    std::string characteristic_instance_id,
-    blink::WebBluetoothDeviceId device_id,
-    WebBluetoothService::RemoteCharacteristicReadValueCallback read_callback) {
-  pending_pair_device_ids_.erase(device_id);
-  pairing_manager_delegate_->RemoteCharacteristicReadValue(
-      characteristic_instance_id, std::move(read_callback));
-}
-
-void WebBluetoothPairingManager::OnReadCharacteristicValuePairFailure(
+void WebBluetoothPairingManager::OnReadCharacteristicValuePair(
     std::string characteristic_instance_id,
     blink::WebBluetoothDeviceId device_id,
     int num_pair_attempts,
     WebBluetoothService::RemoteCharacteristicReadValueCallback read_callback,
-    BluetoothDevice::ConnectErrorCode error_code) {
+    absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
   pending_pair_device_ids_.erase(device_id);
-  if (error_code == BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED &&
+  if (!error_code.has_value()) {
+    pairing_manager_delegate_->RemoteCharacteristicReadValue(
+        characteristic_instance_id, std::move(read_callback));
+    return;
+  }
+
+  if (*error_code == BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED &&
       num_pair_attempts < kMaxPairAttempts) {
     PairForCharacteristicReadValue(characteristic_instance_id,
                                    num_pair_attempts, std::move(read_callback));
@@ -99,7 +91,8 @@
   }
 
   std::move(read_callback)
-      .Run(WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(error_code),
+      .Run(WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(
+               error_code.value()),
            /*value=*/absl::nullopt);
 }
 
@@ -127,45 +120,36 @@
   }
   pending_pair_device_ids_.insert(device_id);
 
-  auto split_read_callback = base::SplitOnceCallback(std::move(read_callback));
   pairing_manager_delegate_->PairDevice(
       device_id, this,
-      base::BindOnce(
-          &WebBluetoothPairingManager::OnReadDescriptorValuePairSuccess,
-          weak_ptr_factory_.GetWeakPtr(), descriptor_instance_id, device_id,
-          std::move(split_read_callback.first)),
-      base::BindOnce(
-          &WebBluetoothPairingManager::OnReadDescriptorValuePairFailure,
-          weak_ptr_factory_.GetWeakPtr(), descriptor_instance_id, device_id,
-          num_pair_attempts + 1, std::move(split_read_callback.second)));
+      base::BindOnce(&WebBluetoothPairingManager::OnReadDescriptorValuePair,
+                     weak_ptr_factory_.GetWeakPtr(), descriptor_instance_id,
+                     device_id, num_pair_attempts + 1,
+                     std::move(read_callback)));
 }
 
-void WebBluetoothPairingManager::OnReadDescriptorValuePairSuccess(
-    std::string descriptor_instance_id,
-    blink::WebBluetoothDeviceId device_id,
-    WebBluetoothService::RemoteDescriptorReadValueCallback read_callback) {
-  pending_pair_device_ids_.erase(device_id);
-  pairing_manager_delegate_->RemoteDescriptorReadValue(
-      descriptor_instance_id, std::move(read_callback));
-}
-
-void WebBluetoothPairingManager::OnReadDescriptorValuePairFailure(
+void WebBluetoothPairingManager::OnReadDescriptorValuePair(
     std::string descriptor_instance_id,
     blink::WebBluetoothDeviceId device_id,
     int num_pair_attempts,
-    WebBluetoothService::RemoteDescriptorReadValueCallback read_callback,
-    BluetoothDevice::ConnectErrorCode error_code) {
+    WebBluetoothService::RemoteDescriptorReadValueCallback callback,
+    absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
   pending_pair_device_ids_.erase(device_id);
-  if (error_code == BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED &&
+  if (!error_code) {
+    pairing_manager_delegate_->RemoteDescriptorReadValue(descriptor_instance_id,
+                                                         std::move(callback));
+    return;
+  }
+  if (*error_code == BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED &&
       num_pair_attempts < kMaxPairAttempts) {
     PairForDescriptorReadValue(descriptor_instance_id, num_pair_attempts,
-                               std::move(read_callback));
+                               std::move(callback));
     return;
   }
 
-  std::move(read_callback)
-      .Run(WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(error_code),
-           /*value=*/absl::nullopt);
+  std::move(callback).Run(
+      WebBluetoothServiceImpl::TranslateConnectErrorAndRecord(*error_code),
+      /*value=*/absl::nullopt);
 }
 
 void WebBluetoothPairingManager::RequestPinCode(BluetoothDevice* device) {
diff --git a/content/browser/bluetooth/web_bluetooth_pairing_manager.h b/content/browser/bluetooth/web_bluetooth_pairing_manager.h
index da950cf3..e4cdfdd0 100644
--- a/content/browser/bluetooth/web_bluetooth_pairing_manager.h
+++ b/content/browser/bluetooth/web_bluetooth_pairing_manager.h
@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
 #include "device/bluetooth/bluetooth_device.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h"
 
 namespace content {
@@ -60,33 +61,21 @@
           read_callback);
 
  private:
-  void OnReadCharacteristicValuePairSuccess(
-      std::string characteristic_instance_id,
-      blink::WebBluetoothDeviceId device_id,
-      blink::mojom::WebBluetoothService::RemoteCharacteristicReadValueCallback
-          read_callback);
-
-  void OnReadCharacteristicValuePairFailure(
+  void OnReadCharacteristicValuePair(
       std::string characteristic_instance_id,
       blink::WebBluetoothDeviceId device_id,
       int num_pair_attempts,
       blink::mojom::WebBluetoothService::RemoteCharacteristicReadValueCallback
           read_callback,
-      device::BluetoothDevice::ConnectErrorCode error_code);
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
 
-  void OnReadDescriptorValuePairSuccess(
-      std::string descriptor_instance_id,
-      blink::WebBluetoothDeviceId device_id,
-      blink::mojom::WebBluetoothService::RemoteDescriptorReadValueCallback
-          read_callback);
-
-  void OnReadDescriptorValuePairFailure(
+  void OnReadDescriptorValuePair(
       std::string descriptor_instance_id,
       blink::WebBluetoothDeviceId device_id,
       int num_pair_attempts,
       blink::mojom::WebBluetoothService::RemoteDescriptorReadValueCallback
           read_callback,
-      device::BluetoothDevice::ConnectErrorCode error_code);
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
 
   // device::BluetoothPairingDelegate implementation:
   void RequestPinCode(device::BluetoothDevice* device) override;
diff --git a/content/browser/bluetooth/web_bluetooth_pairing_manager_delegate.h b/content/browser/bluetooth/web_bluetooth_pairing_manager_delegate.h
index 5cf1b13..ababa1c 100644
--- a/content/browser/bluetooth/web_bluetooth_pairing_manager_delegate.h
+++ b/content/browser/bluetooth/web_bluetooth_pairing_manager_delegate.h
@@ -35,8 +35,7 @@
   virtual void PairDevice(
       const blink::WebBluetoothDeviceId& device_id,
       device::BluetoothDevice::PairingDelegate* pairing_delegate,
-      base::OnceClosure callback,
-      device::BluetoothDevice::ConnectErrorCallback error_callback) = 0;
+      device::BluetoothDevice::ConnectCallback callback) = 0;
 
   // Cancels a pairing attempt to a remote device, clearing its reference to
   // the pairing delegate.
diff --git a/content/browser/bluetooth/web_bluetooth_pairing_manager_unittest.cc b/content/browser/bluetooth/web_bluetooth_pairing_manager_unittest.cc
index e3da81c..00cc0d9c 100644
--- a/content/browser/bluetooth/web_bluetooth_pairing_manager_unittest.cc
+++ b/content/browser/bluetooth/web_bluetooth_pairing_manager_unittest.cc
@@ -61,11 +61,9 @@
     return invalid_device_id;
   }
 
-  void PairDevice(
-      const WebBluetoothDeviceId& device_id,
-      device::BluetoothDevice::PairingDelegate* pairing_delegate,
-      base::OnceClosure callback,
-      BluetoothDevice::ConnectErrorCallback error_callback) override {
+  void PairDevice(const WebBluetoothDeviceId& device_id,
+                  device::BluetoothDevice::PairingDelegate* pairing_delegate,
+                  BluetoothDevice::ConnectCallback callback) override {
     ASSERT_TRUE(device_id.IsValid());
     EXPECT_EQ(device_id, valid_device_id);
     num_pair_attempts_++;
@@ -74,40 +72,36 @@
       case AuthBehavior::kSucceedFirst:
         EXPECT_EQ(1, num_pair_attempts_);
         device_paired_ = true;
-        std::move(callback).Run();
+        std::move(callback).Run(/*error_code=*/absl::nullopt);
         break;
       case AuthBehavior::kSucceedSecond:
         switch (num_pair_attempts_) {
           case 1:
-            std::move(error_callback).Run(BluetoothDevice::ERROR_AUTH_REJECTED);
+            std::move(callback).Run(BluetoothDevice::ERROR_AUTH_REJECTED);
             break;
           case 2:
             device_paired_ = true;
-            std::move(callback).Run();
+            std::move(callback).Run(/*error_code=*/absl::nullopt);
             break;
           default:
             NOTREACHED();
-            std::move(error_callback).Run(BluetoothDevice::ERROR_UNKNOWN);
+            std::move(callback).Run(BluetoothDevice::ERROR_UNKNOWN);
         }
         break;
       case AuthBehavior::kFailAll:
-        std::move(error_callback).Run(BluetoothDevice::ERROR_AUTH_REJECTED);
+        std::move(callback).Run(BluetoothDevice::ERROR_AUTH_REJECTED);
         break;
       case AuthBehavior::kSuspend:
         EXPECT_TRUE(pair_callback_.is_null());
-        EXPECT_TRUE(pair_error_callback_.is_null());
         pair_callback_ = std::move(callback);
-        pair_error_callback_ = std::move(error_callback);
         break;
       case AuthBehavior::kFirstSuspend:
         if (num_pair_attempts_ == 1) {
           EXPECT_TRUE(pair_callback_.is_null());
-          EXPECT_TRUE(pair_error_callback_.is_null());
           pair_callback_ = std::move(callback);
-          pair_error_callback_ = std::move(error_callback);
         } else {
           device_paired_ = true;
-          std::move(callback).Run();
+          std::move(callback).Run(/*error_code=*/absl::nullopt);
         }
         break;
       case AuthBehavior::kUnspecified:
@@ -119,16 +113,13 @@
   void CancelPairing(const WebBluetoothDeviceId& device_id) override {
     ASSERT_TRUE(device_id.IsValid());
     EXPECT_EQ(device_id, valid_device_id);
-    pair_callback_.Reset();
-    EXPECT_FALSE(pair_error_callback_.is_null());
-    std::move(pair_error_callback_).Run(BluetoothDevice::ERROR_AUTH_CANCELED);
+    std::move(pair_callback_).Run(BluetoothDevice::ERROR_AUTH_CANCELED);
   }
 
   void ResumeSuspendedPairingWithSuccess() {
     device_paired_ = true;
-    pair_error_callback_.Reset();
     EXPECT_FALSE(pair_callback_.is_null());
-    std::move(pair_callback_).Run();
+    std::move(pair_callback_).Run(/*error+_code=*/absl::nullopt);
   }
 
   void RemoteCharacteristicReadValue(
@@ -198,8 +189,7 @@
  private:
   int num_pair_attempts_ = 0;
   bool device_paired_ = false;
-  base::OnceClosure pair_callback_;
-  BluetoothDevice::ConnectErrorCallback pair_error_callback_;
+  BluetoothDevice::ConnectCallback pair_callback_;
   AuthBehavior auth_behavior_ = AuthBehavior::kUnspecified;
   const std::string characteristic_instance_id_ = "valid-id-for-tesing";
   const std::string invalid_characteristic_instance_id_ = "invalid-id";
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.cc b/content/browser/bluetooth/web_bluetooth_service_impl.cc
index 5878586..05def03 100644
--- a/content/browser/bluetooth/web_bluetooth_service_impl.cc
+++ b/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -923,18 +923,10 @@
   mojo::AssociatedRemote<blink::mojom::WebBluetoothServerClient>
       web_bluetooth_server_client(std::move(client));
 
-  // TODO(crbug.com/730593): Remove SplitOnceCallback() by updating
-  // the callee interface. The |callback| will only be called once, but it is
-  // passed to both the success and error callbacks.
-  auto split_callback = base::SplitOnceCallback(std::move(callback));
-  query_result.device->CreateGattConnection(
-      base::BindOnce(&WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess,
-                     weak_ptr_factory_.GetWeakPtr(), device_id, start_time,
-                     std::move(web_bluetooth_server_client),
-                     std::move(split_callback.first)),
-      base::BindOnce(&WebBluetoothServiceImpl::OnCreateGATTConnectionFailed,
-                     weak_ptr_factory_.GetWeakPtr(), start_time,
-                     std::move(split_callback.second)));
+  query_result.device->CreateGattConnection(base::BindOnce(
+      &WebBluetoothServiceImpl::OnCreateGATTConnection,
+      weak_ptr_factory_.GetWeakPtr(), device_id, start_time,
+      std::move(web_bluetooth_server_client), std::move(callback)));
 }
 
 void WebBluetoothServiceImpl::RemoteServerDisconnect(
@@ -1889,13 +1881,19 @@
                           std::move(web_bluetooth_device));
 }
 
-void WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess(
+void WebBluetoothServiceImpl::OnCreateGATTConnection(
     const blink::WebBluetoothDeviceId& device_id,
     base::TimeTicks start_time,
     mojo::AssociatedRemote<blink::mojom::WebBluetoothServerClient> client,
     RemoteServerConnectCallback callback,
-    std::unique_ptr<BluetoothGattConnection> connection) {
+    std::unique_ptr<BluetoothGattConnection> connection,
+    absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (error_code.has_value()) {
+    RecordConnectGATTTimeFailed(base::TimeTicks::Now() - start_time);
+    std::move(callback).Run(TranslateConnectErrorAndRecord(error_code.value()));
+    return;
+  }
   RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time);
   RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS);
 
@@ -1910,15 +1908,6 @@
                              std::move(client));
 }
 
-void WebBluetoothServiceImpl::OnCreateGATTConnectionFailed(
-    base::TimeTicks start_time,
-    RemoteServerConnectCallback callback,
-    BluetoothDevice::ConnectErrorCode error_code) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  RecordConnectGATTTimeFailed(base::TimeTicks::Now() - start_time);
-  std::move(callback).Run(TranslateConnectErrorAndRecord(error_code));
-}
-
 void WebBluetoothServiceImpl::OnCharacteristicReadValue(
     RemoteCharacteristicReadValueCallback callback,
     absl::optional<BluetoothGattService::GattErrorCode> error_code,
@@ -2369,25 +2358,21 @@
 void WebBluetoothServiceImpl::PairDevice(
     const blink::WebBluetoothDeviceId& device_id,
     BluetoothDevice::PairingDelegate* pairing_delegate,
-    base::OnceClosure callback,
-    BluetoothDevice::ConnectErrorCallback error_callback) {
+    BluetoothDevice::ConnectCallback callback) {
   if (!device_id.IsValid()) {
-    std::move(error_callback)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN);
+    std::move(callback).Run(BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN);
     return;
   }
 
   BluetoothDevice* device = GetCachedDevice(device_id);
   if (!device) {
-    std::move(error_callback)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN);
+    std::move(callback).Run(BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN);
     return;
   }
 
   DCHECK(!device->IsPaired());
 
-  device->Pair(pairing_delegate, std::move(callback),
-               std::move(error_callback));
+  device->Pair(pairing_delegate, std::move(callback));
 }
 
 void WebBluetoothServiceImpl::CancelPairing(
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.h b/content/browser/bluetooth/web_bluetooth_service_impl.h
index 886c3545..a81552a 100644
--- a/content/browser/bluetooth/web_bluetooth_service_impl.h
+++ b/content/browser/bluetooth/web_bluetooth_service_impl.h
@@ -290,16 +290,13 @@
                    const std::string& device_id);
 
   // Callbacks for BluetoothDevice::CreateGattConnection.
-  void OnCreateGATTConnectionSuccess(
+  void OnCreateGATTConnection(
       const blink::WebBluetoothDeviceId& device_id,
       base::TimeTicks start_time,
       mojo::AssociatedRemote<blink::mojom::WebBluetoothServerClient> client,
       RemoteServerConnectCallback callback,
-      std::unique_ptr<device::BluetoothGattConnection> connection);
-  void OnCreateGATTConnectionFailed(
-      base::TimeTicks start_time,
-      RemoteServerConnectCallback callback,
-      device::BluetoothDevice::ConnectErrorCode error_code);
+      std::unique_ptr<device::BluetoothGattConnection> connection,
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
 
   // Callbacks for BluetoothRemoteGattCharacteristic::ReadRemoteCharacteristic.
   void OnCharacteristicReadValue(
@@ -409,11 +406,9 @@
       const std::string& characteristic_instance_id) override;
   blink::WebBluetoothDeviceId GetDescriptorDeviceId(
       const std::string& descriptor_instance_id) override;
-  void PairDevice(
-      const blink::WebBluetoothDeviceId& device_id,
-      device::BluetoothDevice::PairingDelegate* pairing_delegate,
-      base::OnceClosure callback,
-      device::BluetoothDevice::ConnectErrorCallback error_callback) override;
+  void PairDevice(const blink::WebBluetoothDeviceId& device_id,
+                  device::BluetoothDevice::PairingDelegate* pairing_delegate,
+                  device::BluetoothDevice::ConnectCallback callback) override;
   void CancelPairing(const blink::WebBluetoothDeviceId& device_id) override;
 
   // Used to open a BluetoothChooser and start a device discovery session.
diff --git a/content/web_test/browser/web_test_bluetooth_adapter_provider.cc b/content/web_test/browser/web_test_bluetooth_adapter_provider.cc
index 88c2f7f..5f80c83 100644
--- a/content/web_test/browser/web_test_bluetooth_adapter_provider.cc
+++ b/content/web_test/browser/web_test_bluetooth_adapter_provider.cc
@@ -141,6 +141,14 @@
   return std::move(std::get<k>(args)).Run(p0, func());
 }
 
+// Invokes Run() on the k-th argument of the function with the
+// result from func and argument p1
+ACTION_TEMPLATE(RunCallbackWithFunctionResult,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_2_VALUE_PARAMS(func, p1)) {
+  return std::move(std::get<k>(args)).Run(func(), p1);
+}
+
 // Function to iterate over the adapter's devices and return the one
 // that matches the address.
 ACTION_P(GetMockDevice, adapter) {
@@ -922,8 +930,8 @@
   // Gatt connection. When called after after IsGattDiscoveryComplete runs
   // success callback with a new Gatt connection and notifies of services
   // discovered.
-  ON_CALL(*device, CreateGattConnection_(_, _))
-      .WillByDefault(RunCallbackWithResult<0 /* success_callback */>(
+  ON_CALL(*device, CreateGattConnection_(_))
+      .WillByDefault(RunCallbackWithFunctionResult<0 /* callback */>(
           [adapter_ptr, device_ptr]() {
             std::vector<BluetoothRemoteGattService*> services =
                 device_ptr->GetMockServices();
@@ -938,7 +946,8 @@
             device_ptr->SetConnected(true);
             return std::make_unique<NiceMockBluetoothGattConnection>(
                 adapter_ptr, device_ptr->GetAddress());
-          }));
+          },
+          /*error_code=*/absl::nullopt));
 
   // The first time this function is called we:
   // 1. Add a service (This indicates that this function has been called)
@@ -988,15 +997,15 @@
                                  BluetoothUUID(kHealthThermometerUUID)})));
   NiceMockBluetoothDevice* device_ptr = device.get();
 
-  ON_CALL(*device, CreateGattConnection_(_, _))
+  ON_CALL(*device, CreateGattConnection_(_))
       .WillByDefault(
           Invoke([adapter_ptr, device_ptr](
-                     BluetoothDevice::GattConnectionCallback& callback,
-                     BluetoothDevice::ConnectErrorCallback& error_callback) {
+                     BluetoothDevice::GattConnectionCallback& callback) {
             device_ptr->SetConnected(true);
             std::move(callback).Run(
                 std::make_unique<NiceMockBluetoothGattConnection>(
-                    adapter_ptr, device_ptr->GetAddress()));
+                    adapter_ptr, device_ptr->GetAddress()),
+                /*error_code=*/absl::nullopt);
             device_ptr->RunPendingCallbacks();
           }));
 
@@ -1184,15 +1193,15 @@
                                  BluetoothUUID(kHealthThermometerUUID)})));
   NiceMockBluetoothDevice* device_ptr = device.get();
 
-  ON_CALL(*device, CreateGattConnection_(_, _))
+  ON_CALL(*device, CreateGattConnection_(_))
       .WillByDefault(
           Invoke([adapter_ptr, device_ptr](
-                     BluetoothDevice::GattConnectionCallback& callback,
-                     BluetoothDevice::ConnectErrorCallback& error_callback) {
+                     BluetoothDevice::GattConnectionCallback& callback) {
             device_ptr->SetConnected(true);
             std::move(callback).Run(
                 std::make_unique<NiceMockBluetoothGattConnection>(
-                    adapter_ptr, device_ptr->GetAddress()));
+                    adapter_ptr, device_ptr->GetAddress()),
+                /*error_code=*/absl::nullopt);
             device_ptr->RunPendingCallbacks();
           }));
 
@@ -1342,9 +1351,9 @@
       .WillByDefault(
           Invoke(device.get(), &MockBluetoothDevice::GetMockService));
 
-  ON_CALL(*device, CreateGattConnection_(_, _))
-      .WillByDefault(RunCallback<1 /* error_callback */>(
-          BluetoothDevice::ERROR_UNSUPPORTED_DEVICE));
+  ON_CALL(*device, CreateGattConnection_(_))
+      .WillByDefault(RunOnceCallback<0>(
+          /*connection=*/nullptr, BluetoothDevice::ERROR_UNSUPPORTED_DEVICE));
 
   return device;
 }
@@ -1386,12 +1395,15 @@
 
   MockBluetoothDevice* device_ptr = device.get();
 
-  ON_CALL(*device, CreateGattConnection_(_, _))
-      .WillByDefault(RunCallbackWithResult<0 /* success_callback */>(
-          [adapter, device_ptr]() {
+  ON_CALL(*device, CreateGattConnection_(_))
+      .WillByDefault(
+          Invoke([adapter, device_ptr](
+                     BluetoothDevice::GattConnectionCallback& callback) {
             device_ptr->SetConnected(true);
-            return std::make_unique<NiceMockBluetoothGattConnection>(
-                adapter, device_ptr->GetAddress());
+            std::move(callback).Run(
+                std::make_unique<NiceMockBluetoothGattConnection>(
+                    adapter, device_ptr->GetAddress()),
+                /*error_code=*/absl::nullopt);
           }));
 
   ON_CALL(*device, IsGattServicesDiscoveryComplete())
@@ -1412,8 +1424,8 @@
   auto device(
       GetBaseDevice(adapter, device_name, uuids, makeMACAddress(error_code)));
 
-  ON_CALL(*device, CreateGattConnection_(_, _))
-      .WillByDefault(RunOnceCallback<1 /* error_callback */>(error_code));
+  ON_CALL(*device, CreateGattConnection_(_))
+      .WillByDefault(RunOnceCallback<0>(/*connection=*/nullptr, error_code));
 
   return device;
 }
diff --git a/device/bluetooth/adapter.cc b/device/bluetooth/adapter.cc
index 7dca1f4..f069be6 100644
--- a/device/bluetooth/adapter.cc
+++ b/device/bluetooth/adapter.cc
@@ -85,12 +85,9 @@
     return;
   }
 
-  auto split_callback = base::SplitOnceCallback(std::move(callback));
-  device->CreateGattConnection(
-      base::BindOnce(&Adapter::OnGattConnected, weak_ptr_factory_.GetWeakPtr(),
-                     std::move(split_callback.first)),
-      base::BindOnce(&Adapter::OnConnectError, weak_ptr_factory_.GetWeakPtr(),
-                     std::move(split_callback.second)));
+  device->CreateGattConnection(base::BindOnce(&Adapter::OnGattConnect,
+                                              weak_ptr_factory_.GetWeakPtr(),
+                                              std::move(callback)));
 }
 
 void Adapter::GetDevices(GetDevicesCallback callback) {
@@ -395,22 +392,22 @@
   }
 }
 
-void Adapter::OnGattConnected(
+void Adapter::OnGattConnect(
     ConnectToDeviceCallback callback,
-    std::unique_ptr<device::BluetoothGattConnection> connection) {
+    std::unique_ptr<device::BluetoothGattConnection> connection,
+    absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
+  if (error_code.has_value()) {
+    std::move(callback).Run(
+        mojo::ConvertTo<mojom::ConnectResult>(error_code.value()),
+        /*device=*/mojo::NullRemote());
+    return;
+  }
   mojo::PendingRemote<mojom::Device> device;
   Device::Create(adapter_, std::move(connection),
                  device.InitWithNewPipeAndPassReceiver());
   std::move(callback).Run(mojom::ConnectResult::SUCCESS, std::move(device));
 }
 
-void Adapter::OnConnectError(
-    ConnectToDeviceCallback callback,
-    device::BluetoothDevice::ConnectErrorCode error_code) {
-  std::move(callback).Run(mojo::ConvertTo<mojom::ConnectResult>(error_code),
-                          /*device=*/mojo::NullRemote());
-}
-
 void Adapter::OnRegisterAdvertisement(
     RegisterAdvertisementCallback callback,
     scoped_refptr<device::BluetoothAdvertisement> advertisement) {
diff --git a/device/bluetooth/adapter.h b/device/bluetooth/adapter.h
index 8fc3865..b251917 100644
--- a/device/bluetooth/adapter.h
+++ b/device/bluetooth/adapter.h
@@ -100,11 +100,10 @@
       const std::string& address,
       device::BluetoothDevice* device);
 
-  void OnGattConnected(
+  void OnGattConnect(
       ConnectToDeviceCallback callback,
-      std::unique_ptr<device::BluetoothGattConnection> connection);
-  void OnConnectError(ConnectToDeviceCallback callback,
-                      device::BluetoothDevice::ConnectErrorCode error_code);
+      std::unique_ptr<device::BluetoothGattConnection> connection,
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
 
   void OnRegisterAdvertisement(
       RegisterAdvertisementCallback callback,
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index 717daca..54d9024 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -862,7 +862,7 @@
   DVLOG(1) << *device_mac << ": Failed to connect to peripheral with error "
            << BluetoothAdapterMac::String(error)
            << ", error code: " << error_code;
-  device_mac->DidFailToConnectGatt(error_code);
+  device_mac->DidConnectGatt(error_code);
 }
 
 void BluetoothAdapterMac::DidDisconnectPeripheral(CBPeripheral* peripheral,
diff --git a/device/bluetooth/bluetooth_adapter_mac_metrics_unittest.mm b/device/bluetooth/bluetooth_adapter_mac_metrics_unittest.mm
index b922b73..838ca21 100644
--- a/device/bluetooth/bluetooth_adapter_mac_metrics_unittest.mm
+++ b/device/bluetooth/bluetooth_adapter_mac_metrics_unittest.mm
@@ -23,8 +23,8 @@
   void FakeServiceBoilerPlate() {
     ASSERT_NO_FATAL_FAILURE(FakeDeviceBoilerPlate());
 
-    device_->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                  GetConnectErrorCallback(Call::NOT_EXPECTED));
+    device_->CreateGattConnection(
+        GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
     SimulateGattConnection(device_);
     base::RunLoop().RunUntilIdle();
     SimulateGattServicesDiscovered(
@@ -171,4 +171,4 @@
       "Bluetooth.MacOS.Errors.DidWriteValueForDescriptor", 1);
 }
 
-}
\ No newline at end of file
+}  // namespace device
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc
index ed515821..649b7ee6 100644
--- a/device/bluetooth/bluetooth_adapter_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -1460,8 +1460,8 @@
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
 
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
 
@@ -1913,8 +1913,8 @@
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(1);
   device->SetAsExpiredForTesting();
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1u, adapter_->GetDevices().size());
diff --git a/device/bluetooth/bluetooth_classic_device_mac.h b/device/bluetooth/bluetooth_classic_device_mac.h
index 88e45b2..05208ee 100644
--- a/device/bluetooth/bluetooth_classic_device_mac.h
+++ b/device/bluetooth/bluetooth_classic_device_mac.h
@@ -55,8 +55,7 @@
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
   void Connect(PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+               ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
diff --git a/device/bluetooth/bluetooth_classic_device_mac.mm b/device/bluetooth/bluetooth_classic_device_mac.mm
index 503a27a..7724fd4d 100644
--- a/device/bluetooth/bluetooth_classic_device_mac.mm
+++ b/device/bluetooth/bluetooth_classic_device_mac.mm
@@ -76,7 +76,7 @@
 void BluetoothClassicDeviceMac::CreateGattConnectionImpl(
     absl::optional<BluetoothUUID> service_uuid) {
   // Classic devices do not support GATT connection.
-  DidFailToConnectGatt(ERROR_UNSUPPORTED_DEVICE);
+  DidConnectGatt(ERROR_UNSUPPORTED_DEVICE);
 }
 
 void BluetoothClassicDeviceMac::DisconnectGatt() {}
@@ -209,8 +209,7 @@
 }
 
 void BluetoothClassicDeviceMac::Connect(PairingDelegate* pairing_delegate,
-                                        base::OnceClosure callback,
-                                        ConnectErrorCallback error_callback) {
+                                        ConnectCallback callback) {
   NOTIMPLEMENTED();
 }
 
diff --git a/device/bluetooth/bluetooth_device.cc b/device/bluetooth/bluetooth_device.cc
index e269c80..fc2c0a4 100644
--- a/device/bluetooth/bluetooth_device.cc
+++ b/device/bluetooth/bluetooth_device.cc
@@ -356,16 +356,14 @@
 
 void BluetoothDevice::CreateGattConnection(
     GattConnectionCallback callback,
-    ConnectErrorCallback error_callback,
     absl::optional<BluetoothUUID> service_uuid) {
   if (!supports_service_specific_discovery_)
     service_uuid.reset();
 
   const bool connection_already_pending =
-      !create_gatt_connection_success_callbacks_.empty();
+      !create_gatt_connection_callbacks_.empty();
 
-  create_gatt_connection_success_callbacks_.push_back(std::move(callback));
-  create_gatt_connection_error_callbacks_.push_back(std::move(error_callback));
+  create_gatt_connection_callbacks_.push_back(std::move(callback));
 
   // If a service-specific discovery was originally requested, but this request
   // is for a different or non-specific discovery, then the previous discovery
@@ -378,7 +376,7 @@
 
   if (IsGattConnected()) {
     DCHECK(!connection_already_pending);
-    return DidConnectGatt();
+    return DidConnectGatt(/*error_code=*/absl::nullopt);
   }
 
   if (connection_already_pending) {
@@ -500,32 +498,33 @@
   return std::make_unique<BluetoothGattConnection>(adapter_, GetAddress());
 }
 
-void BluetoothDevice::DidConnectGatt() {
-  for (auto& callback : create_gatt_connection_success_callbacks_)
-    std::move(callback).Run(CreateBluetoothGattConnectionObject());
+void BluetoothDevice::DidConnectGatt(absl::optional<ConnectErrorCode> error) {
+  if (error.has_value()) {
+    // Connection request should only be made if there are no active
+    // connections.
+    DCHECK(gatt_connections_.empty());
 
-  create_gatt_connection_success_callbacks_.clear();
-  create_gatt_connection_error_callbacks_.clear();
+    target_service_.reset();
+
+    for (auto& callback : create_gatt_connection_callbacks_)
+      std::move(callback).Run(/*connection=*/nullptr, error.value());
+    create_gatt_connection_callbacks_.clear();
+    return;
+  }
+
+  for (auto& callback : create_gatt_connection_callbacks_) {
+    std::move(callback).Run(CreateBluetoothGattConnectionObject(),
+                            /*error_code=*/absl::nullopt);
+  }
+
+  create_gatt_connection_callbacks_.clear();
   GetAdapter()->NotifyDeviceChanged(this);
 }
 
-void BluetoothDevice::DidFailToConnectGatt(ConnectErrorCode error) {
-  // Connection request should only be made if there are no active
-  // connections.
-  DCHECK(gatt_connections_.empty());
-
-  target_service_.reset();
-
-  for (auto& error_callback : create_gatt_connection_error_callbacks_)
-    std::move(error_callback).Run(error);
-  create_gatt_connection_success_callbacks_.clear();
-  create_gatt_connection_error_callbacks_.clear();
-}
-
 void BluetoothDevice::DidDisconnectGatt() {
   // Pending calls to connect GATT are not expected, if they were then
-  // DidFailToConnectGatt should have been called.
-  DCHECK(create_gatt_connection_error_callbacks_.empty());
+  // DidConnectGatt should have been called.
+  DCHECK(create_gatt_connection_callbacks_.empty());
 
   target_service_.reset();
 
@@ -557,8 +556,7 @@
 }
 
 void BluetoothDevice::Pair(PairingDelegate* pairing_delegate,
-                           base::OnceClosure callback,
-                           ConnectErrorCallback error_callback) {
+                           ConnectCallback callback) {
   NOTREACHED();
 }
 
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h
index 29ecb88f..de6f39dc 100644
--- a/device/bluetooth/bluetooth_device.h
+++ b/device/bluetooth/bluetooth_device.h
@@ -385,10 +385,10 @@
   // is called, in the success case the callback is simply not called.
   using ErrorCallback = base::OnceClosure;
 
-  // The ConnectErrorCallback is used for methods that can fail with an error,
-  // passed back as an error code argument to this callback.
-  // In the success case this callback is not called.
-  using ConnectErrorCallback = base::OnceCallback<void(enum ConnectErrorCode)>;
+  // Reports the status of a device connection attempt. |error_code| will
+  // contain a value upon failure, otherwise the attempt was successful.
+  using ConnectCallback =
+      base::OnceCallback<void(absl::optional<ConnectErrorCode> error_code)>;
 
   using ConnectionInfoCallback =
       base::OnceCallback<void(const ConnectionInfo&)>;
@@ -435,14 +435,12 @@
   // calls. To explicitly force a low-security connection without bonding,
   // pass NULL, though this is ignored if the device is already paired.
   //
-  // If the request fails, |error_callback| will be called; otherwise,
-  // |callback| is called when the request is complete.
+  // |callback| will be called with the status of the connection attempt.
   // After calling Connect, CancelPairing should be called to cancel the pairing
   // process and release the pairing delegate if user cancels the pairing and
   // closes the pairing UI.
   virtual void Connect(PairingDelegate* pairing_delegate,
-                       base::OnceClosure callback,
-                       ConnectErrorCallback error_callback) = 0;
+                       ConnectCallback callback) = 0;
 
   // Pairs the device. This method triggers pairing unconditially, i.e. it
   // ignores the |IsPaired()| value.
@@ -451,8 +449,7 @@
   // implemented on ChromeOS, Linux and Windows 10. On Windows, only pairing
   // with a pin code is currently supported.
   virtual void Pair(PairingDelegate* pairing_delegate,
-                    base::OnceClosure callback,
-                    ConnectErrorCallback error_callback);
+                    ConnectCallback callback);
 
   // Sends the PIN code |pincode| to the remote device during pairing.
   //
@@ -525,9 +522,10 @@
       ConnectToServiceCallback callback,
       ConnectToServiceErrorCallback error_callback) = 0;
 
-  // Opens a new GATT connection to this device. On success, a new
-  // BluetoothGattConnection will be handed to the caller via |callback|. On
-  // error, |error_callback| will be called. The connection will be kept alive,
+  // Opens a new GATT connection to this device. On success, |callback| will
+  // be called with a valid BluetoothGattConnection and |error_code| will have
+  // no value. On error, |callback| will be called with a null connection and
+  // a valid |error_code|. The connection will be kept alive,
   // as long as there is at least one active GATT connection. In the case that
   // the underlying connection gets terminated, either due to a call to
   // BluetoothDevice::Disconnect or other unexpected circumstances, the
@@ -543,10 +541,10 @@
   // |BluetoothAdapter::Observer::GattServicesDiscovered| is still the correct
   // event to watch for.
   using GattConnectionCallback =
-      base::OnceCallback<void(std::unique_ptr<BluetoothGattConnection>)>;
+      base::OnceCallback<void(std::unique_ptr<BluetoothGattConnection>,
+                              absl::optional<ConnectErrorCode> error_code)>;
   virtual void CreateGattConnection(
       GattConnectionCallback callback,
-      ConnectErrorCallback error_callback,
       absl::optional<BluetoothUUID> service_uuid = absl::nullopt);
 
   // Set the gatt services discovery complete flag for this device.
@@ -692,9 +690,8 @@
   explicit BluetoothDevice(BluetoothAdapter* adapter);
 
   // Implements platform specific operations to initiate a GATT connection.
-  // Subclasses must also call DidConnectGatt, DidFailToConnectGatt, or
-  // DidDisconnectGatt immediately or asynchronously as the connection state
-  // changes.
+  // Subclasses must also call DidConnectGatt or DidDisconnectGatt immediately
+  // or asynchronously as the connection state changes.
   virtual void CreateGattConnectionImpl(
       absl::optional<BluetoothUUID> service_uuid) = 0;
 
@@ -719,10 +716,8 @@
   // to ensure a change in platform state is correctly tracked.
   //
   // Under normal behavior it is expected that after CreateGattConnectionImpl
-  // an platform will call DidConnectGatt or DidFailToConnectGatt, but not
-  // DidDisconnectGatt.
-  void DidConnectGatt();
-  void DidFailToConnectGatt(ConnectErrorCode);
+  // a platform will call DidConnectGatt but not DidDisconnectGatt.
+  void DidConnectGatt(absl::optional<ConnectErrorCode> error_code);
   void DidDisconnectGatt();
 
   // Tracks BluetoothGattConnection instances that act as a reference count
@@ -747,9 +742,8 @@
   // contains a value if |supports_service_specific_discovery_| is true.
   absl::optional<BluetoothUUID> target_service_;
 
-  // Callbacks for pending success and error result of CreateGattConnection.
-  std::vector<GattConnectionCallback> create_gatt_connection_success_callbacks_;
-  std::vector<ConnectErrorCallback> create_gatt_connection_error_callbacks_;
+  // Callbacks for result of CreateGattConnection.
+  std::vector<GattConnectionCallback> create_gatt_connection_callbacks_;
 
   // BluetoothGattConnection objects keeping the GATT connection alive.
   std::set<BluetoothGattConnection*> gatt_connections_;
diff --git a/device/bluetooth/bluetooth_device_android.cc b/device/bluetooth/bluetooth_device_android.cc
index 7fa255db..7bcd8d8 100644
--- a/device/bluetooth/bluetooth_device_android.cc
+++ b/device/bluetooth/bluetooth_device_android.cc
@@ -143,8 +143,7 @@
 }
 
 void BluetoothDeviceAndroid::Connect(PairingDelegate* pairing_delegate,
-                                     base::OnceClosure callback,
-                                     ConnectErrorCallback error_callback) {
+                                     ConnectCallback callback) {
   NOTIMPLEMENTED();
 }
 
@@ -200,13 +199,13 @@
     bool connected) {
   gatt_connected_ = connected;
   if (gatt_connected_) {
-    DidConnectGatt();
-  } else if (!create_gatt_connection_error_callbacks_.empty()) {
+    DidConnectGatt(/*error_code=*/absl::nullopt);
+  } else if (!create_gatt_connection_callbacks_.empty()) {
     // We assume that if there are any pending connection callbacks there
     // was a failed connection attempt.
     // TODO(ortuno): Return an error code based on |status|
     // http://crbug.com/578191
-    DidFailToConnectGatt(ERROR_FAILED);
+    DidConnectGatt(ERROR_FAILED);
   } else {
     // Otherwise an existing connection was terminated.
     gatt_services_.clear();
diff --git a/device/bluetooth/bluetooth_device_android.h b/device/bluetooth/bluetooth_device_android.h
index 31a25fb..de413a6 100644
--- a/device/bluetooth/bluetooth_device_android.h
+++ b/device/bluetooth/bluetooth_device_android.h
@@ -69,9 +69,8 @@
   void SetConnectionLatency(ConnectionLatency connection_latency,
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
-  void Connect(device::BluetoothDevice::PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+  void Connect(PairingDelegate* pairing_delegate,
+               ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc
index 4dada0a..1b85698 100644
--- a/device/bluetooth/bluetooth_device_unittest.cc
+++ b/device/bluetooth/bluetooth_device_unittest.cc
@@ -149,8 +149,8 @@
 
   SimulatePairingPinCode(device, "123456");
   TestPairingDelegate pairing_delegate;
-  device->Pair(&pairing_delegate, GetCallback(Call::EXPECTED),
-               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->Pair(&pairing_delegate,
+               GetConnectCallback(Call::EXPECTED, Result::SUCCESS));
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -180,8 +180,8 @@
 
   SimulatePairingPinCode(device, "123456");
   TestPairingDelegate pairing_delegate;
-  device->Pair(&pairing_delegate, GetCallback(Call::NOT_EXPECTED),
-               GetConnectErrorCallback(Call::EXPECTED));
+  device->Pair(&pairing_delegate,
+               GetConnectCallback(Call::EXPECTED, Result::FAILURE));
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -212,8 +212,8 @@
 
   SimulatePairingPinCode(device, "123456");
   TestPairingDelegate pairing_delegate;
-  device->Pair(&pairing_delegate, GetCallback(Call::NOT_EXPECTED),
-               GetConnectErrorCallback(Call::EXPECTED));
+  device->Pair(&pairing_delegate,
+               GetConnectCallback(Call::EXPECTED, Result::FAILURE));
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -244,8 +244,8 @@
 
   SimulatePairingPinCode(device, "123456");
   TestPairingDelegate pairing_delegate;
-  device->Pair(&pairing_delegate, GetCallback(Call::NOT_EXPECTED),
-               GetConnectErrorCallback(Call::EXPECTED));
+  device->Pair(&pairing_delegate,
+               GetConnectCallback(Call::EXPECTED, Result::FAILURE));
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -2200,8 +2200,8 @@
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
   EXPECT_FALSE(device->IsConnected());
-  device->CreateGattConnection(GetGattConnectionCallback(Call::NOT_EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::NOT_EXPECTED, Result::FAILURE));
   SimulateStatusChangeToDisconnect(device);
 
   base::RunLoop().RunUntilIdle();
diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc
index 92aec55..0a11ecb 100644
--- a/device/bluetooth/bluetooth_device_win.cc
+++ b/device/bluetooth/bluetooth_device_win.cc
@@ -161,8 +161,7 @@
 }
 
 void BluetoothDeviceWin::Connect(PairingDelegate* pairing_delegate,
-                                 base::OnceClosure callback,
-                                 ConnectErrorCallback error_callback) {
+                                 ConnectCallback callback) {
   NOTIMPLEMENTED();
 }
 
diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h
index 96bd8e9..0df3dcf 100644
--- a/device/bluetooth/bluetooth_device_win.h
+++ b/device/bluetooth/bluetooth_device_win.h
@@ -64,8 +64,7 @@
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
   void Connect(PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+               ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
diff --git a/device/bluetooth/bluetooth_device_winrt.cc b/device/bluetooth/bluetooth_device_winrt.cc
index 2ce8971..24562fc 100644
--- a/device/bluetooth/bluetooth_device_winrt.cc
+++ b/device/bluetooth/bluetooth_device_winrt.cc
@@ -60,10 +60,10 @@
 using ABI::Windows::Foundation::IClosable;
 using Microsoft::WRL::ComPtr;
 
-void PostTask(BluetoothPairingWinrt::ErrorCallback error_callback,
-              BluetoothDevice::ConnectErrorCode error_code) {
+void PostTask(BluetoothPairingWinrt::ConnectCallback callback,
+              absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(std::move(error_callback), error_code));
+      FROM_HERE, base::BindOnce(std::move(callback), error_code));
 }
 
 ComPtr<IDeviceInformationPairing> GetDeviceInformationPairing(
@@ -326,18 +326,16 @@
 }
 
 void BluetoothDeviceWinrt::Connect(PairingDelegate* pairing_delegate,
-                                   base::OnceClosure callback,
-                                   ConnectErrorCallback error_callback) {
+                                   ConnectCallback callback) {
   NOTIMPLEMENTED();
 }
 
 void BluetoothDeviceWinrt::Pair(PairingDelegate* pairing_delegate,
-                                base::OnceClosure callback,
-                                ConnectErrorCallback error_callback) {
+                                ConnectCallback callback) {
   BLUETOOTH_LOG(DEBUG) << "BluetoothDeviceWinrt::Pair()";
   if (pairing_) {
     BLUETOOTH_LOG(DEBUG) << "Another Pair Operation is already in progress.";
-    PostTask(std::move(error_callback), ERROR_INPROGRESS);
+    PostTask(std::move(callback), ERROR_INPROGRESS);
     return;
   }
 
@@ -345,7 +343,7 @@
       GetDeviceInformationPairing(ble_device_);
   if (!pairing) {
     BLUETOOTH_LOG(DEBUG) << "Failed to get DeviceInformationPairing.";
-    PostTask(std::move(error_callback), ERROR_UNKNOWN);
+    PostTask(std::move(callback), ERROR_UNKNOWN);
     return;
   }
 
@@ -354,7 +352,7 @@
   if (FAILED(hr)) {
     BLUETOOTH_LOG(DEBUG) << "Obtaining IDeviceInformationPairing2 failed: "
                          << logging::SystemErrorCodeToString(hr);
-    PostTask(std::move(error_callback), ERROR_UNKNOWN);
+    PostTask(std::move(callback), ERROR_UNKNOWN);
     return;
   }
 
@@ -363,33 +361,22 @@
   if (FAILED(hr)) {
     BLUETOOTH_LOG(DEBUG) << "DeviceInformationPairing::get_Custom() failed: "
                          << logging::SystemErrorCodeToString(hr);
-    PostTask(std::move(error_callback), ERROR_UNKNOWN);
+    PostTask(std::move(callback), ERROR_UNKNOWN);
     return;
   }
 
-  // Wrap success and error callback, so that they clean up the pairing object
-  // once they are run.
-  base::OnceClosure wrapped_callback = base::BindOnce(
-      [](base::WeakPtr<BluetoothDeviceWinrt> device,
-         base::OnceClosure callback) {
+  // Wrap callback, so that it cleans up the pairing object when run.
+  auto wrapped_callback = base::BindOnce(
+      [](base::WeakPtr<BluetoothDeviceWinrt> device, ConnectCallback callback,
+         absl::optional<ConnectErrorCode> error_code) {
         if (device)
           device->pairing_.reset();
-        std::move(callback).Run();
+        std::move(callback).Run(error_code);
       },
       weak_ptr_factory_.GetWeakPtr(), std::move(callback));
 
-  ConnectErrorCallback wrapped_error_callback = base::BindOnce(
-      [](base::WeakPtr<BluetoothDeviceWinrt> device,
-         ConnectErrorCallback error_callback, ConnectErrorCode error_code) {
-        if (device)
-          device->pairing_.reset();
-        std::move(error_callback).Run(error_code);
-      },
-      weak_ptr_factory_.GetWeakPtr(), std::move(error_callback));
-
   pairing_ = std::make_unique<BluetoothPairingWinrt>(
-      this, pairing_delegate, std::move(custom), std::move(wrapped_callback),
-      std::move(wrapped_error_callback));
+      this, pairing_delegate, std::move(custom), std::move(wrapped_callback));
   pairing_->StartPairing();
 }
 
@@ -506,7 +493,7 @@
   // imminent and therefore avoids starting one itself.
   pending_gatt_service_discovery_start_ = false;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidFailToConnectGatt,
+      FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidConnectGatt,
                                 weak_ptr_factory_.GetWeakPtr(),
                                 ConnectErrorCode::ERROR_FAILED));
 }
@@ -595,7 +582,7 @@
     // in a GATT connection attempt as well and trigger
     // OnConnectionStatusChanged on success.
     if (IsGattConnected()) {
-      DidConnectGatt();
+      DidConnectGatt(/*error_code=*/absl::nullopt);
     }
     StartGattDiscovery();
     return;
@@ -684,7 +671,7 @@
   // Check whether we missed the initial GattSessionStatus change notification
   // because the OS had already established a connection.
   if (IsGattConnected()) {
-    DidConnectGatt();
+    DidConnectGatt(/*error_code=*/absl::nullopt);
     StartGattDiscovery();
   }
 }
@@ -717,7 +704,7 @@
   }
 
   if (IsGattConnected()) {
-    DidConnectGatt();
+    DidConnectGatt(/*error_code=*/absl::nullopt);
     StartGattDiscovery();
   } else {
     gatt_discoverer_.reset();
@@ -746,7 +733,7 @@
   }
 
   if (IsGattConnected()) {
-    DidConnectGatt();
+    DidConnectGatt(/*error_code=*/absl::nullopt);
   } else {
     gatt_discoverer_.reset();
     ClearGattServices();
diff --git a/device/bluetooth/bluetooth_device_winrt.h b/device/bluetooth/bluetooth_device_winrt.h
index 23846e6..daa33c24 100644
--- a/device/bluetooth/bluetooth_device_winrt.h
+++ b/device/bluetooth/bluetooth_device_winrt.h
@@ -68,11 +68,9 @@
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
   void Connect(PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+               ConnectCallback callback) override;
   void Pair(PairingDelegate* pairing_delegate,
-            base::OnceClosure callback,
-            ConnectErrorCallback error_callback) override;
+            ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.h b/device/bluetooth/bluetooth_low_energy_device_mac.h
index 41cf5d38..54116b3 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.h
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.h
@@ -62,8 +62,7 @@
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
   void Connect(PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+               ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm
index 4a91351..9a89728 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.mm
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm
@@ -159,8 +159,7 @@
 }
 
 void BluetoothLowEnergyDeviceMac::Connect(PairingDelegate* pairing_delegate,
-                                          base::OnceClosure callback,
-                                          ConnectErrorCallback error_callback) {
+                                          ConnectCallback callback) {
   NOTIMPLEMENTED();
 }
 
@@ -429,7 +428,7 @@
   DVLOG(1) << *this << ": GATT connected.";
   if (!connected_) {
     connected_ = true;
-    DidConnectGatt();
+    DidConnectGatt(/*error_code=*/absl::nullopt);
     DiscoverPrimaryServices();
   } else {
     // -[<CBCentralManagerDelegate> centralManager:didConnectPeripheral:] can be
@@ -536,14 +535,14 @@
   //   1. When the connection to the device breaks (either because
   //      we closed it or the device closed it).
   //   2. When we cancel a pending connection request.
-  if (create_gatt_connection_error_callbacks_.empty()) {
+  if (create_gatt_connection_callbacks_.empty()) {
     // If there are no pending callbacks then the connection broke (#1).
     DidDisconnectGatt();
     return;
   }
   // Else we canceled the connection request (#2).
   // TODO(http://crbug.com/585897): Need to pass the error.
-  DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+  DidConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
 }
 
 std::ostream& operator<<(std::ostream& out,
diff --git a/device/bluetooth/bluetooth_pairing_winrt.cc b/device/bluetooth/bluetooth_pairing_winrt.cc
index e526eea..aea2b430 100644
--- a/device/bluetooth/bluetooth_pairing_winrt.cc
+++ b/device/bluetooth/bluetooth_pairing_winrt.cc
@@ -44,10 +44,10 @@
 using ABI::Windows::Foundation::IAsyncOperation;
 using Microsoft::WRL::ComPtr;
 
-void PostTask(BluetoothPairingWinrt::ErrorCallback error_callback,
-              BluetoothDevice::ConnectErrorCode error_code) {
+void PostTask(BluetoothPairingWinrt::ConnectCallback callback,
+              absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(std::move(error_callback), error_code));
+      FROM_HERE, base::BindOnce(std::move(callback), error_code));
 }
 
 }  // namespace
@@ -56,13 +56,11 @@
     BluetoothDeviceWinrt* device,
     BluetoothDevice::PairingDelegate* pairing_delegate,
     ComPtr<IDeviceInformationCustomPairing> custom_pairing,
-    Callback callback,
-    ErrorCallback error_callback)
+    ConnectCallback callback)
     : device_(device),
       pairing_delegate_(pairing_delegate),
       custom_pairing_(std::move(custom_pairing)),
-      callback_(std::move(callback)),
-      error_callback_(std::move(error_callback)) {
+      callback_(std::move(callback)) {
   DCHECK(device_);
   DCHECK(pairing_delegate_);
   DCHECK(custom_pairing_);
@@ -88,7 +86,7 @@
                           weak_ptr_factory_.GetWeakPtr()));
 
   if (!pairing_requested_token_) {
-    PostTask(std::move(error_callback_),
+    PostTask(std::move(callback_),
              BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
@@ -99,7 +97,7 @@
   if (FAILED(hr)) {
     DVLOG(2) << "DeviceInformationCustomPairing::PairAsync() failed: "
              << logging::SystemErrorCodeToString(hr);
-    PostTask(std::move(error_callback_),
+    PostTask(std::move(callback_),
              BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
@@ -111,7 +109,7 @@
   if (FAILED(hr)) {
     DVLOG(2) << "PostAsyncResults failed: "
              << logging::SystemErrorCodeToString(hr);
-    PostTask(std::move(error_callback_),
+    PostTask(std::move(callback_),
              BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
@@ -131,8 +129,7 @@
   if (FAILED(hr)) {
     DVLOG(2) << "Accepting Pairing Request With Pin failed: "
              << logging::SystemErrorCodeToString(hr);
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
@@ -141,8 +138,7 @@
   if (FAILED(hr)) {
     DVLOG(2) << "Completing Deferred Pairing Request failed: "
              << logging::SystemErrorCodeToString(hr);
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
   }
 }
 
@@ -153,13 +149,12 @@
   if (FAILED(hr)) {
     DVLOG(2) << "Completing Deferred Pairing Request failed: "
              << logging::SystemErrorCodeToString(hr);
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
-  std::move(error_callback_)
-      .Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED);
+  std::move(callback_).Run(
+      BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED);
 }
 
 void BluetoothPairingWinrt::CancelPairing() {
@@ -169,13 +164,12 @@
   if (FAILED(hr)) {
     DVLOG(2) << "Completing Deferred Pairing Request failed: "
              << logging::SystemErrorCodeToString(hr);
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
-  std::move(error_callback_)
-      .Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED);
+  std::move(callback_).Run(
+      BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED);
 }
 
 void BluetoothPairingWinrt::OnPairingRequested(
@@ -188,16 +182,14 @@
   if (FAILED(hr)) {
     DVLOG(2) << "Getting Pairing Kind failed: "
              << logging::SystemErrorCodeToString(hr);
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
   DVLOG(2) << "DevicePairingKind: " << static_cast<int>(pairing_kind);
   if (pairing_kind != DevicePairingKinds_ProvidePin) {
     DVLOG(2) << "Unexpected DevicePairingKind.";
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
@@ -205,8 +197,7 @@
   if (FAILED(hr)) {
     DVLOG(2) << "Getting Pairing Deferral failed: "
              << logging::SystemErrorCodeToString(hr);
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
@@ -222,8 +213,7 @@
   if (FAILED(hr)) {
     DVLOG(2) << "Getting Pairing Result Status failed: "
              << logging::SystemErrorCodeToString(hr);
-    std::move(error_callback_)
-        .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+    std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
     return;
   }
 
@@ -231,36 +221,34 @@
   switch (status) {
     case DevicePairingResultStatus_AlreadyPaired:
     case DevicePairingResultStatus_Paired:
-      std::move(callback_).Run();
+      std::move(callback_).Run(/*error_code=*/absl::nullopt);
       return;
     case DevicePairingResultStatus_PairingCanceled:
-      std::move(error_callback_)
-          .Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED);
+      std::move(callback_).Run(
+          BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED);
       return;
     case DevicePairingResultStatus_AuthenticationFailure:
-      std::move(error_callback_)
-          .Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_FAILED);
+      std::move(callback_).Run(
+          BluetoothDevice::ConnectErrorCode::ERROR_AUTH_FAILED);
       return;
     case DevicePairingResultStatus_ConnectionRejected:
     case DevicePairingResultStatus_RejectedByHandler:
-      std::move(error_callback_)
-          .Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED);
+      std::move(callback_).Run(
+          BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED);
       return;
     case DevicePairingResultStatus_AuthenticationTimeout:
-      std::move(error_callback_)
-          .Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_TIMEOUT);
+      std::move(callback_).Run(
+          BluetoothDevice::ConnectErrorCode::ERROR_AUTH_TIMEOUT);
       return;
     case DevicePairingResultStatus_Failed:
-      std::move(error_callback_)
-          .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+      std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
       return;
     case DevicePairingResultStatus_OperationAlreadyInProgress:
-      std::move(error_callback_)
-          .Run(BluetoothDevice::ConnectErrorCode::ERROR_INPROGRESS);
+      std::move(callback_).Run(
+          BluetoothDevice::ConnectErrorCode::ERROR_INPROGRESS);
       return;
     default:
-      std::move(error_callback_)
-          .Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
+      std::move(callback_).Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
       return;
   }
 }
diff --git a/device/bluetooth/bluetooth_pairing_winrt.h b/device/bluetooth/bluetooth_pairing_winrt.h
index f7d1cfb..7d15307c 100644
--- a/device/bluetooth/bluetooth_pairing_winrt.h
+++ b/device/bluetooth/bluetooth_pairing_winrt.h
@@ -23,9 +23,9 @@
 // Currently only pairing with a pin code is supported.
 class BluetoothPairingWinrt {
  public:
-  using Callback = base::OnceClosure;
-  using ErrorCallback =
-      base::OnceCallback<void(BluetoothDevice::ConnectErrorCode)>;
+  // On error |error_code| will have a value, otherwise successful.
+  using ConnectCallback = base::OnceCallback<void(
+      absl::optional<BluetoothDevice::ConnectErrorCode> error_code)>;
 
   BluetoothPairingWinrt(
       BluetoothDeviceWinrt* device,
@@ -33,8 +33,7 @@
       Microsoft::WRL::ComPtr<
           ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing>
           custom_pairing,
-      Callback callback,
-      ErrorCallback error_callback);
+      ConnectCallback callback);
 
   ~BluetoothPairingWinrt();
 
@@ -80,8 +79,7 @@
   Microsoft::WRL::ComPtr<
       ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing>
       custom_pairing_;
-  Callback callback_;
-  ErrorCallback error_callback_;
+  ConnectCallback callback_;
 
   absl::optional<EventRegistrationToken> pairing_requested_token_;
 
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc
index 43dbb6fa..7742b97d 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc
@@ -52,8 +52,8 @@
     InitWithFakeAdapter();
     StartLowEnergyDiscoverySession();
     device_ = SimulateLowEnergyDevice(3);
-    device_->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                  GetConnectErrorCallback(Call::NOT_EXPECTED));
+    device_->CreateGattConnection(
+        GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
     SimulateGattConnection(device_);
     base::RunLoop().RunUntilIdle();
 
@@ -194,10 +194,10 @@
   // 2 devices to verify unique IDs across them.
   BluetoothDevice* device1 = SimulateLowEnergyDevice(3);
   BluetoothDevice* device2 = SimulateLowEnergyDevice(4);
-  device1->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                GetConnectErrorCallback(Call::NOT_EXPECTED));
-  device2->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device1->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
+  device2->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device1);
   SimulateGattConnection(device2);
   base::RunLoop().RunUntilIdle();
@@ -269,8 +269,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
   SimulateGattServicesDiscovered(
@@ -318,8 +318,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
   SimulateGattServicesDiscovered(
@@ -4607,8 +4607,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
 
   TestBluetoothAdapterObserver observer(adapter_);
 
@@ -4669,8 +4669,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
 
   TestBluetoothAdapterObserver observer(adapter_);
 
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_unittest.cc b/device/bluetooth/bluetooth_remote_gatt_descriptor_unittest.cc
index a3eb5a2..f809ecb 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_unittest.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_unittest.cc
@@ -39,8 +39,8 @@
     InitWithFakeAdapter();
     StartLowEnergyDiscoverySession();
     device_ = SimulateLowEnergyDevice(3);
-    device_->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                  GetConnectErrorCallback(Call::NOT_EXPECTED));
+    device_->CreateGattConnection(
+        GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
     SimulateGattConnection(device_);
     base::RunLoop().RunUntilIdle();
     SimulateGattServicesDiscovered(
@@ -94,10 +94,10 @@
   // 2 devices to verify that descriptors on them have distinct IDs.
   BluetoothDevice* device1 = SimulateLowEnergyDevice(3);
   BluetoothDevice* device2 = SimulateLowEnergyDevice(4);
-  device1->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                GetConnectErrorCallback(Call::NOT_EXPECTED));
-  device2->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device1->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
+  device2->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device1);
   SimulateGattConnection(device2);
   base::RunLoop().RunUntilIdle();
@@ -185,8 +185,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   SimulateGattServicesDiscovered(
       device, std::vector<std::string>({kTestUUIDGenericAccess}));
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_unittest.cc b/device/bluetooth/bluetooth_remote_gatt_service_unittest.cc
index e089eda..67d9741 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_unittest.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_service_unittest.cc
@@ -49,8 +49,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(1);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
   SimulateGattServicesDiscovered(
@@ -80,10 +80,10 @@
   // 2 devices to verify unique IDs across them.
   BluetoothDevice* device1 = SimulateLowEnergyDevice(3);
   BluetoothDevice* device2 = SimulateLowEnergyDevice(4);
-  device1->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                GetConnectErrorCallback(Call::NOT_EXPECTED));
-  device2->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                                GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device1->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
+  device2->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device1);
   SimulateGattConnection(device2);
   base::RunLoop().RunUntilIdle();
@@ -129,8 +129,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
 
@@ -164,8 +164,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
 
@@ -199,8 +199,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
 
@@ -260,8 +260,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
 
@@ -329,8 +329,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
 
@@ -395,8 +395,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
   SimulateGattConnection(device);
   base::RunLoop().RunUntilIdle();
 
@@ -442,8 +442,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
 
   TestBluetoothAdapterObserver observer(adapter_);
 
@@ -508,8 +508,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
 
   TestBluetoothAdapterObserver observer(adapter_);
 
@@ -559,8 +559,8 @@
   InitWithFakeAdapter();
   StartLowEnergyDiscoverySession();
   BluetoothDevice* device = SimulateLowEnergyDevice(3);
-  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
-                               GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->CreateGattConnection(
+      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));
 
   TestBluetoothAdapterObserver observer(adapter_);
 
diff --git a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
index ee3d96f..562e0fc 100644
--- a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
@@ -254,9 +254,15 @@
     QuitMessageLoop();
   }
 
-  void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) {
-    ++error_callback_count_;
-    last_connect_error_ = error;
+  void ConnectCallback(
+      absl::optional<BluetoothDevice::ConnectErrorCode> error) {
+    if (error.has_value()) {
+      ++error_callback_count_;
+      last_connect_error_ = error.value();
+      return;
+    }
+    ++callback_count_;
+    QuitMessageLoop();
   }
 
   void ErrorCompletionCallback(const std::string& error_message) {
@@ -2366,9 +2372,8 @@
   ASSERT_FALSE(device->IsPaired());
 
   // Connect the device so it becomes trusted and remembered.
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   ASSERT_EQ(1, callback_count_);
   ASSERT_EQ(0, error_callback_count_);
@@ -2412,9 +2417,8 @@
 
   // Connect without a pairing delegate; since the device is already Paired
   // this should succeed and the device should become connected.
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -2441,9 +2445,8 @@
 
   // Connect without a pairing delegate; since the device does not require
   // pairing, this should succeed and the device should become connected.
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -2477,9 +2480,8 @@
   ASSERT_TRUE(device != nullptr);
   ASSERT_TRUE(device->IsPaired());
 
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   ASSERT_EQ(1, callback_count_);
   ASSERT_EQ(0, error_callback_count_);
@@ -2491,9 +2493,8 @@
   // anything to initiate the connection.
   TestBluetoothAdapterObserver observer(adapter_);
 
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -2519,9 +2520,8 @@
 
   // Connect without a pairing delegate; since the device requires pairing,
   // this should fail with an error.
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   EXPECT_EQ(0, callback_count_);
   EXPECT_EQ(1, error_callback_count_);
@@ -2543,9 +2543,8 @@
   ASSERT_TRUE(device != nullptr);
 
   fake_bluetooth_device_client_->LeaveConnectionsPending();
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   EXPECT_EQ(0, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -2571,9 +2570,8 @@
   ASSERT_TRUE(device != nullptr);
   ASSERT_TRUE(device->IsPaired());
 
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
 
   ASSERT_EQ(1, callback_count_);
   ASSERT_EQ(0, error_callback_count_);
@@ -2647,8 +2645,8 @@
   TestPairingDelegate pairing_delegate;
   adapter_->AddPairingDelegate(
       &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
-  device->Pair(&pairing_delegate, GetCallback(),
-               base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Pair(&pairing_delegate,
+               base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                               base::Unretained(this)));
   EXPECT_EQ(1, pairing_delegate.call_count_);
   EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
@@ -2688,8 +2686,8 @@
   TestPairingDelegate pairing_delegate;
   adapter_->AddPairingDelegate(
       &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
-  device->Pair(&pairing_delegate, GetCallback(),
-               base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Pair(&pairing_delegate,
+               base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                               base::Unretained(this)));
 
   // For already paired devices a call to |Pair| should succeed without calling
@@ -2715,8 +2713,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -2766,8 +2764,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -2820,8 +2818,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   // One call for DisplayPasskey() and one for KeysEntered().
@@ -2893,8 +2891,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -2947,8 +2945,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -2999,8 +2997,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3050,8 +3048,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3095,8 +3093,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3130,8 +3128,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3166,8 +3164,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3212,8 +3210,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3250,8 +3248,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3288,8 +3286,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3326,8 +3324,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3364,8 +3362,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3402,8 +3400,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3440,8 +3438,8 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   TestPairingDelegate pairing_delegate;
-  device->Connect(&pairing_delegate, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
+  device->Connect(&pairing_delegate,
+                  base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
                                  base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3966,9 +3964,8 @@
   BluetoothDevice* device = adapter_->GetDevice(
       bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
 
-  device->Connect(nullptr, GetCallback(),
-                  base::BindOnce(&BluetoothBlueZTest::ConnectErrorCallback,
-                                 base::Unretained(this)));
+  device->Connect(nullptr, base::BindOnce(&BluetoothBlueZTest::ConnectCallback,
+                                          base::Unretained(this)));
   EXPECT_TRUE(device->IsConnected());
 
   // Calling GetConnectionInfo for a connected device should return valid
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.cc b/device/bluetooth/bluez/bluetooth_device_bluez.cc
index c8e87130..b21ccd8a 100644
--- a/device/bluetooth/bluez/bluetooth_device_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_device_bluez.cc
@@ -218,7 +218,7 @@
 
   auto error_callback = base::BindOnce(
       &BluetoothDeviceBlueZ::OnConnectError, weak_ptr_factory_.GetWeakPtr(),
-      base::BindOnce(&BluetoothDeviceBlueZ::DidFailToConnectGatt,
+      base::BindOnce(&BluetoothDeviceBlueZ::DidConnectGatt,
                      weak_ptr_factory_.GetWeakPtr()));
 
   // TODO(crbug.com/630586): Until there is a way to create a reference counted
@@ -229,8 +229,6 @@
 #else
   Connect(/*pairing_delegate=*/nullptr,
           base::BindOnce(&BluetoothDeviceBlueZ::DidConnectGatt,
-                         weak_ptr_factory_.GetWeakPtr()),
-          base::BindOnce(&BluetoothDeviceBlueZ::DidFailToConnectGatt,
                          weak_ptr_factory_.GetWeakPtr()));
 #endif
 }
@@ -541,8 +539,7 @@
 
 void BluetoothDeviceBlueZ::Connect(
     BluetoothDevice::PairingDelegate* pairing_delegate,
-    base::OnceClosure callback,
-    ConnectErrorCallback error_callback) {
+    ConnectCallback callback) {
   if (num_connecting_calls_++ == 0)
     adapter()->NotifyDeviceChanged(this);
 
@@ -551,40 +548,40 @@
 
   if (IsPaired() || !pairing_delegate) {
     // No need to pair, or unable to, skip straight to connection.
-    ConnectInternal(std::move(callback), std::move(error_callback));
+    ConnectInternal(std::move(callback));
   } else {
     // Initiate high-security connection with pairing.
     BeginPairing(pairing_delegate);
 
     // This callback is only called once but is passed to two different places.
-    auto split_error_callback =
-        base::SplitOnceCallback(std::move(error_callback));
+    auto split_callback = base::SplitOnceCallback(std::move(callback));
 
     bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair(
         object_path_,
         base::BindOnce(&BluetoothDeviceBlueZ::OnPairDuringConnect,
-                       weak_ptr_factory_.GetWeakPtr(), std::move(callback),
-                       std::move(split_error_callback.first)),
+                       weak_ptr_factory_.GetWeakPtr(),
+                       std::move(split_callback.first)),
         base::BindOnce(&BluetoothDeviceBlueZ::OnPairDuringConnectError,
                        weak_ptr_factory_.GetWeakPtr(),
-                       std::move(split_error_callback.second)));
+                       std::move(split_callback.second)));
   }
 }
 
 void BluetoothDeviceBlueZ::Pair(
     BluetoothDevice::PairingDelegate* pairing_delegate,
-    base::OnceClosure callback,
-    ConnectErrorCallback error_callback) {
+    ConnectCallback callback) {
   DCHECK(pairing_delegate);
   BeginPairing(pairing_delegate);
 
+  auto split_callback = base::SplitOnceCallback(std::move(callback));
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair(
       object_path_,
       base::BindOnce(&BluetoothDeviceBlueZ::OnPair,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(split_callback.first)),
       base::BindOnce(&BluetoothDeviceBlueZ::OnPairError,
                      weak_ptr_factory_.GetWeakPtr(),
-                     std::move(error_callback)));
+                     std::move(split_callback.second)));
 }
 
 void BluetoothDeviceBlueZ::SetPinCode(const std::string& pincode) {
@@ -977,20 +974,20 @@
 }
 #endif
 
-void BluetoothDeviceBlueZ::ConnectInternal(
-    base::OnceClosure callback,
-    ConnectErrorCallback error_callback) {
+void BluetoothDeviceBlueZ::ConnectInternal(ConnectCallback callback) {
   BLUETOOTH_LOG(EVENT) << object_path_.value() << ": Connecting";
+  auto split_callback = base::SplitOnceCallback(std::move(callback));
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Connect(
       object_path_,
       base::BindOnce(&BluetoothDeviceBlueZ::OnConnect,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(split_callback.first)),
       base::BindOnce(&BluetoothDeviceBlueZ::OnConnectError,
                      weak_ptr_factory_.GetWeakPtr(),
-                     std::move(error_callback)));
+                     std::move(split_callback.second)));
 }
 
-void BluetoothDeviceBlueZ::OnConnect(base::OnceClosure callback) {
+void BluetoothDeviceBlueZ::OnConnect(ConnectCallback callback) {
   BLUETOOTH_LOG(EVENT) << object_path_.value()
                        << ": Unpausing discovery after connection";
   if (--num_connecting_calls_ == 0)
@@ -1002,10 +999,10 @@
 
   SetTrusted();
 
-  std::move(callback).Run();
+  std::move(callback).Run(/*error_code=*/absl::nullopt);
 }
 
-void BluetoothDeviceBlueZ::OnConnectError(ConnectErrorCallback error_callback,
+void BluetoothDeviceBlueZ::OnConnectError(ConnectCallback callback,
                                           const std::string& error_name,
                                           const std::string& error_message) {
   BLUETOOTH_LOG(EVENT) << object_path_.value()
@@ -1031,21 +1028,19 @@
     error_code = ERROR_UNSUPPORTED_DEVICE;
   }
 
-  std::move(error_callback).Run(error_code);
+  std::move(callback).Run(error_code);
 }
 
-void BluetoothDeviceBlueZ::OnPairDuringConnect(
-    base::OnceClosure callback,
-    ConnectErrorCallback error_callback) {
+void BluetoothDeviceBlueZ::OnPairDuringConnect(ConnectCallback callback) {
   BLUETOOTH_LOG(EVENT) << object_path_.value() << ": Paired";
 
   EndPairing();
 
-  ConnectInternal(std::move(callback), std::move(error_callback));
+  ConnectInternal(std::move(callback));
 }
 
 void BluetoothDeviceBlueZ::OnPairDuringConnectError(
-    ConnectErrorCallback error_callback,
+    ConnectCallback callback,
     const std::string& error_name,
     const std::string& error_message) {
   if (--num_connecting_calls_ == 0)
@@ -1063,16 +1058,16 @@
   // Determine the error code from error_name.
   ConnectErrorCode error_code = DBusErrorToConnectError(error_name);
 
-  std::move(error_callback).Run(error_code);
+  std::move(callback).Run(error_code);
 }
 
-void BluetoothDeviceBlueZ::OnPair(base::OnceClosure callback) {
+void BluetoothDeviceBlueZ::OnPair(ConnectCallback callback) {
   BLUETOOTH_LOG(EVENT) << object_path_.value() << ": Paired";
   EndPairing();
-  std::move(callback).Run();
+  std::move(callback).Run(/*error_code=*/absl::nullopt);
 }
 
-void BluetoothDeviceBlueZ::OnPairError(ConnectErrorCallback error_callback,
+void BluetoothDeviceBlueZ::OnPairError(ConnectCallback callback,
                                        const std::string& error_name,
                                        const std::string& error_message) {
   BLUETOOTH_LOG(ERROR) << object_path_.value()
@@ -1080,7 +1075,7 @@
                        << error_message;
   EndPairing();
   ConnectErrorCode error_code = DBusErrorToConnectError(error_name);
-  std::move(error_callback).Run(error_code);
+  std::move(callback).Run(error_code);
 }
 
 void BluetoothDeviceBlueZ::OnCancelPairingError(
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.h b/device/bluetooth/bluez/bluetooth_device_bluez.h
index 180ea00..30776c4 100644
--- a/device/bluetooth/bluez/bluetooth_device_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_device_bluez.h
@@ -82,8 +82,7 @@
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
   void Connect(device::BluetoothDevice::PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+               ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
@@ -105,8 +104,7 @@
   void SetGattServicesDiscoveryComplete(bool complete) override;
   bool IsGattServicesDiscoveryComplete() const override;
   void Pair(device::BluetoothDevice::PairingDelegate* pairing_delegate,
-            base::OnceClosure callback,
-            ConnectErrorCallback error_callback) override;
+            ConnectCallback callback) override;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   void ExecuteWrite(base::OnceClosure callback,
                     ExecuteWriteErrorCallback error_callback) override;
@@ -239,10 +237,9 @@
 
   // Internal method to initiate a connection to this device, and methods called
   // by dbus:: on completion of the D-Bus method call.
-  void ConnectInternal(base::OnceClosure callback,
-                       ConnectErrorCallback error_callback);
-  void OnConnect(base::OnceClosure callback);
-  void OnConnectError(ConnectErrorCallback error_callback,
+  void ConnectInternal(ConnectCallback callback);
+  void OnConnect(ConnectCallback callback);
+  void OnConnectError(ConnectCallback callback,
                       const std::string& error_name,
                       const std::string& error_message);
 
@@ -255,16 +252,15 @@
 
   // Called by dbus:: on completion of the D-Bus method call to pair the device,
   // made inside |Connect()|.
-  void OnPairDuringConnect(base::OnceClosure callback,
-                           ConnectErrorCallback error_callback);
-  void OnPairDuringConnectError(ConnectErrorCallback error_callback,
+  void OnPairDuringConnect(ConnectCallback callback);
+  void OnPairDuringConnectError(ConnectCallback callback,
                                 const std::string& error_name,
                                 const std::string& error_message);
 
   // Called by dbus: on completion of the D-Bus method call to pair the device,
   // made inside |Pair()|.
-  void OnPair(base::OnceClosure callback);
-  void OnPairError(ConnectErrorCallback error_callback,
+  void OnPair(ConnectCallback callback);
+  void OnPairError(ConnectCallback callback,
                    const std::string& error_name,
                    const std::string& error_message);
 
diff --git a/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc
index 54ed2cc..3af6ef7 100644
--- a/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc
@@ -275,7 +275,13 @@
     }
   }
 
-  void GattConnectionCallback(std::unique_ptr<BluetoothGattConnection> conn) {
+  void GattConnectionCallback(
+      std::unique_ptr<BluetoothGattConnection> conn,
+      absl::optional<BluetoothDevice::ConnectErrorCode> error) {
+    if (error.has_value()) {
+      ++error_callback_count_;
+      return;
+    }
     ++success_callback_count_;
     gatt_conn_ = std::move(conn);
   }
@@ -299,10 +305,6 @@
     ++error_callback_count_;
   }
 
-  void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) {
-    ++error_callback_count_;
-  }
-
  protected:
   void QuitMessageLoop() {
     if (base::RunLoop::IsRunningOnCurrentThread())
@@ -447,8 +449,6 @@
 
   device->CreateGattConnection(
       base::BindOnce(&BluetoothGattBlueZTest::GattConnectionCallback,
-                     base::Unretained(this)),
-      base::BindOnce(&BluetoothGattBlueZTest::ConnectErrorCallback,
                      base::Unretained(this)));
 
   EXPECT_EQ(1, success_callback_count_);
@@ -467,8 +467,6 @@
 
   device->CreateGattConnection(
       base::BindOnce(&BluetoothGattBlueZTest::GattConnectionCallback,
-                     base::Unretained(this)),
-      base::BindOnce(&BluetoothGattBlueZTest::ConnectErrorCallback,
                      base::Unretained(this)));
 
   EXPECT_EQ(2, success_callback_count_);
@@ -492,8 +490,6 @@
 
   device->CreateGattConnection(
       base::BindOnce(&BluetoothGattBlueZTest::GattConnectionCallback,
-                     base::Unretained(this)),
-      base::BindOnce(&BluetoothGattBlueZTest::ConnectErrorCallback,
                      base::Unretained(this)));
 
   EXPECT_EQ(4, success_callback_count_);
@@ -679,8 +675,6 @@
   // Verify that the device can be connected to again:
   device->CreateGattConnection(
       base::BindOnce(&BluetoothGattBlueZTest::GattConnectionCallback,
-                     base::Unretained(this)),
-      base::BindOnce(&BluetoothGattBlueZTest::ConnectErrorCallback,
                      base::Unretained(this)));
   properties->connected.ReplaceValue(true);
   EXPECT_TRUE(device->IsConnected());
diff --git a/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc
index 7f1e515..dfd861b 100644
--- a/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc
@@ -185,8 +185,7 @@
       static_cast<BluetoothDeviceBlueZ*>(adapter_->GetDevice(
           bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
   GetServiceRecords(device, false);
-  device->Connect(nullptr, GetCallback(Call::EXPECTED),
-                  GetConnectErrorCallback(Call::NOT_EXPECTED));
+  device->Connect(nullptr, GetConnectCallback(Call::EXPECTED, Result::SUCCESS));
   GetServiceRecords(device, true);
   VerifyRecords();
 }
diff --git a/device/bluetooth/cast/bluetooth_device_cast.cc b/device/bluetooth/cast/bluetooth_device_cast.cc
index d76a3c8..03842a1d 100644
--- a/device/bluetooth/cast/bluetooth_device_cast.cc
+++ b/device/bluetooth/cast/bluetooth_device_cast.cc
@@ -174,19 +174,17 @@
 }
 
 void BluetoothDeviceCast::Connect(PairingDelegate* pairing_delegate,
-                                  base::OnceClosure callback,
-                                  ConnectErrorCallback error_callback) {
+                                  ConnectCallback callback) {
   // This method is used only for Bluetooth classic.
   NOTIMPLEMENTED() << __func__ << " Only BLE functionality is supported.";
-  std::move(error_callback).Run(BluetoothDevice::ERROR_UNSUPPORTED_DEVICE);
+  std::move(callback).Run(BluetoothDevice::ERROR_UNSUPPORTED_DEVICE);
 }
 
 void BluetoothDeviceCast::Pair(PairingDelegate* pairing_delegate,
-                               base::OnceClosure callback,
-                               ConnectErrorCallback error_callback) {
+                               ConnectCallback callback) {
   // TODO(slan): Implement this or delegate to lower level.
   NOTIMPLEMENTED();
-  std::move(error_callback).Run(BluetoothDevice::ERROR_UNSUPPORTED_DEVICE);
+  std::move(callback).Run(BluetoothDevice::ERROR_UNSUPPORTED_DEVICE);
 }
 
 void BluetoothDeviceCast::SetPinCode(const std::string& pincode) {
@@ -295,7 +293,7 @@
   // Update state in the base class. This will cause pending callbacks to be
   // fired.
   if (!was_connected && connected) {
-    DidConnectGatt();
+    DidConnectGatt(/*error_code=*/absl::nullopt);
     remote_device_->GetServices(base::BindOnce(
         &BluetoothDeviceCast::OnGetServices, weak_factory_.GetWeakPtr()));
   } else if (was_connected && !connected) {
@@ -367,7 +365,7 @@
   DVLOG(2) << __func__ << " success:" << success;
   pending_connect_ = false;
   if (!success) {
-    DidFailToConnectGatt(ERROR_FAILED);
+    DidConnectGatt(ERROR_FAILED);
   }
 }
 
diff --git a/device/bluetooth/cast/bluetooth_device_cast.h b/device/bluetooth/cast/bluetooth_device_cast.h
index 2fd548d3..73cdee7 100644
--- a/device/bluetooth/cast/bluetooth_device_cast.h
+++ b/device/bluetooth/cast/bluetooth_device_cast.h
@@ -61,11 +61,9 @@
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
   void Connect(PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+               ConnectCallback callback) override;
   void Pair(PairingDelegate* pairing_delegate,
-            base::OnceClosure callback,
-            ConnectErrorCallback error_callback) override;
+            ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
diff --git a/device/bluetooth/test/bluetooth_test.cc b/device/bluetooth/test/bluetooth_test.cc
index ded564ba..6088e78 100644
--- a/device/bluetooth/test/bluetooth_test.cc
+++ b/device/bluetooth/test/bluetooth_test.cc
@@ -136,16 +136,16 @@
 
   device->CreateGattConnection(
       base::BindLambdaForTesting(
-          [&result, &connection,
-           &run_loop](std::unique_ptr<BluetoothGattConnection> new_connection) {
-            result = true;
-            connection = std::move(new_connection);
-            run_loop.Quit();
-          }),
-      base::BindLambdaForTesting(
-          [this, &result, &run_loop](BluetoothDevice::ConnectErrorCode error) {
-            result = false;
-            last_connect_error_code_ = error;
+          [this, &result, &connection, &run_loop](
+              std::unique_ptr<BluetoothGattConnection> new_connection,
+              absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
+            if (error_code.has_value()) {
+              result = false;
+              last_connect_error_code_ = error_code.value();
+            } else {
+              result = true;
+              connection = std::move(new_connection);
+            }
             run_loop.Quit();
           }),
       std::move(service_uuid));
@@ -261,14 +261,35 @@
 
 void BluetoothTestBase::GattConnectionCallback(
     Call expected,
-    std::unique_ptr<BluetoothGattConnection> connection) {
-  ++callback_count_;
+    Result expected_result,
+    std::unique_ptr<BluetoothGattConnection> connection,
+    absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
+  Result actual_result;
+  if (error_code) {
+    ++error_callback_count_;
+    ++actual_error_callback_calls_;
+    last_connect_error_code_ = error_code.value();
+    actual_result = Result::FAILURE;
+  } else {
+    ++callback_count_;
+    ++actual_success_callback_calls_;
+    actual_result = Result::SUCCESS;
+  }
   gatt_connections_.push_back(std::move(connection));
 
-  if (expected == Call::EXPECTED)
-    ++actual_success_callback_calls_;
-  else
-    unexpected_success_callback_ = true;
+  if (expected == Call::EXPECTED) {
+    if (actual_result != expected_result) {
+      if (actual_result == Result::SUCCESS)
+        unexpected_success_callback_ = true;
+      else
+        unexpected_error_callback_ = true;
+    }
+  } else {
+    if (actual_result == Result::SUCCESS)
+      unexpected_success_callback_ = true;
+    else
+      unexpected_error_callback_ = true;
+  }
 }
 
 void BluetoothTestBase::NotifyCallback(
@@ -363,16 +384,35 @@
     unexpected_error_callback_ = true;
 }
 
-void BluetoothTestBase::ConnectErrorCallback(
+void BluetoothTestBase::OnConnectCallback(
     Call expected,
-    enum BluetoothDevice::ConnectErrorCode error_code) {
-  ++error_callback_count_;
-  last_connect_error_code_ = error_code;
-
-  if (expected == Call::EXPECTED)
+    Result expected_result,
+    absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
+  Result actual_result;
+  if (error_code) {
+    ++error_callback_count_;
     ++actual_error_callback_calls_;
-  else
-    unexpected_error_callback_ = true;
+    last_connect_error_code_ = error_code.value();
+    actual_result = Result::FAILURE;
+  } else {
+    ++callback_count_;
+    ++actual_success_callback_calls_;
+    actual_result = Result::SUCCESS;
+  }
+
+  if (expected == Call::EXPECTED) {
+    if (actual_result != expected_result) {
+      if (actual_result == Result::SUCCESS)
+        unexpected_success_callback_ = true;
+      else
+        unexpected_error_callback_ = true;
+    }
+  } else {
+    if (actual_result == Result::SUCCESS)
+      unexpected_success_callback_ = true;
+    else
+      unexpected_error_callback_ = true;
+  }
 }
 
 void BluetoothTestBase::GattErrorCallback(
@@ -452,11 +492,16 @@
 }
 
 BluetoothDevice::GattConnectionCallback
-BluetoothTestBase::GetGattConnectionCallback(Call expected) {
-  if (expected == Call::EXPECTED)
-    ++expected_success_callback_calls_;
+BluetoothTestBase::GetGattConnectionCallback(Call expected,
+                                             Result expected_result) {
+  if (expected == Call::EXPECTED) {
+    if (expected_result == Result::SUCCESS)
+      ++expected_success_callback_calls_;
+    else
+      ++expected_error_callback_calls_;
+  }
   return base::BindOnce(&BluetoothTestBase::GattConnectionCallback,
-                        weak_factory_.GetWeakPtr(), expected);
+                        weak_factory_.GetWeakPtr(), expected, expected_result);
 }
 
 BluetoothRemoteGattCharacteristic::NotifySessionCallback
@@ -517,12 +562,17 @@
                         weak_factory_.GetWeakPtr(), expected);
 }
 
-BluetoothDevice::ConnectErrorCallback
-BluetoothTestBase::GetConnectErrorCallback(Call expected) {
-  if (expected == Call::EXPECTED)
-    ++expected_error_callback_calls_;
-  return base::BindOnce(&BluetoothTestBase::ConnectErrorCallback,
-                        weak_factory_.GetWeakPtr(), expected);
+BluetoothDevice::ConnectCallback BluetoothTestBase::GetConnectCallback(
+    Call expected,
+    Result expected_result) {
+  if (expected == Call::EXPECTED) {
+    if (expected_result == Result::SUCCESS)
+      ++expected_success_callback_calls_;
+    else
+      ++expected_error_callback_calls_;
+  }
+  return base::BindOnce(&BluetoothTestBase::OnConnectCallback,
+                        weak_factory_.GetWeakPtr(), expected, expected_result);
 }
 
 base::OnceCallback<void(BluetoothGattService::GattErrorCode)>
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h
index c7f64590..ef27b49 100644
--- a/device/bluetooth/test/bluetooth_test.h
+++ b/device/bluetooth/test/bluetooth_test.h
@@ -607,8 +607,11 @@
                                    scoped_refptr<BluetoothAdvertisement>);
   void DiscoverySessionCallback(Call expected,
                                 std::unique_ptr<BluetoothDiscoverySession>);
-  void GattConnectionCallback(Call expected,
-                              std::unique_ptr<BluetoothGattConnection>);
+  void GattConnectionCallback(
+      Call expected,
+      Result expected_result,
+      std::unique_ptr<BluetoothGattConnection>,
+      absl::optional<BluetoothDevice::ConnectErrorCode>);
   void NotifyCallback(Call expected,
                       std::unique_ptr<BluetoothGattNotifySession>);
   void NotifyCheckForPrecedingCalls(
@@ -624,8 +627,9 @@
   void ErrorCallback(Call expected);
   void AdvertisementErrorCallback(Call expected,
                                   BluetoothAdvertisement::ErrorCode error_code);
-  void ConnectErrorCallback(Call expected,
-                            enum BluetoothDevice::ConnectErrorCode);
+  void OnConnectCallback(Call expected,
+                         Result expected_result,
+                         absl::optional<BluetoothDevice::ConnectErrorCode>);
   void GattErrorCallback(Call expected, BluetoothGattService::GattErrorCode);
   void ReentrantStartNotifySessionSuccessCallback(
       Call expected,
@@ -644,7 +648,8 @@
   BluetoothAdapter::DiscoverySessionCallback GetDiscoverySessionCallback(
       Call expected);
   BluetoothDevice::GattConnectionCallback GetGattConnectionCallback(
-      Call expected);
+      Call expected,
+      Result expected_result);
   BluetoothRemoteGattCharacteristic::NotifySessionCallback GetNotifyCallback(
       Call expected);
   BluetoothRemoteGattCharacteristic::NotifySessionCallback
@@ -658,7 +663,8 @@
   BluetoothAdapter::ErrorCallback GetErrorCallback(Call expected);
   BluetoothAdapter::AdvertisementErrorCallback GetAdvertisementErrorCallback(
       Call expected);
-  BluetoothDevice::ConnectErrorCallback GetConnectErrorCallback(Call expected);
+  BluetoothDevice::ConnectCallback GetConnectCallback(Call expected,
+                                                      Result expected_result);
   base::OnceCallback<void(BluetoothGattService::GattErrorCode)>
   GetGattErrorCallback(Call expected);
   BluetoothRemoteGattCharacteristic::NotifySessionCallback
diff --git a/device/bluetooth/test/fake_peripheral.cc b/device/bluetooth/test/fake_peripheral.cc
index 14f3536..633984c 100644
--- a/device/bluetooth/test/fake_peripheral.cc
+++ b/device/bluetooth/test/fake_peripheral.cc
@@ -61,7 +61,7 @@
 
 void FakePeripheral::SetNextGATTConnectionResponse(uint16_t code) {
   DCHECK(!next_connection_response_);
-  DCHECK(create_gatt_connection_error_callbacks_.empty());
+  DCHECK(create_gatt_connection_callbacks_.empty());
   next_connection_response_ = code;
 }
 
@@ -240,8 +240,7 @@
 }
 
 void FakePeripheral::Connect(PairingDelegate* pairing_delegate,
-                             base::OnceClosure callback,
-                             ConnectErrorCallback error_callback) {
+                             ConnectCallback callback) {
   NOTREACHED();
 }
 
@@ -291,15 +290,13 @@
 
 void FakePeripheral::CreateGattConnection(
     GattConnectionCallback callback,
-    ConnectErrorCallback error_callback,
     absl::optional<device::BluetoothUUID> service_uuid) {
-  create_gatt_connection_success_callbacks_.push_back(std::move(callback));
-  create_gatt_connection_error_callbacks_.push_back(std::move(error_callback));
+  create_gatt_connection_callbacks_.push_back(std::move(callback));
 
   // TODO(crbug.com/728870): Stop overriding CreateGattConnection once
   // IsGattConnected() is fixed. See issue for more details.
   if (gatt_connected_)
-    return DidConnectGatt();
+    return DidConnectGatt(/*error_code=*/absl::nullopt);
 
   CreateGattConnectionImpl(std::move(service_uuid));
 }
@@ -344,11 +341,11 @@
 
   if (code == mojom::kHCISuccess) {
     gatt_connected_ = true;
-    DidConnectGatt();
+    DidConnectGatt(/*error_code=*/absl::nullopt);
   } else if (code == mojom::kHCIConnectionTimeout) {
-    DidFailToConnectGatt(ERROR_FAILED);
+    DidConnectGatt(ERROR_FAILED);
   } else {
-    DidFailToConnectGatt(ERROR_UNKNOWN);
+    DidConnectGatt(ERROR_UNKNOWN);
   }
 }
 
diff --git a/device/bluetooth/test/fake_peripheral.h b/device/bluetooth/test/fake_peripheral.h
index 1a5dbb3..e9b1ee0 100644
--- a/device/bluetooth/test/fake_peripheral.h
+++ b/device/bluetooth/test/fake_peripheral.h
@@ -102,8 +102,7 @@
                             base::OnceClosure callback,
                             ErrorCallback error_callback) override;
   void Connect(PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               ConnectErrorCallback error_callback) override;
+               ConnectCallback callback) override;
   void SetPinCode(const std::string& pincode) override;
   void SetPasskey(uint32_t passkey) override;
   void ConfirmPairing() override;
@@ -122,7 +121,6 @@
       ConnectToServiceErrorCallback error_callback) override;
   void CreateGattConnection(
       GattConnectionCallback callback,
-      ConnectErrorCallback error_callback,
       absl::optional<device::BluetoothUUID> service_uuid) override;
   bool IsGattServicesDiscoveryComplete() const override;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h
index 143951d..40b21f25 100644
--- a/device/bluetooth/test/mock_bluetooth_device.h
+++ b/device/bluetooth/test/mock_bluetooth_device.h
@@ -71,23 +71,19 @@
                     base::OnceClosure& callback,
                     ErrorCallback& error_callback));
   void Connect(BluetoothDevice::PairingDelegate* pairing_delegate,
-               base::OnceClosure callback,
-               BluetoothDevice::ConnectErrorCallback error_callback) override {
-    Connect_(pairing_delegate, callback, error_callback);
+               ConnectCallback callback) override {
+    Connect_(pairing_delegate, callback);
   }
-  MOCK_METHOD3(Connect_,
+  MOCK_METHOD2(Connect_,
                void(BluetoothDevice::PairingDelegate* pairing_delegate,
-                    base::OnceClosure& callback,
-                    BluetoothDevice::ConnectErrorCallback& error_callback));
+                    ConnectCallback& callback));
   void Pair(BluetoothDevice::PairingDelegate* pairing_delegate,
-            base::OnceClosure callback,
-            BluetoothDevice::ConnectErrorCallback error_callback) override {
-    Pair_(pairing_delegate, callback, error_callback);
+            ConnectCallback callback) override {
+    Pair_(pairing_delegate, callback);
   }
-  MOCK_METHOD3(Pair_,
+  MOCK_METHOD2(Pair_,
                void(BluetoothDevice::PairingDelegate* pairing_delegate,
-                    base::OnceClosure& callback,
-                    BluetoothDevice::ConnectErrorCallback& error_callback));
+                    ConnectCallback& callback));
   MOCK_METHOD1(SetPinCode, void(const std::string&));
   MOCK_METHOD1(SetPasskey, void(uint32_t));
   MOCK_METHOD0(ConfirmPairing, void());
@@ -109,13 +105,10 @@
                     ConnectToServiceErrorCallback error_callback));
   void CreateGattConnection(
       GattConnectionCallback callback,
-      ConnectErrorCallback error_callback,
       absl::optional<BluetoothUUID> service_uuid) override {
-    CreateGattConnection_(callback, error_callback);
+    CreateGattConnection_(callback);
   }
-  MOCK_METHOD2(CreateGattConnection_,
-               void(GattConnectionCallback& callback,
-                    ConnectErrorCallback& error_callback));
+  MOCK_METHOD1(CreateGattConnection_, void(GattConnectionCallback& callback));
 
   MOCK_METHOD1(SetGattServicesDiscoveryComplete, void(bool));
   MOCK_CONST_METHOD0(IsGattServicesDiscoveryComplete, bool());
diff --git a/device/fido/cable/fido_ble_connection.cc b/device/fido/cable/fido_ble_connection.cc
index 64256de..6450cf2 100644
--- a/device/fido/cable/fido_ble_connection.cc
+++ b/device/fido/cable/fido_ble_connection.cc
@@ -185,12 +185,9 @@
 
   pending_connection_callback_ = std::move(callback);
   FIDO_LOG(DEBUG) << "Creating a GATT connection...";
-  // TODO(crbug.com/1007780): This function should take OnceCallbacks.
   device->CreateGattConnection(
       base::BindOnce(&FidoBleConnection::OnCreateGattConnection,
                      weak_factory_.GetWeakPtr()),
-      base::BindOnce(&FidoBleConnection::OnCreateGattConnectionError,
-                     weak_factory_.GetWeakPtr()),
       BluetoothUUID(kGoogleCableUUID128));
 }
 
@@ -269,9 +266,18 @@
 }
 
 void FidoBleConnection::OnCreateGattConnection(
-    std::unique_ptr<BluetoothGattConnection> connection) {
+    std::unique_ptr<BluetoothGattConnection> connection,
+    absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
   FIDO_LOG(DEBUG) << "GATT connection created";
   DCHECK(pending_connection_callback_);
+  if (error_code.has_value()) {
+    FIDO_LOG(ERROR) << "CreateGattConnection() failed: "
+                    << ToString(error_code.value());
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(std::move(pending_connection_callback_), false));
+    return;
+  }
   connection_ = std::move(connection);
 
   BluetoothDevice* device = adapter_->GetDevice(address_);
@@ -292,15 +298,6 @@
   ConnectToFidoService();
 }
 
-void FidoBleConnection::OnCreateGattConnectionError(
-    BluetoothDevice::ConnectErrorCode error_code) {
-  DCHECK(pending_connection_callback_);
-  FIDO_LOG(ERROR) << "CreateGattConnection() failed: " << ToString(error_code);
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(std::move(pending_connection_callback_), false));
-}
-
 void FidoBleConnection::ConnectToFidoService() {
   FIDO_LOG(EVENT) << "Attempting to connect to a Fido service.";
   DCHECK(pending_connection_callback_);
diff --git a/device/fido/cable/fido_ble_connection.h b/device/fido/cable/fido_ble_connection.h
index d8bd16b..f1d7d6fd 100644
--- a/device/fido/cable/fido_ble_connection.h
+++ b/device/fido/cable/fido_ble_connection.h
@@ -89,9 +89,8 @@
   const BluetoothRemoteGattService* GetFidoService();
 
   void OnCreateGattConnection(
-      std::unique_ptr<BluetoothGattConnection> connection);
-  void OnCreateGattConnectionError(
-      BluetoothDevice::ConnectErrorCode error_code);
+      std::unique_ptr<BluetoothGattConnection> connection,
+      absl::optional<BluetoothDevice::ConnectErrorCode> error_code);
 
   void ConnectToFidoService();
   void OnReadServiceRevisions(std::vector<ServiceRevision> service_revisions);
diff --git a/device/fido/cable/fido_ble_connection_unittest.cc b/device/fido/cable/fido_ble_connection_unittest.cc
index 4946b0b..79dd4fe 100644
--- a/device/fido/cable/fido_ble_connection_unittest.cc
+++ b/device/fido/cable/fido_ble_connection_unittest.cc
@@ -146,10 +146,11 @@
 
   void SetupConnectingFidoDevice(const std::string& device_address) {
     ON_CALL(*fido_device_, CreateGattConnection_)
-        .WillByDefault(Invoke([this, &device_address](auto& callback, auto&&) {
+        .WillByDefault(Invoke([this, &device_address](auto& callback) {
           connection_ =
               new NiceMockBluetoothGattConnection(adapter_, device_address);
-          std::move(callback).Run(std::move(base::WrapUnique(connection_)));
+          std::move(callback).Run(std::move(base::WrapUnique(connection_)),
+                                  /*error_code=*/absl::nullopt);
         }));
 
     ON_CALL(*fido_device_, IsGattServicesDiscoveryComplete)
@@ -192,9 +193,10 @@
 
   void SimulateGattConnectionError() {
     EXPECT_CALL(*fido_device_, CreateGattConnection_)
-        .WillOnce(Invoke([](auto&&, auto&& error_callback) {
+        .WillOnce(Invoke([](auto&& callback) {
           base::ThreadTaskRunnerHandle::Get()->PostTask(
-              FROM_HERE, base::BindOnce(std::move(error_callback),
+              FROM_HERE, base::BindOnce(std::move(callback),
+                                        /*connection=*/nullptr,
                                         BluetoothDevice::ERROR_FAILED));
         }));
   }
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_api.cc b/extensions/browser/api/bluetooth/bluetooth_private_api.cc
index 32cd459..282d59f 100644
--- a/extensions/browser/api/bluetooth/bluetooth_private_api.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_private_api.cc
@@ -100,6 +100,32 @@
                                        : details.listener_url.host();
 }
 
+bt_private::ConnectResultType DeviceConnectErrorToConnectResult(
+    device::BluetoothDevice::ConnectErrorCode error_code) {
+  switch (error_code) {
+    case device::BluetoothDevice::ERROR_AUTH_CANCELED:
+      return bt_private::CONNECT_RESULT_TYPE_AUTHCANCELED;
+    case device::BluetoothDevice::ERROR_AUTH_FAILED:
+      return bt_private::CONNECT_RESULT_TYPE_AUTHFAILED;
+    case device::BluetoothDevice::ERROR_AUTH_REJECTED:
+      return bt_private::CONNECT_RESULT_TYPE_AUTHREJECTED;
+    case device::BluetoothDevice::ERROR_AUTH_TIMEOUT:
+      return bt_private::CONNECT_RESULT_TYPE_AUTHTIMEOUT;
+    case device::BluetoothDevice::ERROR_FAILED:
+      return bt_private::CONNECT_RESULT_TYPE_FAILED;
+    case device::BluetoothDevice::ERROR_INPROGRESS:
+      return bt_private::CONNECT_RESULT_TYPE_INPROGRESS;
+    case device::BluetoothDevice::ERROR_UNKNOWN:
+      return bt_private::CONNECT_RESULT_TYPE_UNKNOWNERROR;
+    case device::BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
+      return bt_private::CONNECT_RESULT_TYPE_UNSUPPORTEDDEVICE;
+    case device::BluetoothDevice::NUM_CONNECT_ERROR_CODES:
+      NOTREACHED();
+      break;
+  }
+  return bt_private::CONNECT_RESULT_TYPE_NONE;
+}
+
 }  // namespace
 
 // static
@@ -567,51 +593,21 @@
           ->GetPairingDelegate(GetExtensionId());
   device->Connect(
       pairing_delegate,
-      base::BindOnce(&BluetoothPrivateConnectFunction::OnSuccessCallback, this),
-      base::BindOnce(&BluetoothPrivateConnectFunction::OnErrorCallback, this));
+      base::BindOnce(&BluetoothPrivateConnectFunction::OnConnect, this));
 }
 
-void BluetoothPrivateConnectFunction::OnSuccessCallback() {
+void BluetoothPrivateConnectFunction::OnConnect(
+    absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
+  if (error_code.has_value()) {
+    // Set the result type and respond with true (success).
+    Respond(ArgumentList(bt_private::Connect::Results::Create(
+        DeviceConnectErrorToConnectResult(error_code.value()))));
+    return;
+  }
   Respond(ArgumentList(bt_private::Connect::Results::Create(
       bt_private::CONNECT_RESULT_TYPE_SUCCESS)));
 }
 
-void BluetoothPrivateConnectFunction::OnErrorCallback(
-    device::BluetoothDevice::ConnectErrorCode error) {
-  bt_private::ConnectResultType result = bt_private::CONNECT_RESULT_TYPE_NONE;
-  switch (error) {
-    case device::BluetoothDevice::ERROR_AUTH_CANCELED:
-      result = bt_private::CONNECT_RESULT_TYPE_AUTHCANCELED;
-      break;
-    case device::BluetoothDevice::ERROR_AUTH_FAILED:
-      result = bt_private::CONNECT_RESULT_TYPE_AUTHFAILED;
-      break;
-    case device::BluetoothDevice::ERROR_AUTH_REJECTED:
-      result = bt_private::CONNECT_RESULT_TYPE_AUTHREJECTED;
-      break;
-    case device::BluetoothDevice::ERROR_AUTH_TIMEOUT:
-      result = bt_private::CONNECT_RESULT_TYPE_AUTHTIMEOUT;
-      break;
-    case device::BluetoothDevice::ERROR_FAILED:
-      result = bt_private::CONNECT_RESULT_TYPE_FAILED;
-      break;
-    case device::BluetoothDevice::ERROR_INPROGRESS:
-      result = bt_private::CONNECT_RESULT_TYPE_INPROGRESS;
-      break;
-    case device::BluetoothDevice::ERROR_UNKNOWN:
-      result = bt_private::CONNECT_RESULT_TYPE_UNKNOWNERROR;
-      break;
-    case device::BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
-      result = bt_private::CONNECT_RESULT_TYPE_UNSUPPORTEDDEVICE;
-      break;
-    case device::BluetoothDevice::NUM_CONNECT_ERROR_CODES:
-      NOTREACHED();
-      break;
-  }
-  // Set the result type and respond with true (success).
-  Respond(ArgumentList(bt_private::Connect::Results::Create(result)));
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 
 BluetoothPrivatePairFunction::BluetoothPrivatePairFunction() {}
@@ -642,21 +638,19 @@
     return;
   }
 
-  device->Pair(
-      pairing_delegate,
-      base::BindOnce(&BluetoothPrivatePairFunction::OnSuccessCallback, this),
-      base::BindOnce(&BluetoothPrivatePairFunction::OnErrorCallback, this));
+  device->Pair(pairing_delegate,
+               base::BindOnce(&BluetoothPrivatePairFunction::OnPair, this));
 }
 
-void BluetoothPrivatePairFunction::OnSuccessCallback() {
+void BluetoothPrivatePairFunction::OnPair(
+    absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
+  if (error_code.has_value()) {
+    Respond(Error(kPairingFailed));
+    return;
+  }
   Respond(NoArguments());
 }
 
-void BluetoothPrivatePairFunction::OnErrorCallback(
-    device::BluetoothDevice::ConnectErrorCode error) {
-  Respond(Error(kPairingFailed));
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 
 BluetoothPrivateRecordPairingFunction::BluetoothPrivateRecordPairingFunction() =
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_api.h b/extensions/browser/api/bluetooth/bluetooth_private_api.h
index ce54a91..46df482 100644
--- a/extensions/browser/api/bluetooth/bluetooth_private_api.h
+++ b/extensions/browser/api/bluetooth/bluetooth_private_api.h
@@ -11,6 +11,7 @@
 #include "extensions/browser/api/bluetooth/bluetooth_extension_function.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 #include "extensions/browser/event_router.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace device {
 class BluetoothAdapter;
@@ -216,8 +217,8 @@
  private:
   ~BluetoothPrivateConnectFunction() override;
 
-  void OnSuccessCallback();
-  void OnErrorCallback(device::BluetoothDevice::ConnectErrorCode error);
+  void OnConnect(
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error);
 
   std::unique_ptr<bluetooth_private::Connect::Params> params_;
 
@@ -236,8 +237,8 @@
  private:
   ~BluetoothPrivatePairFunction() override;
 
-  void OnSuccessCallback();
-  void OnErrorCallback(device::BluetoothDevice::ConnectErrorCode error);
+  void OnPair(
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
 
   std::unique_ptr<bluetooth_private::Pair::Params> params_;
 
diff --git a/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc b/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc
index f0a74fc..8e62e445 100644
--- a/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_private_apitest.cc
@@ -22,6 +22,7 @@
 #include "extensions/common/switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
+using ::base::test::RunOnceCallback;
 using ::base::test::RunOnceClosure;
 using ::device::BluetoothDiscoveryFilter;
 using ::device::BluetoothUUID;
@@ -290,7 +291,8 @@
       .Times(2)
       .WillOnce(Return(false))
       .WillOnce(Return(true));
-  EXPECT_CALL(*mock_device_, Connect_(_, _, _)).WillOnce(RunOnceClosure<1>());
+  EXPECT_CALL(*mock_device_, Connect_(_, _))
+      .WillOnce(RunOnceCallback<1>(/*error_code=*/absl::nullopt));
   ASSERT_TRUE(RunExtensionTest("bluetooth_private/connect", {},
                                {.load_as_component = true}))
       << message_;
@@ -302,12 +304,12 @@
                   _, device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH));
   EXPECT_CALL(*mock_device_, ExpectingConfirmation())
       .WillRepeatedly(Return(true));
-  EXPECT_CALL(*mock_device_, Pair_(_, _, _))
+  EXPECT_CALL(*mock_device_, Pair_(_, _))
       .WillOnce(DoAll(
           WithoutArgs(Invoke(
               this,
               &BluetoothPrivateApiTest::DispatchConfirmPasskeyPairingEvent)),
-          RunOnceClosure<1>()));
+          RunOnceCallback<1>(/*error_code=*/absl::nullopt)));
   ASSERT_TRUE(RunExtensionTest("bluetooth_private/pair", {},
                                {.load_as_component = true}))
       << message_;
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
index 03c1b4c..5a54979 100644
--- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
+++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
@@ -442,17 +442,17 @@
 
   event_router->Connect(
       persistent, extension(), params_->device_address,
-      base::BindOnce(&BluetoothLowEnergyConnectFunction::SuccessCallback, this),
-      base::BindOnce(&BluetoothLowEnergyConnectFunction::ErrorCallback, this));
+      base::BindOnce(&BluetoothLowEnergyConnectFunction::ConnectCallback,
+                     this));
 }
 
-void BluetoothLowEnergyConnectFunction::SuccessCallback() {
-  Respond(NoArguments());
-}
-
-void BluetoothLowEnergyConnectFunction::ErrorCallback(
+void BluetoothLowEnergyConnectFunction::ConnectCallback(
     BluetoothLowEnergyEventRouter::Status status) {
-  Respond(Error(StatusToString(status)));
+  if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
+    Respond(Error(StatusToString(status)));
+    return;
+  }
+  Respond(NoArguments());
 }
 
 BluetoothLowEnergyDisconnectFunction::BluetoothLowEnergyDisconnectFunction() {}
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h
index ed00b5f..eecf4800 100644
--- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h
+++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h
@@ -158,10 +158,7 @@
   std::unique_ptr<bluetooth_low_energy::Connect::Params> params_;
 
  private:
-  // Success and error callbacks, called by
-  // BluetoothLowEnergyEventRouter::Connect.
-  void SuccessCallback();
-  void ErrorCallback(BluetoothLowEnergyEventRouter::Status status);
+  void ConnectCallback(BluetoothLowEnergyEventRouter::Status status);
 };
 
 class BluetoothLowEnergyDisconnectFunction
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
index 6089b8e..6a5a5a0a 100644
--- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
+++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
@@ -211,6 +211,37 @@
   return error_status;
 }
 
+extensions::BluetoothLowEnergyEventRouter::Status
+DeviceConnectErrorCodeToStatus(BluetoothDevice::ConnectErrorCode error_code) {
+  switch (error_code) {
+    case BluetoothDevice::ERROR_AUTH_CANCELED:
+      return extensions::BluetoothLowEnergyEventRouter::kStatusErrorCanceled;
+    case BluetoothDevice::ERROR_AUTH_FAILED:
+      return extensions::BluetoothLowEnergyEventRouter::
+          kStatusErrorAuthenticationFailed;
+    case BluetoothDevice::ERROR_AUTH_REJECTED:
+      return extensions::BluetoothLowEnergyEventRouter::
+          kStatusErrorAuthenticationFailed;
+    case BluetoothDevice::ERROR_AUTH_TIMEOUT:
+      return extensions::BluetoothLowEnergyEventRouter::kStatusErrorTimeout;
+    case BluetoothDevice::ERROR_FAILED:
+      return extensions::BluetoothLowEnergyEventRouter::kStatusErrorFailed;
+    case BluetoothDevice::ERROR_INPROGRESS:
+      return extensions::BluetoothLowEnergyEventRouter::kStatusErrorInProgress;
+    case BluetoothDevice::ERROR_UNKNOWN:
+      return extensions::BluetoothLowEnergyEventRouter::kStatusErrorFailed;
+    case BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
+      return extensions::BluetoothLowEnergyEventRouter::
+          kStatusErrorUnsupportedDevice;
+    case BluetoothDevice::NUM_CONNECT_ERROR_CODES:
+      NOTREACHED();
+      return extensions::BluetoothLowEnergyEventRouter::
+          kStatusErrorInvalidArguments;
+  }
+  NOTREACHED();
+  return extensions::BluetoothLowEnergyEventRouter::kStatusErrorFailed;
+}
+
 }  // namespace
 
 namespace extensions {
@@ -298,12 +329,11 @@
 void BluetoothLowEnergyEventRouter::Connect(bool persistent,
                                             const Extension* extension,
                                             const std::string& device_address,
-                                            base::OnceClosure callback,
-                                            ErrorCallback error_callback) {
+                                            ErrorCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (!adapter_.get()) {
     VLOG(1) << "BluetoothAdapter not ready.";
-    std::move(error_callback).Run(kStatusErrorFailed);
+    std::move(callback).Run(kStatusErrorFailed);
     return;
   }
 
@@ -311,7 +341,7 @@
   const std::string connect_id = extension_id + device_address;
 
   if (connecting_devices_.count(connect_id) != 0) {
-    std::move(error_callback).Run(kStatusErrorInProgress);
+    std::move(callback).Run(kStatusErrorInProgress);
     return;
   }
 
@@ -320,7 +350,7 @@
   if (conn) {
     if (conn->GetConnection()->IsConnected()) {
       VLOG(1) << "Application already connected to device: " << device_address;
-      std::move(error_callback).Run(kStatusErrorAlreadyConnected);
+      std::move(callback).Run(kStatusErrorAlreadyConnected);
       return;
     }
 
@@ -331,7 +361,7 @@
   BluetoothDevice* device = adapter_->GetDevice(device_address);
   if (!device) {
     VLOG(1) << "Bluetooth device not found: " << device_address;
-    std::move(error_callback).Run(kStatusErrorNotFound);
+    std::move(callback).Run(kStatusErrorNotFound);
     return;
   }
 
@@ -339,10 +369,7 @@
   device->CreateGattConnection(
       base::BindOnce(&BluetoothLowEnergyEventRouter::OnCreateGattConnection,
                      weak_ptr_factory_.GetWeakPtr(), persistent, extension_id,
-                     device_address, std::move(callback)),
-      base::BindOnce(&BluetoothLowEnergyEventRouter::OnConnectError,
-                     weak_ptr_factory_.GetWeakPtr(), extension_id,
-                     device_address, std::move(error_callback)));
+                     device_address, std::move(callback)));
 }
 
 void BluetoothLowEnergyEventRouter::Disconnect(
@@ -1656,8 +1683,19 @@
     bool persistent,
     const std::string& extension_id,
     const std::string& device_address,
-    base::OnceClosure callback,
-    std::unique_ptr<BluetoothGattConnection> connection) {
+    ErrorCallback callback,
+    std::unique_ptr<BluetoothGattConnection> connection,
+    absl::optional<BluetoothDevice::ConnectErrorCode> error_code) {
+  if (error_code.has_value()) {
+    VLOG(2) << "Failed to create GATT connection: " << error_code.value();
+
+    const std::string connect_id = extension_id + device_address;
+    DCHECK_NE(0U, connecting_devices_.count(connect_id));
+
+    connecting_devices_.erase(connect_id);
+    std::move(callback).Run(DeviceConnectErrorCodeToStatus(error_code.value()));
+    return;
+  }
   VLOG(2) << "GATT connection created.";
   DCHECK(connection.get());
   DCHECK(!FindConnection(extension_id, device_address));
@@ -1673,7 +1711,7 @@
   manager->Add(conn);
 
   connecting_devices_.erase(connect_id);
-  std::move(callback).Run();
+  std::move(callback).Run(kStatusSuccess);
 }
 
 void BluetoothLowEnergyEventRouter::OnError(
@@ -1684,52 +1722,6 @@
   std::move(error_callback).Run(GattErrorToRouterError(error_code));
 }
 
-void BluetoothLowEnergyEventRouter::OnConnectError(
-    const std::string& extension_id,
-    const std::string& device_address,
-    ErrorCallback error_callback,
-    BluetoothDevice::ConnectErrorCode error_code) {
-  VLOG(2) << "Failed to create GATT connection: " << error_code;
-
-  const std::string connect_id = extension_id + device_address;
-  DCHECK_NE(0U, connecting_devices_.count(connect_id));
-
-  connecting_devices_.erase(connect_id);
-  Status error_status = kStatusErrorFailed;
-  switch (error_code) {
-    case BluetoothDevice::ERROR_AUTH_CANCELED:
-      error_status = kStatusErrorCanceled;
-      break;
-    case BluetoothDevice::ERROR_AUTH_FAILED:
-      error_status = kStatusErrorAuthenticationFailed;
-      break;
-    case BluetoothDevice::ERROR_AUTH_REJECTED:
-      error_status = kStatusErrorAuthenticationFailed;
-      break;
-    case BluetoothDevice::ERROR_AUTH_TIMEOUT:
-      error_status = kStatusErrorTimeout;
-      break;
-    case BluetoothDevice::ERROR_FAILED:
-      error_status = kStatusErrorFailed;
-      break;
-    case BluetoothDevice::ERROR_INPROGRESS:
-      error_status = kStatusErrorInProgress;
-      break;
-    case BluetoothDevice::ERROR_UNKNOWN:
-      error_status = kStatusErrorFailed;
-      break;
-    case BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
-      error_status = kStatusErrorUnsupportedDevice;
-      break;
-    case BluetoothDevice::NUM_CONNECT_ERROR_CODES:
-      NOTREACHED();
-      error_status = kStatusErrorInvalidArguments;
-      break;
-  }
-
-  std::move(error_callback).Run(error_status);
-}
-
 void BluetoothLowEnergyEventRouter::OnStartNotifySession(
     bool persistent,
     const std::string& extension_id,
diff --git a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
index 6b0e8340..cb927bfc 100644
--- a/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
+++ b/extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
@@ -30,6 +30,7 @@
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/api/bluetooth_low_energy.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 
@@ -124,14 +125,13 @@
   // Creates a GATT connection to the device with address |device_address| for
   // extension |extension|. The connection is kept alive until the extension is
   // unloaded, the device is removed, or is disconnect by the host subsystem.
-  // |error_callback| is called with an error status in case of failure. If
+  // |callback| is called with the status of the connect operation. If
   // |persistent| is true, then the allocated connection resource is persistent
   // across unloads.
   void Connect(bool persistent,
                const Extension* extension,
                const std::string& device_address,
-               base::OnceClosure callback,
-               ErrorCallback error_callback);
+               ErrorCallback callback);
 
   // Disconnects the currently open GATT connection of extension |extension| to
   // device with address |device_address|. |error_callback| is called with an
@@ -447,8 +447,9 @@
       bool persistent,
       const std::string& extension_id,
       const std::string& device_address,
-      base::OnceClosure callback,
-      std::unique_ptr<device::BluetoothGattConnection> connection);
+      ErrorCallback callback,
+      std::unique_ptr<device::BluetoothGattConnection> connection,
+      absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
 
   // Called by BluetoothGattService in response to Register().
   void OnRegisterGattServiceSuccess(const std::string& service_id,
@@ -466,12 +467,6 @@
   void OnError(ErrorCallback error_callback,
                device::BluetoothGattService::GattErrorCode error_code);
 
-  // Called by BluetoothDevice in response to a call to CreateGattConnection.
-  void OnConnectError(const std::string& extension_id,
-                      const std::string& device_address,
-                      ErrorCallback error_callback,
-                      device::BluetoothDevice::ConnectErrorCode error_code);
-
   // Called by BluetoothRemoteGattCharacteristic in response to a call to
   // StartNotifySession.
   void OnStartNotifySession(