chromium/device/bluetooth/floss/bluetooth_adapter_floss.cc

// Copyright 2021 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/floss/bluetooth_adapter_floss.h"

#include "base/containers/contains.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/notreached.h"
#include "base/observer_list.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
#include "components/device_event_log/device_event_log.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/chromeos_platform_features.h"
#include "device/bluetooth/floss/bluetooth_advertisement_floss.h"
#include "device/bluetooth/floss/bluetooth_device_floss.h"
#include "device/bluetooth/floss/bluetooth_local_gatt_service_floss.h"
#include "device/bluetooth/floss/bluetooth_low_energy_scan_session_floss.h"
#include "device/bluetooth/floss/bluetooth_socket_floss.h"
#include "device/bluetooth/floss/floss_dbus_manager.h"
#include "device/bluetooth/floss/floss_lescan_client.h"
#include "device/bluetooth/floss/floss_socket_manager.h"
#include "device/bluetooth/public/cpp/bluetooth_address.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "device/bluetooth/chromeos/bluetooth_connection_logger.h"
#include "device/bluetooth/chromeos/bluetooth_utils.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/devicetype.h"
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

namespace floss {

namespace {
UMABluetoothDiscoverySessionOutcome;

UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA(
    const Error& error) {}

// Helper function to gate init behind a check for Object Manager support.
void InitWhenObjectManagerKnown(base::OnceClosure callback) {}

bool DeviceNeedsToReadProperties(device::BluetoothDevice* device) {}

}  // namespace

// Empty delegate for BLE scanning used during discovery.
class BleDelegateForDiscovery
    : public device::BluetoothLowEnergyScanSession::Delegate {};

// According to the Bluetooth spec, these are the min and max values possible
// for advertising interval. Core 5.3 Spec, Vol 4, Part E, Section 7.8.5.
constexpr uint16_t kMinIntervalMs =;
constexpr uint16_t kMaxIntervalMs =;

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

BluetoothAdapterFloss::BluetoothAdapterFloss() {}

BluetoothAdapterFloss::~BluetoothAdapterFloss() {}

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

void BluetoothAdapterFloss::Shutdown() {}

void BluetoothAdapterFloss::AddAdapterObservers() {}

void BluetoothAdapterFloss::RemoveAdapterObservers() {}

void BluetoothAdapterFloss::RemoveAdapter() {}

void BluetoothAdapterFloss::PopulateInitialDevices() {}

void BluetoothAdapterFloss::Init() {}

void BluetoothAdapterFloss::NotifyDeviceFound(uint8_t scanner_id,
                                              const std::string& address) {}

BluetoothDeviceFloss* BluetoothAdapterFloss::CreateOrGetDeviceForUpdate(
    const std::string& address,
    const std::string& name) {}

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

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

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

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

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

bool BluetoothAdapterFloss::IsInitialized() const {}

bool BluetoothAdapterFloss::IsPresent() const {}

bool BluetoothAdapterFloss::IsPowered() const {}

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

bool BluetoothAdapterFloss::IsDiscoverable() const {}

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

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

bool BluetoothAdapterFloss::IsDiscovering() const {}

std::unique_ptr<BluetoothDeviceFloss>
BluetoothAdapterFloss::CreateBluetoothDeviceFloss(FlossDeviceId device) {}

void BluetoothAdapterFloss::OnMethodResponse(base::OnceClosure callback,
                                             ErrorCallback error_callback,
                                             DBusResult<Void> ret) {}

void BluetoothAdapterFloss::OnRepeatedDiscoverySessionResult(
    bool start_discovery,
    bool is_error,
    UMABluetoothDiscoverySessionOutcome outcome) {}

void BluetoothAdapterFloss::OnStartDiscovery(
    DiscoverySessionResultCallback callback,
    DBusResult<Void> ret) {}

void BluetoothAdapterFloss::OnStopDiscovery(
    DiscoverySessionResultCallback callback,
    DBusResult<Void> ret) {}

void BluetoothAdapterFloss::OnInitializeDeviceProperties(
    BluetoothDeviceFloss* device_ptr) {}

void BluetoothAdapterFloss::OnDeviceUuidsChanged(
    BluetoothDeviceFloss* device_ptr) {}

void BluetoothAdapterFloss::OnGetConnectionState(const FlossDeviceId& device_id,
                                                 DBusResult<uint32_t> ret) {}

void BluetoothAdapterFloss::OnGetBondState(const FlossDeviceId& device_id,
                                           DBusResult<uint32_t> ret) {}

void BluetoothAdapterFloss::OnGetBatteryInformation(
    DBusResult<std::optional<BatterySet>> battery_set) {}

// Announce to observers a change in the adapter state.
void BluetoothAdapterFloss::DiscoverableChanged(bool discoverable) {}

void BluetoothAdapterFloss::DiscoveringChanged(bool discovering) {}

void BluetoothAdapterFloss::PresentChanged(bool present) {}

void BluetoothAdapterFloss::NotifyAdapterPoweredChanged(bool powered) {}

void BluetoothAdapterFloss::NotifyDeviceConnectedStateChanged(
    BluetoothDeviceFloss* device,
    bool is_now_connected) {}

// Observers

void BluetoothAdapterFloss::AdapterPresent(int adapter, bool present) {}

void BluetoothAdapterFloss::AdapterEnabledChanged(int adapter, bool enabled) {}

void BluetoothAdapterFloss::OnAdapterClientsReady(bool enabled,
                                                  bool is_newly_present) {}

void BluetoothAdapterFloss::AdapterDiscoveringChanged(bool state) {}

void BluetoothAdapterFloss::AdapterFoundDevice(
    const FlossDeviceId& device_found) {}

void BluetoothAdapterFloss::UpdateDeviceProperties(
    bool is_triggered_by_inquiry,
    const FlossDeviceId& device_found) {}

void BluetoothAdapterFloss::AdapterClearedDevice(
    const FlossDeviceId& device_cleared) {}

void BluetoothAdapterFloss::AdapterDevicePropertyChanged(
    FlossAdapterClient::BtPropertyType prop_type,
    const FlossDeviceId& device) {}

void BluetoothAdapterFloss::AdapterSspRequest(
    const FlossDeviceId& remote_device,
    uint32_t cod,
    FlossAdapterClient::BluetoothSspVariant variant,
    uint32_t passkey) {}

void BluetoothAdapterFloss::AdapterPinDisplay(
    const FlossDeviceId& remote_device,
    std::string pincode) {}

void BluetoothAdapterFloss::AdapterPinRequest(
    const FlossDeviceId& remote_device,
    uint32_t cod,
    bool min_16_digit) {}

void BluetoothAdapterFloss::DeviceBondStateChanged(
    const FlossDeviceId& remote_device,
    uint32_t status,
    FlossAdapterClient::BondState bond_state) {}

void BluetoothAdapterFloss::AdapterDeviceConnected(
    const FlossDeviceId& device_id) {}

std::optional<device::BluetoothDevice::BatteryType> variant_to_battery_type(
    const std::string& variant) {}

void BluetoothAdapterFloss::BatteryInfoUpdated(std::string remote_address,
                                               BatterySet battery_set) {}

void BluetoothAdapterFloss::AdapterDeviceDisconnected(
    const FlossDeviceId& device_id) {}

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

#if BUILDFLAG(IS_CHROMEOS)
void BluetoothAdapterFloss::DevicePolicyEffectChanged(
    const FlossDeviceId& device_id,
    const std::optional<PolicyEffect>& effect) {
  BLUETOOTH_LOG(EVENT) << __func__ << ": " << device_id;

  BluetoothDeviceFloss* device =
      static_cast<BluetoothDeviceFloss*>(GetDevice(device_id.address));
  if (!device) {
    LOG(WARNING) << "Device disconnected for an unknown device "
                 << device_id.address;
    return;
  }

  device->SetIsBlockedByPolicy(effect.has_value() ? effect.value().affected
                                                  : false);
}

void BluetoothAdapterFloss::ServiceAllowlistChanged(
    const std::vector<device::BluetoothUUID>& allowlist) {
  std::vector<std::string> uuid_str(allowlist.size());

  base::ranges::transform(
      allowlist, uuid_str.begin(),
      [](device::BluetoothUUID dev) { return dev.canonical_value(); });

  BLUETOOTH_LOG(EVENT) << __func__ << ": " << base::JoinString(uuid_str, ",");
  // TODO(b/257877673): Notify observers
}
#endif  // BUILDFLAG(IS_CHROMEOS)

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

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

void BluetoothAdapterFloss::OnCreateServiceError(
    scoped_refptr<BluetoothSocketFloss> socket,
    CreateServiceErrorCallback error_callback,
    const std::string& error_message) {}

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

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

  return FlossDBusManager::Get()->GetAdapterClient()->IsExtAdvSupported();
}
#endif  // BUILDFLAG(IS_CHROMEOS)

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

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

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

void BluetoothAdapterFloss::AddLocalGattService(
    std::unique_ptr<BluetoothLocalGattServiceFloss> service) {}

void BluetoothAdapterFloss::RemoveLocalGattService(
    BluetoothLocalGattServiceFloss* service) {}

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

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

void BluetoothAdapterFloss::RegisterGattService(
    BluetoothLocalGattServiceFloss* service) {}

void BluetoothAdapterFloss::OnGattServiceAdded(
    BluetoothLocalGattServiceFloss* service,
    DBusResult<Void> ret) {}

void BluetoothAdapterFloss::UnregisterGattService(
    BluetoothLocalGattServiceFloss* service) {}

void BluetoothAdapterFloss::OnGattServiceRemoved(
    BluetoothLocalGattServiceFloss* service,
    DBusResult<Void> ret) {}

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

#if BUILDFLAG(IS_CHROMEOS)
void BluetoothAdapterFloss::SetServiceAllowList(const UUIDList& uuids,
                                                base::OnceClosure callback,
                                                ErrorCallback error_callback) {
  FlossDBusManager::Get()->GetAdminClient()->SetAllowedServices(
      base::BindOnce(&BluetoothAdapterFloss::OnMethodResponse,
                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
                     std::move(error_callback)),
      uuids);
}

std::unique_ptr<device::BluetoothLowEnergyScanSession>
BluetoothAdapterFloss::StartLowEnergyScanSession(
    std::unique_ptr<device::BluetoothLowEnergyScanFilter> filter,
    base::WeakPtr<device::BluetoothLowEnergyScanSession::Delegate> delegate) {
  auto scan_session = std::make_unique<BluetoothLowEnergyScanSessionFloss>(
      std::move(filter), delegate,
      base::BindOnce(&BluetoothAdapterFloss::OnLowEnergyScanSessionDestroyed,
                     weak_ptr_factory_.GetWeakPtr()));
  FlossDBusManager::Get()->GetLEScanClient()->RegisterScanner(base::BindOnce(
      &BluetoothAdapterFloss::OnRegisterScanner, weak_ptr_factory_.GetWeakPtr(),
      scan_session->GetWeakPtr()));
  return scan_session;
}

device::BluetoothAdapter::LowEnergyScanSessionHardwareOffloadingStatus
BluetoothAdapterFloss::GetLowEnergyScanSessionHardwareOffloadingStatus() {
  if (!IsPowered()) {
    BLUETOOTH_LOG(ERROR)
        << "GetLowEnergyScanSessionHardwareOffloadingStatus called when "
        << "adapter is not powered.";
    return device::BluetoothAdapter::
        LowEnergyScanSessionHardwareOffloadingStatus::kUndetermined;
  }
  return FlossDBusManager::Get()->GetGattManagerClient()->GetMsftSupported()
             ? device::BluetoothAdapter::
                   LowEnergyScanSessionHardwareOffloadingStatus::kSupported
             : device::BluetoothAdapter::
                   LowEnergyScanSessionHardwareOffloadingStatus::kNotSupported;
}

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

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

  for (auto role :
       FlossDBusManager::Get()->GetAdapterClient()->GetSupportedRoles()) {
    switch (role) {
      case FlossAdapterClient::BtAdapterRole::kCentral:
        roles.push_back(BluetoothAdapter::BluetoothRole::kCentral);
        break;
      case FlossAdapterClient::BtAdapterRole::kPeripheral:
        roles.push_back(BluetoothAdapter::BluetoothRole::kPeripheral);
        break;
      case FlossAdapterClient::BtAdapterRole::kCentralPeripheral:
        roles.push_back(BluetoothAdapter::BluetoothRole::kCentralPeripheral);
        break;
      default:
        BLUETOOTH_LOG(EVENT)
            << __func__ << ": Unknown role: " << static_cast<uint32_t>(role);
    }
  }

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

#if BUILDFLAG(IS_CHROMEOS_ASH)
void BluetoothAdapterFloss::SetStandardChromeOSAdapterName() {
  if (!IsPresent()) {
    BLUETOOTH_LOG(ERROR)
        << "SetStandardChromeOSAdapterName called when adapter is not present.";
    return;
  }

  std::string alias = ash::GetDeviceBluetoothName(GetAddress());
  FlossDBusManager::Get()->GetAdapterClient()->SetName(base::DoNothing(),
                                                       alias);
}

void BluetoothAdapterFloss::ConfigureBluetoothTelephony(bool enabled) {
  FlossDBusManager::Get()->GetBluetoothTelephonyClient()->SetPhoneOpsEnabled(
      base::DoNothing(), enabled);
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

void BluetoothAdapterFloss::ScannerRegistered(device::BluetoothUUID uuid,
                                              uint8_t scanner_id,
                                              GattStatus status) {}

void BluetoothAdapterFloss::ScanResultReceived(ScanResult scan_result) {}

void BluetoothAdapterFloss::AdvertisementFound(uint8_t scanner_id,
                                               ScanResult scan_result) {}

void BluetoothAdapterFloss::AdvertisementLost(uint8_t scanner_id,
                                              ScanResult scan_result) {}

void BluetoothAdapterFloss::RemovePairingDelegateInternal(
    device::BluetoothDevice::PairingDelegate* pairing_delegate) {}

base::WeakPtr<device::BluetoothAdapter> BluetoothAdapterFloss::GetWeakPtr() {}

bool BluetoothAdapterFloss::SetPoweredImpl(bool powered) {}

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

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

void BluetoothAdapterFloss::StopScan(DiscoverySessionResultCallback callback) {}

void BluetoothAdapterFloss::OnRegisterScanner(
    base::WeakPtr<BluetoothLowEnergyScanSessionFloss> scan_session,
    DBusResult<device::BluetoothUUID> ret) {}

void BluetoothAdapterFloss::OnStartScan(
    device::BluetoothUUID uuid,
    uint8_t scanner_id,
    DBusResult<FlossDBusClient::BtifStatus> ret) {}

void BluetoothAdapterFloss::OnLowEnergyScanSessionDestroyed(
    const std::string& uuid_str) {}

void BluetoothAdapterFloss::OnUnregisterScanner(uint8_t scanner_id,
                                                DBusResult<bool> ret) {}

}  // namespace floss