#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
namespace floss {
namespace {
UMABluetoothDiscoverySessionOutcome;
UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA(
const Error& error) { … }
void InitWhenObjectManagerKnown(base::OnceClosure callback) { … }
bool DeviceNeedsToReadProperties(device::BluetoothDevice* device) { … }
}
class BleDelegateForDiscovery
: public device::BluetoothLowEnergyScanSession::Delegate { … };
constexpr uint16_t kMinIntervalMs = …;
constexpr uint16_t kMaxIntervalMs = …;
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) { … }
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) { … }
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, ",");
}
#endif
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
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
#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
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) { … }
}