// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device/bluetooth/adapter.h"

#include <string>
#include <utility>
#include <vector>

#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "device/bluetooth/advertisement.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/device.h"
#include "device/bluetooth/discovery_session.h"
#include "device/bluetooth/floss/floss_features.h"
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
#include "device/bluetooth/public/mojom/connect_result_type_converter.h"
#include "device/bluetooth/server_socket.h"
#include "device/bluetooth/socket.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"

#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
#include "device/bluetooth/bluez/metrics_recorder.h"
#endif

namespace bluetooth {
namespace {

const char kMojoReceivingPipeError[] = "Failed to create receiving DataPipe.";
const char kMojoSendingPipeError[] = "Failed to create sending DataPipe.";
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
const char kCannotConnectToDeviceError[] = "Cannot connect to device.";
#endif

}  // namespace

Adapter::ConnectToServiceRequestDetails::ConnectToServiceRequestDetails(
    const std::string& address,
    const device::BluetoothUUID& service_uuid,
    const base::Time& time_requested,
    const bool should_unbond_on_error,
    ConnectToServiceInsecurelyCallback callback)
    : address(address),
      service_uuid(service_uuid),
      time_requested(time_requested),
      should_unbond_on_error(should_unbond_on_error),
      callback(std::move(callback)) {}

Adapter::ConnectToServiceRequestDetails::~ConnectToServiceRequestDetails() =
    default;

Adapter::Adapter(scoped_refptr<device::BluetoothAdapter> adapter)
    : adapter_(std::move(adapter)) {
  adapter_->AddObserver(this);
}

Adapter::~Adapter() {
  for (auto& entry : connect_to_service_request_map_) {
    base::UmaHistogramMediumTimes(
        "Bluetooth.Mojo.PendingConnectAtShutdown."
        "DurationWaiting",
        base::Time::Now() - entry.second->time_requested);
  }
  base::UmaHistogramCounts100(
      "Bluetooth.Mojo.PendingConnectAtShutdown."
      "NumberOfServiceDiscoveriesInProgress",
      connect_to_service_requests_pending_discovery_.size());

  adapter_->RemoveObserver(this);
  adapter_ = nullptr;
}

void Adapter::ConnectToDevice(const std::string& address,
                              ConnectToDeviceCallback callback) {
  device::BluetoothDevice* device = adapter_->GetDevice(address);

  if (!device) {
    std::move(callback).Run(mojom::ConnectResult::DEVICE_NO_LONGER_IN_RANGE,
                            /*device=*/mojo::NullRemote());
    return;
  }

  device->CreateGattConnection(base::BindOnce(&Adapter::OnGattConnect,
                                              weak_ptr_factory_.GetWeakPtr(),
                                              std::move(callback)));
}

void Adapter::GetDevices(GetDevicesCallback callback) {
  std::vector<mojom::DeviceInfoPtr> devices;

  for (const device::BluetoothDevice* device : adapter_->GetDevices()) {
    mojom::DeviceInfoPtr device_info =
        Device::ConstructDeviceInfoStruct(device);
    devices.push_back(std::move(device_info));
  }

  std::move(callback).Run(std::move(devices));
}

void Adapter::GetInfo(GetInfoCallback callback) {
  mojom::AdapterInfoPtr adapter_info = mojom::AdapterInfo::New();
  adapter_info->address = adapter_->GetAddress();
  adapter_info->name = adapter_->GetName();
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
  adapter_info->system_name = adapter_->GetSystemName();
  adapter_info->floss = floss::features::IsFlossEnabled();
#endif
  adapter_info->initialized = adapter_->IsInitialized();
  adapter_info->present = adapter_->IsPresent();
  adapter_info->powered = adapter_->IsPowered();
  adapter_info->discoverable = adapter_->IsDiscoverable();
  adapter_info->discovering = adapter_->IsDiscovering();
  std::move(callback).Run(std::move(adapter_info));
}

void Adapter::AddObserver(mojo::PendingRemote<mojom::AdapterObserver> observer,
                          AddObserverCallback callback) {
  observers_.Add(std::move(observer));
  std::move(callback).Run();
}

void Adapter::RegisterAdvertisement(const device::BluetoothUUID& service_uuid,
                                    const std::vector<uint8_t>& service_data,
                                    bool use_scan_response,
                                    RegisterAdvertisementCallback callback) {
  auto advertisement_data =
      std::make_unique<device::BluetoothAdvertisement::Data>(
          device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);

  device::BluetoothAdvertisement::UUIDList uuid_list;
  uuid_list.push_back(service_uuid.value());
  advertisement_data->set_service_uuids(std::move(uuid_list));

  if (!use_scan_response) {
    device::BluetoothAdvertisement::ServiceData service_data_map;
    service_data_map.emplace(service_uuid.value(), service_data);
    advertisement_data->set_service_data(std::move(service_data_map));
  } else {
    // Require the service uuid to be in 128-bit format.
    DCHECK_EQ(service_uuid.format(),
              device::BluetoothUUID::Format::kFormat128Bit);
    device::BluetoothAdvertisement::ScanResponseData scan_response_data_map;
    // Start with the original scan response data.
    std::vector<uint8_t> scan_response_data(service_data.begin(),
                                            service_data.end());
    // Now insert in front of the service data the identifying 2-bytes of the
    // service id assuming this is a valid 16-bit uuid. For example, the uuid:
    // 0000fef3-0000-1000-8000-00805f9b34fb can be uniquely defined by two bytes
    // ****fef3-****-****-****-************ the rest is the same for all 16-bit
    // uuids as defined by the Bluetooth spec. We insert them in little endian
    // ordering 0xf3 first, then 0xfe in for this example.
    auto service_id_bytes = service_uuid.GetBytes();
    // Take bytes 2 and 3.
    auto id_bytes = base::make_span(service_id_bytes).subspan(2, 2);
    // Add them in reverse order (little endian).
    scan_response_data.insert(scan_response_data.begin(), id_bytes.rbegin(),
                              id_bytes.rend());
    // The platform API only supports AD Type 0x16 "Service Data" which assumes
    // as 16-bit service id.
    scan_response_data_map.emplace(0x16, scan_response_data);
    advertisement_data->set_scan_response_data(
        std::move(scan_response_data_map));
  }

  auto split_callback = base::SplitOnceCallback(std::move(callback));
  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      base::BindOnce(&Adapter::OnRegisterAdvertisement,
                     weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.first)),
      base::BindOnce(&Adapter::OnRegisterAdvertisementError,
                     weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.second)));
}

void Adapter::SetDiscoverable(bool discoverable,
                              SetDiscoverableCallback callback) {
  auto split_callback = base::SplitOnceCallback(std::move(callback));
  adapter_->SetDiscoverable(discoverable,
                            base::BindOnce(&Adapter::OnSetDiscoverable,
                                           weak_ptr_factory_.GetWeakPtr(),
                                           std::move(split_callback.first)),
                            base::BindOnce(&Adapter::OnSetDiscoverableError,
                                           weak_ptr_factory_.GetWeakPtr(),
                                           std::move(split_callback.second)));
}

void Adapter::SetName(const std::string& name, SetNameCallback callback) {
  auto split_callback = base::SplitOnceCallback(std::move(callback));
  adapter_->SetName(
      name,
      base::BindOnce(&Adapter::OnSetName, weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.first)),
      base::BindOnce(&Adapter::OnSetNameError, weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.second)));
}

void Adapter::StartDiscoverySession(const std::string& client_name,
                                    StartDiscoverySessionCallback callback) {
  auto split_callback = base::SplitOnceCallback(std::move(callback));
  adapter_->StartDiscoverySession(
      client_name,
      base::BindOnce(&Adapter::OnStartDiscoverySession,
                     weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.first)),
      base::BindOnce(&Adapter::OnDiscoverySessionError,
                     weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.second)));
}

void Adapter::ConnectToServiceInsecurely(
    const std::string& address,
    const device::BluetoothUUID& service_uuid,
    bool should_unbond_on_error,
    ConnectToServiceInsecurelyCallback callback) {
  if (!base::Contains(allowed_uuids_, service_uuid)) {
    std::move(callback).Run(/*result=*/nullptr);
    return;
  }

  auto* device = adapter_->GetDevice(address);
  int request_id = next_request_id_++;
  connect_to_service_request_map_.emplace(
      request_id, std::make_unique<ConnectToServiceRequestDetails>(
                      address, service_uuid, base::Time::Now(),
                      should_unbond_on_error, std::move(callback)));

  if (device) {
    OnDeviceFetchedForInsecureServiceConnection(request_id, device);
    return;
  }

  // This device has neither been discovered, nor has it been paired/connected
  // to previously. Use the ConnectDevice() API, if available, to connect to it.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
  adapter_->ConnectDevice(
      address, /*address_type=*/std::nullopt,
      base::BindOnce(&Adapter::OnDeviceFetchedForInsecureServiceConnection,
                     weak_ptr_factory_.GetWeakPtr(), request_id),
      base::BindOnce(&Adapter::OnConnectToServiceError,
                     weak_ptr_factory_.GetWeakPtr(), request_id));
#else
  OnConnectToServiceError(request_id, "Device does not exist.");
#endif
}

void Adapter::CreateRfcommServiceInsecurely(
    const std::string& service_name,
    const device::BluetoothUUID& service_uuid,
    CreateRfcommServiceInsecurelyCallback callback) {
  if (!base::Contains(allowed_uuids_, service_uuid)) {
    std::move(callback).Run(/*server_socket=*/mojo::NullRemote());
    return;
  }

  device::BluetoothAdapter::ServiceOptions service_options;
  service_options.name = service_name;
  service_options.require_authentication = false;

  auto split_callback = base::SplitOnceCallback(std::move(callback));
  adapter_->CreateRfcommService(
      service_uuid, service_options,
      base::BindOnce(&Adapter::OnCreateRfcommServiceInsecurely,
                     weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.first)),
      base::BindOnce(&Adapter::OnCreateRfcommServiceInsecurelyError,
                     weak_ptr_factory_.GetWeakPtr(),
                     std::move(split_callback.second)));
}

void Adapter::AdapterPresentChanged(device::BluetoothAdapter* adapter,
                                    bool present) {
  for (auto& observer : observers_)
    observer->PresentChanged(present);
}

void Adapter::AdapterPoweredChanged(device::BluetoothAdapter* adapter,
                                    bool powered) {
  for (auto& observer : observers_)
    observer->PoweredChanged(powered);
}

void Adapter::AdapterDiscoverableChanged(device::BluetoothAdapter* adapter,
                                         bool discoverable) {
  for (auto& observer : observers_)
    observer->DiscoverableChanged(discoverable);
}

void Adapter::AdapterDiscoveringChanged(device::BluetoothAdapter* adapter,
                                        bool discovering) {
  for (auto& observer : observers_)
    observer->DiscoveringChanged(discovering);
}

void Adapter::DeviceAdded(device::BluetoothAdapter* adapter,
                          device::BluetoothDevice* device) {
  for (auto& observer : observers_)
    observer->DeviceAdded(Device::ConstructDeviceInfoStruct(device));
}

void Adapter::DeviceChanged(device::BluetoothAdapter* adapter,
                            device::BluetoothDevice* device) {
  // Because paired Bluetooth devices never fire device-removed events, we also
  // consider a null RSSI indicative of a device no longer being discoverable.
  // In this scenario, we fail any pending connection requests.
  if (!device->GetInquiryRSSI()) {
    ProcessPendingInsecureServiceConnectionRequest(device->GetAddress(),
                                                   /*device=*/nullptr);
  }

  for (auto& observer : observers_)
    observer->DeviceChanged(Device::ConstructDeviceInfoStruct(device));
}

void Adapter::DeviceRemoved(device::BluetoothAdapter* adapter,
                            device::BluetoothDevice* device) {
  ProcessPendingInsecureServiceConnectionRequest(device->GetAddress(),
                                                 /*device=*/nullptr);

  for (auto& observer : observers_)
    observer->DeviceRemoved(Device::ConstructDeviceInfoStruct(device));
}

void Adapter::GattServicesDiscovered(device::BluetoothAdapter* adapter,
                                     device::BluetoothDevice* device) {
  // GattServicesDiscovered() and IsGattServicesDiscoveryComplete() actually
  // indicate that all services on the remote device, including SDP, are
  // resolved. Once service probing for a device within a cached request (in
  // |pending_connect_to_service_args_|) concludes, attempt socket creation
  // again via OnDeviceFetchedForInsecureServiceConnection().
  if (device->IsGattServicesDiscoveryComplete()) {
    ProcessPendingInsecureServiceConnectionRequest(device->GetAddress(),
                                                   device);
  }
}

void Adapter::AllowConnectionsForUuid(
    const device::BluetoothUUID& service_uuid) {
  allowed_uuids_.emplace(service_uuid);
}

void Adapter::OnDeviceFetchedForInsecureServiceConnection(
    int request_id,
    device::BluetoothDevice* device) {
  DCHECK(connect_to_service_request_map_.contains(request_id));

  if (!device) {
    ExecuteConnectToServiceCallback(request_id, /*result=*/nullptr);
    return;
  }

  if (!device->IsPaired() && device->IsConnected() &&
      !device->IsGattServicesDiscoveryComplete()) {
    // This provided device is most likely a result of calling ConnectDevice():
    // it's connected, but the remote device's services are still being probed
    // (IsGattServicesDiscoveryComplete() refers to all services, not just GATT
    // services). That means attempting ConnectToServiceInsecurely() right now
    // would fail with an "InProgress" error. Wait for GattServicesDiscovered()
    // to be called to signal that ConnectToServiceInsecurely() can be called.
    connect_to_service_requests_pending_discovery_.push_back(request_id);
    return;
  }

  device->ConnectToServiceInsecurely(
      connect_to_service_request_map_[request_id]->service_uuid,
      base::BindOnce(&Adapter::OnConnectToService,
                     weak_ptr_factory_.GetWeakPtr(), request_id),
      base::BindOnce(&Adapter::OnConnectToServiceInsecurelyError,
                     weak_ptr_factory_.GetWeakPtr(), request_id));
}

void Adapter::ProcessPendingInsecureServiceConnectionRequest(
    const std::string& address,
    device::BluetoothDevice* device) {
  auto it = connect_to_service_requests_pending_discovery_.begin();
  while (it != connect_to_service_requests_pending_discovery_.end()) {
    auto request_it = connect_to_service_request_map_.find(*it);
    DCHECK(request_it != connect_to_service_request_map_.end());
    if (address == request_it->second->address) {
      OnDeviceFetchedForInsecureServiceConnection(*it, device);
      it = connect_to_service_requests_pending_discovery_.erase(it);
    } else {
      ++it;
    }
  }
}

void Adapter::OnGattConnect(
    ConnectToDeviceCallback callback,
    std::unique_ptr<device::BluetoothGattConnection> connection,
    std::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::OnRegisterAdvertisement(
    RegisterAdvertisementCallback callback,
    scoped_refptr<device::BluetoothAdvertisement> advertisement) {
  mojo::PendingRemote<mojom::Advertisement> pending_advertisement;
  mojo::MakeSelfOwnedReceiver(
      std::make_unique<Advertisement>(std::move(advertisement)),
      pending_advertisement.InitWithNewPipeAndPassReceiver());
  std::move(callback).Run(std::move(pending_advertisement));
}

void Adapter::OnRegisterAdvertisementError(
    RegisterAdvertisementCallback callback,
    device::BluetoothAdvertisement::ErrorCode error_code) {
  DLOG(ERROR) << "Failed to register advertisement, error code: " << error_code;
  std::move(callback).Run(/*advertisement=*/mojo::NullRemote());
}

void Adapter::OnSetDiscoverable(SetDiscoverableCallback callback) {
  std::move(callback).Run(/*success=*/true);
}

void Adapter::OnSetDiscoverableError(SetDiscoverableCallback callback) {
  std::move(callback).Run(/*success=*/false);
}

void Adapter::OnSetName(SetNameCallback callback) {
  std::move(callback).Run(/*success=*/true);
}

void Adapter::OnSetNameError(SetNameCallback callback) {
  std::move(callback).Run(/*success=*/false);
}

void Adapter::OnStartDiscoverySession(
    StartDiscoverySessionCallback callback,
    std::unique_ptr<device::BluetoothDiscoverySession> session) {
  mojo::PendingRemote<mojom::DiscoverySession> pending_session;
  mojo::MakeSelfOwnedReceiver(
      std::make_unique<DiscoverySession>(std::move(session)),
      pending_session.InitWithNewPipeAndPassReceiver());
  std::move(callback).Run(std::move(pending_session));
}

void Adapter::OnDiscoverySessionError(StartDiscoverySessionCallback callback) {
  std::move(callback).Run(/*session=*/mojo::NullRemote());
}

void Adapter::OnConnectToService(
    int request_id,
    scoped_refptr<device::BluetoothSocket> socket) {
  mojo::ScopedDataPipeProducerHandle receive_pipe_producer_handle;
  mojo::ScopedDataPipeConsumerHandle receive_pipe_consumer_handle;
  MojoResult result =
      mojo::CreateDataPipe(/*options=*/nullptr, receive_pipe_producer_handle,
                           receive_pipe_consumer_handle);
  if (result != MOJO_RESULT_OK) {
    socket->Disconnect(base::BindOnce(&Adapter::OnConnectToServiceError,
                                      weak_ptr_factory_.GetWeakPtr(),
                                      request_id, kMojoReceivingPipeError));
    return;
  }

  mojo::ScopedDataPipeProducerHandle send_pipe_producer_handle;
  mojo::ScopedDataPipeConsumerHandle send_pipe_consumer_handle;
  result = mojo::CreateDataPipe(/*options=*/nullptr, send_pipe_producer_handle,
                                send_pipe_consumer_handle);
  if (result != MOJO_RESULT_OK) {
    socket->Disconnect(base::BindOnce(&Adapter::OnConnectToServiceError,
                                      weak_ptr_factory_.GetWeakPtr(),
                                      request_id, kMojoSendingPipeError));
    return;
  }

  mojo::PendingRemote<mojom::Socket> pending_socket;
  mojo::MakeSelfOwnedReceiver(
      std::make_unique<Socket>(std::move(socket),
                               std::move(receive_pipe_producer_handle),
                               std::move(send_pipe_consumer_handle)),
      pending_socket.InitWithNewPipeAndPassReceiver());

  mojom::ConnectToServiceResultPtr connect_to_service_result =
      mojom::ConnectToServiceResult::New();
  connect_to_service_result->socket = std::move(pending_socket);
  connect_to_service_result->receive_stream =
      std::move(receive_pipe_consumer_handle);
  connect_to_service_result->send_stream = std::move(send_pipe_producer_handle);
  ExecuteConnectToServiceCallback(request_id,
                                  std::move(connect_to_service_result));

#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
  RecordConnectToServiceInsecurelyResult(
      ConnectToServiceInsecurelyResult::kSuccess);
#endif
}

void Adapter::OnConnectToServiceError(int request_id,
                                      const std::string& message) {
  DLOG(ERROR) << "Failed to connect to service: '" << message << "'";
  ExecuteConnectToServiceCallback(request_id, /*result=*/nullptr);

#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
  std::optional<ConnectToServiceInsecurelyResult> result =
      ExtractResultFromErrorString(message);
  if (result) {
    RecordConnectToServiceInsecurelyResult(*result);
  } else if (message == kMojoSendingPipeError) {
    RecordConnectToServiceInsecurelyResult(
        ConnectToServiceInsecurelyResult::kMojoSendingPipeError);
  } else if (message == kMojoReceivingPipeError) {
    RecordConnectToServiceInsecurelyResult(
        ConnectToServiceInsecurelyResult::kMojoReceivingPipeError);
  } else if (message == kCannotConnectToDeviceError) {
    RecordConnectToServiceInsecurelyResult(
        ConnectToServiceInsecurelyResult::kCouldNotConnectError);
  } else {
    RecordConnectToServiceInsecurelyResult(
        ConnectToServiceInsecurelyResult::kUnknownError);
  }
#endif
}

void Adapter::OnConnectToServiceInsecurelyError(
    int request_id,
    const std::string& error_message) {
  DCHECK(connect_to_service_request_map_.contains(request_id));
  DLOG(ERROR) << error_message;

#if BUILDFLAG(IS_CHROMEOS)
  device::BluetoothDevice* device =
      adapter_->GetDevice(connect_to_service_request_map_[request_id]->address);
  DCHECK(device);

  ConnectToServiceFailureReason failure_reason =
      ExtractFailureReasonFromErrorString(error_message);
  // When the local device thinks it's paired with the remote device (IsBonded)
  // and we receive one of these errors when trying to connect, then we're most
  // likely in a state where the remote device doesn't recognize the pairing
  // (half-paired).
  bool is_half_paired_failure =
      device->IsBonded() &&
      (failure_reason == ConnectToServiceFailureReason::kReasonCanceled ||
       failure_reason == ConnectToServiceFailureReason::kReasonRefused ||
       failure_reason == ConnectToServiceFailureReason::kReasonUnknown);

  if (is_half_paired_failure &&
      connect_to_service_request_map_[request_id]->should_unbond_on_error) {
    // To recover from the half-paired state, just forget the remote device.
    // This strategy works because the local device will continue attempting to
    // connect. On the next attempt, it will no longer be in the half-paired
    // state.
    DLOG(ERROR) << "Half-paired state detected. Forgetting the device.";
    device->Forget(base::BindOnce(&Adapter::OnConnectToServiceError,
                                  weak_ptr_factory_.GetWeakPtr(), request_id,
                                  error_message),
                   base::BindOnce(&Adapter::OnConnectToServiceError,
                                  weak_ptr_factory_.GetWeakPtr(), request_id,
                                  error_message));
    return;
  }
#endif

  OnConnectToServiceError(request_id, error_message);
}

void Adapter::OnCreateRfcommServiceInsecurely(
    CreateRfcommServiceInsecurelyCallback callback,
    scoped_refptr<device::BluetoothSocket> socket) {
  mojo::PendingRemote<mojom::ServerSocket> pending_server_socket;
  mojo::MakeSelfOwnedReceiver(
      std::make_unique<ServerSocket>(std::move(socket)),
      pending_server_socket.InitWithNewPipeAndPassReceiver());
  std::move(callback).Run(std::move(pending_server_socket));
}

void Adapter::OnCreateRfcommServiceInsecurelyError(
    CreateRfcommServiceInsecurelyCallback callback,
    const std::string& message) {
  LOG(ERROR) << "Failed to create service: '" << message << "'";
  std::move(callback).Run(/*server_socket=*/mojo::NullRemote());
}

void Adapter::ExecuteConnectToServiceCallback(
    int request_id,
    mojom::ConnectToServiceResultPtr result) {
  auto it = connect_to_service_request_map_.find(request_id);
  DCHECK(it != connect_to_service_request_map_.end());

  std::move(it->second->callback).Run(std::move(result));
  connect_to_service_request_map_.erase(it);
}

}  // namespace bluetooth
