chromium/device/bluetooth/bluez/bluetooth_adapter_bluez.cc

// Copyright 2013 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/bluez/bluetooth_adapter_bluez.h"

#include <algorithm>
#include <cstdint>
#include <limits>
#include <memory>
#include <set>
#include <string>
#include <utility>

#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chromeos/constants/chromeos_features.h"
#include "components/device_event_log/device_event_log.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_discovery_session_outcome.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/bluez/bluetooth_adapter_profile_bluez.h"
#include "device/bluetooth/bluez/bluetooth_advertisement_bluez.h"
#include "device/bluetooth/bluez/bluetooth_device_bluez.h"
#include "device/bluetooth/bluez/bluetooth_gatt_service_bluez.h"
#include "device/bluetooth/bluez/bluetooth_local_gatt_characteristic_bluez.h"
#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
#include "device/bluetooth/bluez/bluetooth_pairing_bluez.h"
#include "device/bluetooth/bluez/bluetooth_socket_bluez.h"
#include "device/bluetooth/bluez/bluez_features.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "device/bluetooth/chromeos_platform_features.h"
#endif // BUILDFLAG(IS_CHROMEOS)
#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
#include "device/bluetooth/dbus/bluetooth_admin_policy_client.h"
#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
#include "device/bluetooth/dbus/bluetooth_battery_client.h"
#include "device/bluetooth/dbus/bluetooth_debug_manager_client.h"
#include "device/bluetooth/dbus/bluetooth_device_client.h"
#include "device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h"
#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h"
#include "device/bluetooth/dbus/bluetooth_input_client.h"
#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "device/bluetooth/public/cpp/bluetooth_address.h"
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "base/unguessable_token.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluez/bluetooth_low_energy_scan_session_bluez.h"
#include "device/bluetooth/chromeos/bluetooth_connection_logger.h"
#include "device/bluetooth/chromeos/bluetooth_utils.h"
#include "device/bluetooth/dbus/bluetooth_advertisement_monitor_application_service_provider.h"
#include "device/bluetooth/dbus/bluetooth_advertisement_monitor_manager_client.h"
#include "device/bluetooth/dbus/bluetooth_advertisement_monitor_service_provider.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/devicetype.h"
#include "chromeos/ash/services/nearby/public/cpp/nearby_client_uuids.h"
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

BluetoothAdapter;
BluetoothDevice;
BatteryInfo;
BatteryType;
UUIDSet;
BluetoothDiscoveryFilter;
BluetoothSocket;
BluetoothUUID;
UMABluetoothDiscoverySessionOutcome;

namespace {

// The agent path is relatively meaningless since BlueZ only permits one to
// exist per D-Bus connection, it just has to be unique within Chromium.
const char kAgentPath[] =;
const char kGattApplicationObjectPath[] =;

const char kDeviceNameArcTouch[] =;

#if BUILDFLAG(IS_CHROMEOS)
// This root path identifies the application registering low energy scanners
// through D-Bus.
constexpr char kAdvertisementMonitorApplicationObjectPath[] =
    "/org/chromium/bluetooth_advertisement_monitor";
#endif  // BUILDFLAG(IS_CHROMEOS)

void OnUnregisterAgentError(const std::string& error_name,
                            const std::string& error_message) {}

UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA(
    const std::string& error_name) {}

#if BUILDFLAG(IS_CHROMEOS)
device::BluetoothDevice::ServiceDataMap ConvertServiceDataMap(
    const base::flat_map<std::string, std::vector<uint8_t>>& input) {
  device::BluetoothDevice::ServiceDataMap output;
  for (auto& i : input) {
    output[BluetoothUUID(i.first)] = i.second;
  }

  return output;
}

device::BluetoothDevice::ManufacturerDataMap ConvertManufacturerDataMap(
    const base::flat_map<uint16_t, std::vector<uint8_t>>& input) {
  return device::BluetoothDevice::ManufacturerDataMap(input.begin(),
                                                      input.end());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

bool IsBatteryDisplayBlocklisted(const BluetoothDevice* device) {}

}  // namespace

namespace bluez {

namespace {

void OnRegistrationErrorCallback(
    device::BluetoothGattService::ErrorCallback error_callback,
    bool is_register_callback,
    const std::string& error_name,
    const std::string& error_message) {}

void SetIntervalErrorCallbackConnector(
    device::BluetoothAdapter::AdvertisementErrorCallback error_callback,
    const std::string& error_name,
    const std::string& error_message) {}

void ResetAdvertisingErrorCallbackConnector(
    device::BluetoothAdapter::AdvertisementErrorCallback error_callback,
    const std::string& error_name,
    const std::string& error_message) {}

#if BUILDFLAG(IS_CHROMEOS)
void SetServiceAllowListErrorCallback(
    BluetoothAdapterBlueZ::ErrorCallback error_callback,
    const std::string& error_name,
    const std::string& error_message) {
  BLUETOOTH_LOG(ERROR) << "Error while settting service allow list."
                          " error_name = "
                       << error_name << ", error_message = " << error_message;
  std::move(error_callback).Run();
}
#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace

// static
scoped_refptr<BluetoothAdapterBlueZ> BluetoothAdapterBlueZ::CreateAdapter() {}

void BluetoothAdapterBlueZ::Initialize(base::OnceClosure callback) {}

void BluetoothAdapterBlueZ::Shutdown() {}

BluetoothAdapterBlueZ::BluetoothAdapterBlueZ()
    :{}

void BluetoothAdapterBlueZ::Init() {}

BluetoothAdapterBlueZ::~BluetoothAdapterBlueZ() {}

#if BUILDFLAG(IS_CHROMEOS)
void BluetoothAdapterBlueZ::OnSetDevCoredumpSuccess() {
  bool flag = base::FeatureList::IsEnabled(
      chromeos::bluetooth::features::kBluetoothCoredump);
  BLUETOOTH_LOG(DEBUG) << "Bluetooth devcoredump state set to " << flag;
}

void BluetoothAdapterBlueZ::OnSetDevCoredumpError(
    const std::string& error_name,
    const std::string& error_message) {
  BLUETOOTH_LOG(ERROR) << "Failed to update bluetooth devcoredump state: "
                       << error_name << ": " << error_message;
}
#endif // BUILDFLAG(IS_CHROMEOS)

std::string BluetoothAdapterBlueZ::GetAddress() const {}

std::string BluetoothAdapterBlueZ::GetName() const {}

std::string BluetoothAdapterBlueZ::GetSystemName() const {}

void BluetoothAdapterBlueZ::SetName(const std::string& name,
                                    base::OnceClosure callback,
                                    ErrorCallback error_callback) {}

bool BluetoothAdapterBlueZ::IsInitialized() const {}

bool BluetoothAdapterBlueZ::IsPresent() const {}

bool BluetoothAdapterBlueZ::IsPowered() const {}

void BluetoothAdapterBlueZ::SetPowered(bool powered,
                                       base::OnceClosure callback,
                                       ErrorCallback error_callback) {}

bool BluetoothAdapterBlueZ::IsDiscoverable() const {}

void BluetoothAdapterBlueZ::SetDiscoverable(bool discoverable,
                                            base::OnceClosure callback,
                                            ErrorCallback error_callback) {}

base::TimeDelta BluetoothAdapterBlueZ::GetDiscoverableTimeout() const {}

bool BluetoothAdapterBlueZ::IsDiscovering() const {}

bool BluetoothAdapterBlueZ::IsDiscoveringForTesting() const {}

std::unordered_map<BluetoothDevice*, UUIDSet>
BluetoothAdapterBlueZ::RetrieveGattConnectedDevicesWithDiscoveryFilter(
    const BluetoothDiscoveryFilter& discovery_filter) {}

BluetoothAdapterBlueZ::UUIDList BluetoothAdapterBlueZ::GetUUIDs() const {}

void BluetoothAdapterBlueZ::CreateRfcommService(
    const BluetoothUUID& uuid,
    const ServiceOptions& options,
    CreateServiceCallback callback,
    CreateServiceErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::CreateL2capService(
    const BluetoothUUID& uuid,
    const ServiceOptions& options,
    CreateServiceCallback callback,
    CreateServiceErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::RegisterAdvertisement(
    std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data,
    CreateAdvertisementCallback callback,
    AdvertisementErrorCallback error_callback) {}

#if BUILDFLAG(IS_CHROMEOS)
bool BluetoothAdapterBlueZ::IsExtendedAdvertisementsAvailable() const {
  if (!IsPresent()) {
    return false;
  }

  BluetoothLEAdvertisingManagerClient::Properties* properties =
      bluez::BluezDBusManager::Get()
          ->GetBluetoothLEAdvertisingManagerClient()
          ->GetProperties(object_path_);

  if (!properties) {
    return false;
  }

  // Based on the implementation of kernel bluez, if the controller supports Ext
  // Advertisement, it must support HardwareOffload.
  // (net/bluetooth/mgmt.c:get_supported_adv_flags)
  return base::Contains(
      properties->supported_features.value(),
      bluetooth_advertising_manager::kSupportedFeaturesHardwareOffload);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

void BluetoothAdapterBlueZ::SetAdvertisingInterval(
    const base::TimeDelta& min,
    const base::TimeDelta& max,
    base::OnceClosure callback,
    AdvertisementErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::ResetAdvertising(
    base::OnceClosure callback,
    AdvertisementErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::ConnectDevice(
    const std::string& address,
    const std::optional<device::BluetoothDevice::AddressType>& address_type,
    ConnectDeviceCallback callback,
    ConnectDeviceErrorCallback error_callback) {}

device::BluetoothLocalGattService* BluetoothAdapterBlueZ::GetGattService(
    const std::string& identifier) const {}

base::WeakPtr<device::BluetoothLocalGattService>
BluetoothAdapterBlueZ::CreateLocalGattService(
    const device::BluetoothUUID& uuid,
    bool is_primary,
    device::BluetoothLocalGattService::Delegate* delegate) {}

void BluetoothAdapterBlueZ::RemovePairingDelegateInternal(
    BluetoothDevice::PairingDelegate* pairing_delegate) {}

void BluetoothAdapterBlueZ::AdapterAdded(const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::AdapterRemoved(
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::AdapterPropertyChanged(
    const dbus::ObjectPath& object_path,
    const std::string& property_name) {}

void BluetoothAdapterBlueZ::AdminPolicyAdded(
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::AdminPolicyRemoved(
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::AdminPolicyPropertyChanged(
    const dbus::ObjectPath& object_path,
    const std::string& property_name) {}

void BluetoothAdapterBlueZ::BatteryAdded(const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::BatteryRemoved(
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::BatteryPropertyChanged(
    const dbus::ObjectPath& object_path,
    const std::string& property_name) {}

void BluetoothAdapterBlueZ::DeviceAdded(const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::DeviceRemoved(const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::DevicePropertyChanged(
    const dbus::ObjectPath& object_path,
    const std::string& property_name) {}

void BluetoothAdapterBlueZ::InputPropertyChanged(
    const dbus::ObjectPath& object_path,
    const std::string& property_name) {}

void BluetoothAdapterBlueZ::AgentManagerAdded(
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::AgentManagerRemoved(
    const dbus::ObjectPath& object_path) {}

#if BUILDFLAG(IS_CHROMEOS)
void BluetoothAdapterBlueZ::SupportedAdvertisementMonitorFeaturesChanged() {
  NotifyLowEnergyScanSessionHardwareOffloadingStatusChanged(
      GetLowEnergyScanSessionHardwareOffloadingStatus());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

void BluetoothAdapterBlueZ::Released() {}

void BluetoothAdapterBlueZ::RequestPinCode(const dbus::ObjectPath& device_path,
                                           PinCodeCallback callback) {}

void BluetoothAdapterBlueZ::DisplayPinCode(const dbus::ObjectPath& device_path,
                                           const std::string& pincode) {}

void BluetoothAdapterBlueZ::RequestPasskey(const dbus::ObjectPath& device_path,
                                           PasskeyCallback callback) {}

void BluetoothAdapterBlueZ::DisplayPasskey(const dbus::ObjectPath& device_path,
                                           uint32_t passkey,
                                           uint16_t entered) {}

void BluetoothAdapterBlueZ::RequestConfirmation(
    const dbus::ObjectPath& device_path,
    uint32_t passkey,
    ConfirmationCallback callback) {}

void BluetoothAdapterBlueZ::RequestAuthorization(
    const dbus::ObjectPath& device_path,
    ConfirmationCallback callback) {}

void BluetoothAdapterBlueZ::AuthorizeService(
    const dbus::ObjectPath& device_path,
    const std::string& uuid,
    ConfirmationCallback callback) {}

void BluetoothAdapterBlueZ::Cancel() {}

void BluetoothAdapterBlueZ::OnSetLLPrivacySuccess() {}

void BluetoothAdapterBlueZ::OnSetLLPrivacyError(
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::OnRegisterAgent() {}

void BluetoothAdapterBlueZ::OnRegisterAgentError(
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::OnRequestDefaultAgent() {}

void BluetoothAdapterBlueZ::OnRequestDefaultAgentError(
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::CreateServiceRecord(
    const BluetoothServiceRecordBlueZ& record,
    ServiceRecordCallback callback,
    ServiceRecordErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::RemoveServiceRecord(
    uint32_t handle,
    base::OnceClosure callback,
    ServiceRecordErrorCallback error_callback) {}

BluetoothDeviceBlueZ* BluetoothAdapterBlueZ::GetDeviceWithPath(
    const dbus::ObjectPath& object_path) {}

BluetoothPairingBlueZ* BluetoothAdapterBlueZ::GetPairing(
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::SetAdapter(const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::RemoveAdapter() {}

void BluetoothAdapterBlueZ::DiscoverableChanged(bool discoverable) {}

void BluetoothAdapterBlueZ::DiscoveringChanged(bool discovering) {}

void BluetoothAdapterBlueZ::PresentChanged(bool present) {}

void BluetoothAdapterBlueZ::NotifyDeviceAddressChanged(
    BluetoothDeviceBlueZ* device,
    const std::string& old_address) {}

void BluetoothAdapterBlueZ::NotifyDeviceMTUChanged(BluetoothDeviceBlueZ* device,
                                                   uint16_t mtu) {}

void BluetoothAdapterBlueZ::NotifyDeviceAdvertisementReceived(
    BluetoothDeviceBlueZ* device,
    int16_t rssi,
    const std::vector<uint8_t>& eir) {}

#if BUILDFLAG(IS_CHROMEOS)
void BluetoothAdapterBlueZ::OnAdvertisementReceived(
    std::string device_address,
    std::string device_name,
    uint8_t rssi,
    uint16_t device_appearance,
    const dbus::ObjectPath& device_path,
    ScanRecordPtr scan_record) {
  // Ignore the packet if it could not be parsed successfully.
  if (!scan_record)
    return;

  auto service_data_map = ConvertServiceDataMap(scan_record->service_data_map);
  auto manufacturer_data_map =
      ConvertManufacturerDataMap(scan_record->manufacturer_data_map);
  for (auto& observer : observers_) {
    observer.DeviceAdvertisementReceived(
        device_address, device_name, scan_record->advertisement_name, rssi,
        scan_record->tx_power, device_appearance, scan_record->service_uuids,
        service_data_map, manufacturer_data_map);
  }

  BluetoothDeviceBlueZ* device = GetDeviceWithPath(device_path);
  if (!device) {
    BLUETOOTH_LOG(ERROR) << "Device " << device_path.value() << " not found!";
    return;
  }

  device->SetAdvertisedUUIDs(scan_record->service_uuids);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

void BluetoothAdapterBlueZ::NotifyDeviceConnectedStateChanged(
    BluetoothDeviceBlueZ* device,
    bool is_now_connected) {}

void BluetoothAdapterBlueZ::UseProfile(
    const BluetoothUUID& uuid,
    const dbus::ObjectPath& device_path,
    const bluez::BluetoothProfileManagerClient::Options& options,
    bluez::BluetoothProfileServiceProvider::Delegate* delegate,
    ProfileRegisteredCallback success_callback,
    ErrorCompletionCallback error_callback) {}

void BluetoothAdapterBlueZ::ReleaseProfile(
    const dbus::ObjectPath& device_path,
    BluetoothAdapterProfileBlueZ* profile) {}

void BluetoothAdapterBlueZ::RemoveProfile(const BluetoothUUID& uuid) {}

void BluetoothAdapterBlueZ::AddLocalGattService(
    std::unique_ptr<BluetoothLocalGattServiceBlueZ> service) {}

void BluetoothAdapterBlueZ::RemoveLocalGattService(
    BluetoothLocalGattServiceBlueZ* service) {}

void BluetoothAdapterBlueZ::RegisterGattService(
    BluetoothLocalGattServiceBlueZ* service,
    base::OnceClosure callback,
    device::BluetoothGattService::ErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::UnregisterGattService(
    BluetoothLocalGattServiceBlueZ* service,
    base::OnceClosure callback,
    device::BluetoothGattService::ErrorCallback error_callback) {}

bool BluetoothAdapterBlueZ::IsGattServiceRegistered(
    BluetoothLocalGattServiceBlueZ* service) {}

bool BluetoothAdapterBlueZ::SendValueChanged(
    BluetoothLocalGattCharacteristicBlueZ* characteristic,
    const std::vector<uint8_t>& value) {}

#if BUILDFLAG(IS_CHROMEOS)
void BluetoothAdapterBlueZ::SetServiceAllowList(const UUIDList& uuids,
                                                base::OnceClosure callback,
                                                ErrorCallback error_callback) {
  bluez::BluezDBusManager::Get()
      ->GetBluetoothAdminPolicyClient()
      ->SetServiceAllowList(object_path_, uuids, std::move(callback),
                            base::BindOnce(&SetServiceAllowListErrorCallback,
                                           std::move(error_callback)));
}

std::unique_ptr<device::BluetoothLowEnergyScanSession>
BluetoothAdapterBlueZ::StartLowEnergyScanSession(
    std::unique_ptr<device::BluetoothLowEnergyScanFilter> filter,
    base::WeakPtr<device::BluetoothLowEnergyScanSession::Delegate> delegate) {
  DCHECK(filter);

  dbus::ObjectPath monitor_path = dbus::ObjectPath(
      static_cast<std::string>(kAdvertisementMonitorApplicationObjectPath) +
      "/" + base::UnguessableToken::Create().ToString());
  BLUETOOTH_LOG(EVENT) << __func__ << ": session_id = " << monitor_path.value();

  // Client will take ownership of |low_energy_scan_session|.
  // OnLowEnergyScanSessionDestroyed removes the session from the D-Bus
  // application. |low_energy_scan_session| forwards callbacks from D-Bus to the
  // client-owned |delegate|.
  auto low_energy_scan_session =
      std::make_unique<BluetoothLowEnergyScanSessionBlueZ>(
          monitor_path.value(), weak_ptr_factory_.GetWeakPtr(), delegate,
          base::BindOnce(
              &BluetoothAdapterBlueZ::OnLowEnergyScanSessionDestroyed,
              weak_ptr_factory_.GetWeakPtr()));

  // Implements the advertisement monitor interface and forwards dbus callbacks
  // to the |low_energy_scan_session|.
  auto advertisement_monitor =
      BluetoothAdvertisementMonitorServiceProvider::Create(
          bluez::BluezDBusManager::Get()->GetSystemBus(), monitor_path,
          std::move(filter), low_energy_scan_session->GetWeakPtr());

  if (advertisement_monitor_application_provider_ &&
      is_advertisement_monitor_application_provider_registered_) {
    // Signals D-Bus that a new advertisement monitor is added.
    advertisement_monitor_application_provider_->AddMonitor(
        std::move(advertisement_monitor));
  } else {
    BLUETOOTH_LOG(EVENT) << __func__
                         << ": Advertisement monitor application not yet "
                            "registered. Queuing low energy scan session.";

    pending_advertisement_monitors_.push(std::move(advertisement_monitor));
  }

  return low_energy_scan_session;
}

BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus
BluetoothAdapterBlueZ::GetLowEnergyScanSessionHardwareOffloadingStatus() {
  if (!IsPresent())
    return LowEnergyScanSessionHardwareOffloadingStatus::kUndetermined;

  BluetoothAdvertisementMonitorManagerClient::Properties* properties =
      bluez::BluezDBusManager::Get()
          ->GetBluetoothAdvertisementMonitorManagerClient()
          ->GetProperties(object_path_);

  if (!properties) {
    return LowEnergyScanSessionHardwareOffloadingStatus::kUndetermined;
  }

  return base::Contains(properties->supported_features.value(),
                        bluetooth_advertisement_monitor_manager::
                            kSupportedFeaturesControllerPatterns)
             ? LowEnergyScanSessionHardwareOffloadingStatus::kSupported
             : LowEnergyScanSessionHardwareOffloadingStatus::kNotSupported;
}

std::vector<BluetoothAdapter::BluetoothRole>
BluetoothAdapterBlueZ::GetSupportedRoles() {
  std::vector<BluetoothAdapter::BluetoothRole> roles;

  if (!IsPresent()) {
    return roles;
  }

  bluez::BluetoothAdapterClient::Properties* properties =
      bluez::BluezDBusManager::Get()
          ->GetBluetoothAdapterClient()
          ->GetProperties(object_path_);
  DCHECK(properties);

  for (auto role : properties->roles.value()) {
    if (role == "central") {
      roles.push_back(BluetoothAdapter::BluetoothRole::kCentral);
    } else if (role == "peripheral") {
      roles.push_back(BluetoothAdapter::BluetoothRole::kPeripheral);
    } else if (role == "central-peripheral") {
      roles.push_back(BluetoothAdapter::BluetoothRole::kCentralPeripheral);
    } else {
      BLUETOOTH_LOG(EVENT) << __func__ << ": Unknown role: " << role;
    }
  }

  return roles;
}
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_CHROMEOS_ASH)
void BluetoothAdapterBlueZ::SetStandardChromeOSAdapterName() {
  if (!IsPresent()) {
    return;
  }

  std::string alias = ash::GetDeviceBluetoothName(GetAddress());
  SetName(alias, base::DoNothing(), base::DoNothing());
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

dbus::ObjectPath BluetoothAdapterBlueZ::GetApplicationObjectPath() const {}

void BluetoothAdapterBlueZ::OnRegisterProfile(
    const BluetoothUUID& uuid,
    std::unique_ptr<BluetoothAdapterProfileBlueZ> profile) {}

void BluetoothAdapterBlueZ::SetProfileDelegate(
    const BluetoothUUID& uuid,
    const dbus::ObjectPath& device_path,
    bluez::BluetoothProfileServiceProvider::Delegate* delegate,
    ProfileRegisteredCallback success_callback,
    ErrorCompletionCallback error_callback) {}

void BluetoothAdapterBlueZ::OnRegisterProfileError(
    const BluetoothUUID& uuid,
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::OnSetDiscoverable(base::OnceClosure callback,
                                              ErrorCallback error_callback,
                                              bool success) {}

void BluetoothAdapterBlueZ::OnPropertyChangeCompleted(
    base::OnceClosure callback,
    ErrorCallback error_callback,
    bool success) {}

base::WeakPtr<BluetoothAdapter> BluetoothAdapterBlueZ::GetWeakPtr() {}

// BluetoothAdapterBlueZ should override SetPowered() instead.
bool BluetoothAdapterBlueZ::SetPoweredImpl(bool powered) {}

void BluetoothAdapterBlueZ::UpdateFilter(
    std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
    DiscoverySessionResultCallback callback) {}

void BluetoothAdapterBlueZ::StartScanWithFilter(
    std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
    DiscoverySessionResultCallback callback) {}

void BluetoothAdapterBlueZ::StopScan(DiscoverySessionResultCallback callback) {}

void BluetoothAdapterBlueZ::SetDiscoveryFilter(
    std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
    base::OnceClosure callback,
    DiscoverySessionErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::OnStartDiscovery(
    DiscoverySessionResultCallback callback) {}

void BluetoothAdapterBlueZ::OnStartDiscoveryError(
    DiscoverySessionResultCallback callback,
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::OnStopDiscovery(base::OnceClosure callback) {}

void BluetoothAdapterBlueZ::OnStopDiscoveryError(
    DiscoverySessionErrorCallback error_callback,
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::OnPreSetDiscoveryFilter(
    DiscoverySessionResultCallback callback) {}

void BluetoothAdapterBlueZ::OnPreSetDiscoveryFilterError(
    DiscoverySessionErrorCallback error_callback,
    UMABluetoothDiscoverySessionOutcome outcome) {}

void BluetoothAdapterBlueZ::OnSetDiscoveryFilter(
    base::OnceClosure callback,
    DiscoverySessionErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::OnSetDiscoveryFilterError(
    DiscoverySessionErrorCallback error_callback,
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::UpdateRegisteredApplication(
    bool ignore_unregister_failure,
    base::OnceClosure callback,
    device::BluetoothGattService::ErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::RegisterApplication(
    base::OnceClosure callback,
    device::BluetoothGattService::ErrorCallback error_callback) {}

void BluetoothAdapterBlueZ::RegisterApplicationOnError(
    base::OnceClosure callback,
    device::BluetoothGattService::ErrorCallback error_callback,
    const std::string& /* error_name */,
    const std::string& /* error_message */) {}

void BluetoothAdapterBlueZ::ServiceRecordErrorConnector(
    ServiceRecordErrorCallback error_callback,
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::OnConnectDevice(
    ConnectDeviceCallback callback,
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::OnConnectDeviceError(
    ConnectDeviceErrorCallback error_callback,
    const std::string& error_name,
    const std::string& error_message) {}

void BluetoothAdapterBlueZ::UpdateDeviceAdminPolicyFromAdminPolicyClient(
    const dbus::ObjectPath& object_path) {}

void BluetoothAdapterBlueZ::UpdateDeviceBatteryLevelFromBatteryClient(
    const dbus::ObjectPath& object_path) {}

#if BUILDFLAG(IS_CHROMEOS)
void BluetoothAdapterBlueZ::
    RegisterAdvertisementMonitorApplicationServiceProvider() {
  if (is_advertisement_monitor_application_provider_registered_ ||
      !IsPresent()) {
    return;
  }
  BLUETOOTH_LOG(EVENT) << __func__;

  auto err_callback = [](std::string error_name,
                         const std::string error_message) {
    LOG(ERROR) << "Error while registering advertisement monitor application "
                  "service provider. error_name = "
               << error_name << ", error_message = " << error_message;
  };

  // Registers root application path of advertisement monitors/low energy
  // scanners.
  bluez::BluezDBusManager::Get()
      ->GetBluetoothAdvertisementMonitorManagerClient()
      ->RegisterMonitor(
          dbus::ObjectPath(kAdvertisementMonitorApplicationObjectPath),
          object_path_,
          base::BindOnce(
              &BluetoothAdapterBlueZ::
                  OnRegisterAdvertisementMonitorApplicationServiceProvider,
              weak_ptr_factory_.GetWeakPtr()),
          base::BindOnce(err_callback));
}

void BluetoothAdapterBlueZ::
    OnRegisterAdvertisementMonitorApplicationServiceProvider() {
  is_advertisement_monitor_application_provider_registered_ = true;
  BLUETOOTH_LOG(EVENT) << __func__;

  while (!pending_advertisement_monitors_.empty()) {
    // Signals D-Bus that a new advertisement monitor is added.
    advertisement_monitor_application_provider_->AddMonitor(
        std::move(pending_advertisement_monitors_.front()));
    pending_advertisement_monitors_.pop();
  }
}

void BluetoothAdapterBlueZ::OnLowEnergyScanSessionDestroyed(
    const std::string& session_id) {
  BLUETOOTH_LOG(EVENT) << __func__ << ": session_id = " << session_id;
  if (!advertisement_monitor_application_provider_ ||
      !is_advertisement_monitor_application_provider_registered_) {
    return;
  }
  advertisement_monitor_application_provider_->RemoveMonitor(
      dbus::ObjectPath(session_id));
}
#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace bluez