Index: device/bluetooth/bluetooth_adapter_chromeos.cc |
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc |
deleted file mode 100644 |
index 55d0bef28794b7b1374f2371fa6b97eabc263451..0000000000000000000000000000000000000000 |
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc |
+++ /dev/null |
@@ -1,1531 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "device/bluetooth/bluetooth_adapter_chromeos.h" |
- |
-#include <string> |
- |
-#include "base/bind.h" |
-#include "base/location.h" |
-#include "base/logging.h" |
-#include "base/metrics/histogram.h" |
-#include "base/sequenced_task_runner.h" |
-#include "base/single_thread_task_runner.h" |
-#include "base/thread_task_runner_handle.h" |
-#include "chromeos/system/devicetype.h" |
-#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h" |
-#include "device/bluetooth/bluetooth_advertisement_chromeos.h" |
-#include "device/bluetooth/bluetooth_audio_sink_chromeos.h" |
-#include "device/bluetooth/bluetooth_device.h" |
-#include "device/bluetooth/bluetooth_device_chromeos.h" |
-#include "device/bluetooth/bluetooth_discovery_session_outcome.h" |
-#include "device/bluetooth/bluetooth_pairing_chromeos.h" |
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" |
-#include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h" |
-#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" |
-#include "device/bluetooth/bluetooth_socket_chromeos.h" |
-#include "device/bluetooth/bluetooth_socket_thread.h" |
-#include "device/bluetooth/bluetooth_uuid.h" |
-#include "device/bluetooth/dbus/bluetooth_adapter_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_device_client.h" |
-#include "device/bluetooth/dbus/bluetooth_input_client.h" |
-#include "device/bluetooth/dbus/bluez_dbus_manager.h" |
-#include "third_party/cros_system_api/dbus/service_constants.h" |
- |
-using device::BluetoothAdapter; |
-using device::BluetoothAudioSink; |
-using device::BluetoothDevice; |
-using device::BluetoothDiscoveryFilter; |
-using device::BluetoothSocket; |
-using device::BluetoothUUID; |
-using device::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[] = "/org/chromium/bluetooth_agent"; |
- |
-void OnUnregisterAgentError(const std::string& error_name, |
- const std::string& error_message) { |
- // It's okay if the agent didn't exist, it means we never saw an adapter. |
- if (error_name == bluetooth_agent_manager::kErrorDoesNotExist) |
- return; |
- |
- LOG(WARNING) << "Failed to unregister pairing agent: " |
- << error_name << ": " << error_message; |
-} |
- |
-UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA( |
- const std::string& error_name) { |
- if (error_name == bluez::BluetoothAdapterClient::kUnknownAdapterError) { |
- return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_UNKNOWN_ADAPTER; |
- } else if (error_name == bluez::BluetoothAdapterClient::kNoResponseError) { |
- return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_NO_RESPONSE; |
- } else if (error_name == bluetooth_device::kErrorInProgress) { |
- return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_IN_PROGRESS; |
- } else if (error_name == bluetooth_device::kErrorNotReady) { |
- return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_NOT_READY; |
- } else if (error_name == bluetooth_device::kErrorFailed) { |
- return UMABluetoothDiscoverySessionOutcome::FAILED; |
- } else { |
- LOG(WARNING) << "Can't histogram DBus error " << error_name; |
- return UMABluetoothDiscoverySessionOutcome::UNKNOWN; |
- } |
-} |
- |
-} // namespace |
- |
-namespace device { |
- |
-// static |
-base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( |
- const InitCallback& init_callback) { |
- return chromeos::BluetoothAdapterChromeOS::CreateAdapter(); |
-} |
- |
-} // namespace device |
- |
-namespace chromeos { |
- |
-// static |
-base::WeakPtr<BluetoothAdapter> BluetoothAdapterChromeOS::CreateAdapter() { |
- BluetoothAdapterChromeOS* adapter = new BluetoothAdapterChromeOS(); |
- return adapter->weak_ptr_factory_.GetWeakPtr(); |
-} |
- |
-void BluetoothAdapterChromeOS::Shutdown() { |
- if (dbus_is_shutdown_) |
- return; |
- DCHECK(bluez::BluezDBusManager::IsInitialized()) |
- << "Call BluetoothAdapterFactory::Shutdown() before " |
- "BluezDBusManager::Shutdown()."; |
- |
- if (IsPresent()) |
- RemoveAdapter(); // Also deletes devices_. |
- DCHECK(devices_.empty()); |
- // profiles_ is empty because all BluetoothSockets have been notified |
- // that this adapter is disappearing. |
- DCHECK(profiles_.empty()); |
- |
- for (auto& it : profile_queues_) |
- delete it.second; |
- profile_queues_.clear(); |
- |
- bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->RemoveObserver( |
- this); |
- bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver( |
- this); |
- bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->RemoveObserver( |
- this); |
- |
- VLOG(1) << "Unregistering pairing agent"; |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAgentManagerClient() |
- ->UnregisterAgent(dbus::ObjectPath(kAgentPath), |
- base::Bind(&base::DoNothing), |
- base::Bind(&OnUnregisterAgentError)); |
- |
- agent_.reset(); |
- dbus_is_shutdown_ = true; |
-} |
- |
-BluetoothAdapterChromeOS::BluetoothAdapterChromeOS() |
- : dbus_is_shutdown_(false), |
- num_discovery_sessions_(0), |
- discovery_request_pending_(false), |
- weak_ptr_factory_(this) { |
- ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
- socket_thread_ = device::BluetoothSocketThread::Get(); |
- |
- bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->AddObserver( |
- this); |
- bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); |
- bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->AddObserver(this); |
- |
- // Register the pairing agent. |
- dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus(); |
- agent_.reset(bluez::BluetoothAgentServiceProvider::Create( |
- system_bus, dbus::ObjectPath(kAgentPath), this)); |
- DCHECK(agent_.get()); |
- |
- std::vector<dbus::ObjectPath> object_paths = bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetAdapters(); |
- |
- if (!object_paths.empty()) { |
- VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available."; |
- SetAdapter(object_paths[0]); |
- } |
-} |
- |
-BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() { |
- Shutdown(); |
-} |
- |
-std::string BluetoothAdapterChromeOS::GetAddress() const { |
- if (!IsPresent()) |
- return std::string(); |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- DCHECK(properties); |
- |
- return BluetoothDevice::CanonicalizeAddress(properties->address.value()); |
-} |
- |
-std::string BluetoothAdapterChromeOS::GetName() const { |
- if (!IsPresent()) |
- return std::string(); |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- DCHECK(properties); |
- |
- return properties->alias.value(); |
-} |
- |
-void BluetoothAdapterChromeOS::SetName(const std::string& name, |
- const base::Closure& callback, |
- const ErrorCallback& error_callback) { |
- if (!IsPresent()) { |
- error_callback.Run(); |
- return; |
- } |
- |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_) |
- ->alias.Set( |
- name, |
- base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
-} |
- |
-bool BluetoothAdapterChromeOS::IsInitialized() const { |
- return true; |
-} |
- |
-bool BluetoothAdapterChromeOS::IsPresent() const { |
- return !dbus_is_shutdown_ && !object_path_.value().empty(); |
-} |
- |
-bool BluetoothAdapterChromeOS::IsPowered() const { |
- if (!IsPresent()) |
- return false; |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- |
- return properties->powered.value(); |
-} |
- |
-void BluetoothAdapterChromeOS::SetPowered( |
- bool powered, |
- const base::Closure& callback, |
- const ErrorCallback& error_callback) { |
- if (!IsPresent()) { |
- error_callback.Run(); |
- return; |
- } |
- |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_) |
- ->powered.Set( |
- powered, |
- base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
-} |
- |
-bool BluetoothAdapterChromeOS::IsDiscoverable() const { |
- if (!IsPresent()) |
- return false; |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- |
- return properties->discoverable.value(); |
-} |
- |
-void BluetoothAdapterChromeOS::SetDiscoverable( |
- bool discoverable, |
- const base::Closure& callback, |
- const ErrorCallback& error_callback) { |
- if (!IsPresent()) { |
- error_callback.Run(); |
- return; |
- } |
- |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_) |
- ->discoverable.Set( |
- discoverable, |
- base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoverable, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
-} |
- |
-bool BluetoothAdapterChromeOS::IsDiscovering() const { |
- if (!IsPresent()) |
- return false; |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- |
- return properties->discovering.value(); |
-} |
- |
-void BluetoothAdapterChromeOS::CreateRfcommService( |
- const BluetoothUUID& uuid, |
- const ServiceOptions& options, |
- const CreateServiceCallback& callback, |
- const CreateServiceErrorCallback& error_callback) { |
- DCHECK(!dbus_is_shutdown_); |
- VLOG(1) << object_path_.value() << ": Creating RFCOMM service: " |
- << uuid.canonical_value(); |
- scoped_refptr<BluetoothSocketChromeOS> socket = |
- BluetoothSocketChromeOS::CreateBluetoothSocket( |
- ui_task_runner_, socket_thread_); |
- socket->Listen(this, |
- BluetoothSocketChromeOS::kRfcomm, |
- uuid, |
- options, |
- base::Bind(callback, socket), |
- error_callback); |
-} |
- |
-void BluetoothAdapterChromeOS::CreateL2capService( |
- const BluetoothUUID& uuid, |
- const ServiceOptions& options, |
- const CreateServiceCallback& callback, |
- const CreateServiceErrorCallback& error_callback) { |
- DCHECK(!dbus_is_shutdown_); |
- VLOG(1) << object_path_.value() << ": Creating L2CAP service: " |
- << uuid.canonical_value(); |
- scoped_refptr<BluetoothSocketChromeOS> socket = |
- BluetoothSocketChromeOS::CreateBluetoothSocket( |
- ui_task_runner_, socket_thread_); |
- socket->Listen(this, |
- BluetoothSocketChromeOS::kL2cap, |
- uuid, |
- options, |
- base::Bind(callback, socket), |
- error_callback); |
-} |
- |
-void BluetoothAdapterChromeOS::RegisterAudioSink( |
- const BluetoothAudioSink::Options& options, |
- const device::BluetoothAdapter::AcquiredCallback& callback, |
- const BluetoothAudioSink::ErrorCallback& error_callback) { |
- VLOG(1) << "Registering audio sink"; |
- if (!this->IsPresent()) { |
- error_callback.Run(BluetoothAudioSink::ERROR_INVALID_ADAPTER); |
- return; |
- } |
- scoped_refptr<BluetoothAudioSinkChromeOS> audio_sink( |
- new BluetoothAudioSinkChromeOS(this)); |
- audio_sink->Register( |
- options, base::Bind(&BluetoothAdapterChromeOS::OnRegisterAudioSink, |
- weak_ptr_factory_.GetWeakPtr(), callback, |
- error_callback, audio_sink), |
- error_callback); |
-} |
- |
-void BluetoothAdapterChromeOS::RegisterAdvertisement( |
- scoped_ptr<device::BluetoothAdvertisement::Data> advertisement_data, |
- const CreateAdvertisementCallback& callback, |
- const CreateAdvertisementErrorCallback& error_callback) { |
- scoped_refptr<BluetoothAdvertisementChromeOS> advertisement( |
- new BluetoothAdvertisementChromeOS(advertisement_data.Pass(), this)); |
- advertisement->Register(base::Bind(callback, advertisement), error_callback); |
-} |
- |
-void BluetoothAdapterChromeOS::RemovePairingDelegateInternal( |
- BluetoothDevice::PairingDelegate* pairing_delegate) { |
- // Check if any device is using the pairing delegate. |
- // If so, clear the pairing context which will make any responses no-ops. |
- for (DevicesMap::const_iterator iter = devices_.begin(); |
- iter != devices_.end(); ++iter) { |
- BluetoothDeviceChromeOS* device_chromeos = |
- static_cast<BluetoothDeviceChromeOS*>(iter->second); |
- |
- BluetoothPairingChromeOS* pairing = device_chromeos->GetPairing(); |
- if (pairing && pairing->GetPairingDelegate() == pairing_delegate) |
- device_chromeos->EndPairing(); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::AdapterAdded( |
- const dbus::ObjectPath& object_path) { |
- // Set the adapter to the newly added adapter only if no adapter is present. |
- if (!IsPresent()) |
- SetAdapter(object_path); |
-} |
- |
-void BluetoothAdapterChromeOS::AdapterRemoved( |
- const dbus::ObjectPath& object_path) { |
- if (object_path == object_path_) |
- RemoveAdapter(); |
-} |
- |
-void BluetoothAdapterChromeOS::AdapterPropertyChanged( |
- const dbus::ObjectPath& object_path, |
- const std::string& property_name) { |
- if (object_path != object_path_) |
- return; |
- DCHECK(IsPresent()); |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- |
- if (property_name == properties->powered.name()) { |
- PoweredChanged(properties->powered.value()); |
- } else if (property_name == properties->discoverable.name()) { |
- DiscoverableChanged(properties->discoverable.value()); |
- } else if (property_name == properties->discovering.name()) { |
- DiscoveringChanged(properties->discovering.value()); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::DeviceAdded( |
- const dbus::ObjectPath& object_path) { |
- DCHECK(bluez::BluezDBusManager::Get()); |
- bluez::BluetoothDeviceClient::Properties* properties = |
- bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( |
- object_path); |
- if (!properties || properties->adapter.value() != object_path_) |
- return; |
- DCHECK(IsPresent()); |
- |
- BluetoothDeviceChromeOS* device_chromeos = |
- new BluetoothDeviceChromeOS(this, |
- object_path, |
- ui_task_runner_, |
- socket_thread_); |
- DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end()); |
- |
- devices_.set(device_chromeos->GetAddress(), |
- scoped_ptr<BluetoothDevice>(device_chromeos)); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- DeviceAdded(this, device_chromeos)); |
-} |
- |
-void BluetoothAdapterChromeOS::DeviceRemoved( |
- const dbus::ObjectPath& object_path) { |
- for (DevicesMap::const_iterator iter = devices_.begin(); |
- iter != devices_.end(); ++iter) { |
- BluetoothDeviceChromeOS* device_chromeos = |
- static_cast<BluetoothDeviceChromeOS*>(iter->second); |
- if (device_chromeos->object_path() == object_path) { |
- scoped_ptr<BluetoothDevice> scoped_device = |
- devices_.take_and_erase(iter->first); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- DeviceRemoved(this, device_chromeos)); |
- return; |
- } |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::DevicePropertyChanged( |
- const dbus::ObjectPath& object_path, |
- const std::string& property_name) { |
- BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path); |
- if (!device_chromeos) |
- return; |
- |
- bluez::BluetoothDeviceClient::Properties* properties = |
- bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( |
- object_path); |
- |
- if (property_name == properties->address.name()) { |
- for (DevicesMap::iterator iter = devices_.begin(); iter != devices_.end(); |
- ++iter) { |
- if (iter->second->GetAddress() == device_chromeos->GetAddress()) { |
- std::string old_address = iter->first; |
- VLOG(1) << "Device changed address, old: " << old_address |
- << " new: " << device_chromeos->GetAddress(); |
- scoped_ptr<BluetoothDevice> scoped_device = |
- devices_.take_and_erase(iter); |
- ignore_result(scoped_device.release()); |
- |
- DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end()); |
- devices_.set(device_chromeos->GetAddress(), |
- scoped_ptr<BluetoothDevice>(device_chromeos)); |
- NotifyDeviceAddressChanged(device_chromeos, old_address); |
- break; |
- } |
- } |
- } |
- |
- if (property_name == properties->bluetooth_class.name() || |
- property_name == properties->address.name() || |
- property_name == properties->alias.name() || |
- property_name == properties->paired.name() || |
- property_name == properties->trusted.name() || |
- property_name == properties->connected.name() || |
- property_name == properties->uuids.name() || |
- property_name == properties->rssi.name() || |
- property_name == properties->tx_power.name()) { |
- NotifyDeviceChanged(device_chromeos); |
- } |
- |
- if (property_name == properties->gatt_services.name()) { |
- NotifyGattServicesDiscovered(device_chromeos); |
- } |
- |
- // When a device becomes paired, mark it as trusted so that the user does |
- // not need to approve every incoming connection |
- if (property_name == properties->paired.name() && |
- properties->paired.value() && !properties->trusted.value()) { |
- device_chromeos->SetTrusted(); |
- } |
- |
- // UMA connection counting |
- if (property_name == properties->connected.name()) { |
- // PlayStation joystick tries to reconnect after disconnection from USB. |
- // If it is still not trusted, set it, so it becomes available on the |
- // list of known devices. |
- if (properties->connected.value() && device_chromeos->IsTrustable() && |
- !properties->trusted.value()) |
- device_chromeos->SetTrusted(); |
- |
- int count = 0; |
- |
- for (DevicesMap::const_iterator iter = devices_.begin(); |
- iter != devices_.end(); ++iter) { |
- if (iter->second->IsPaired() && iter->second->IsConnected()) |
- ++count; |
- } |
- |
- UMA_HISTOGRAM_COUNTS_100("Bluetooth.ConnectedDeviceCount", count); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::InputPropertyChanged( |
- const dbus::ObjectPath& object_path, |
- const std::string& property_name) { |
- BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path); |
- if (!device_chromeos) |
- return; |
- |
- bluez::BluetoothInputClient::Properties* properties = |
- bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->GetProperties( |
- object_path); |
- |
- // Properties structure can be removed, which triggers a change in the |
- // BluetoothDevice::IsConnectable() property, as does a change in the |
- // actual reconnect_mode property. |
- if (!properties || property_name == properties->reconnect_mode.name()) { |
- NotifyDeviceChanged(device_chromeos); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::Released() { |
- VLOG(1) << "Release"; |
- if (!IsPresent()) |
- return; |
- DCHECK(agent_.get()); |
- |
- // Called after we unregister the pairing agent, e.g. when changing I/O |
- // capabilities. Nothing much to be done right now. |
-} |
- |
-void BluetoothAdapterChromeOS::RequestPinCode( |
- const dbus::ObjectPath& device_path, |
- const PinCodeCallback& callback) { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << device_path.value() << ": RequestPinCode"; |
- |
- BluetoothPairingChromeOS* pairing = GetPairing(device_path); |
- if (!pairing) { |
- callback.Run(REJECTED, ""); |
- return; |
- } |
- |
- pairing->RequestPinCode(callback); |
-} |
- |
-void BluetoothAdapterChromeOS::DisplayPinCode( |
- const dbus::ObjectPath& device_path, |
- const std::string& pincode) { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << device_path.value() << ": DisplayPinCode: " << pincode; |
- |
- BluetoothPairingChromeOS* pairing = GetPairing(device_path); |
- if (!pairing) |
- return; |
- |
- pairing->DisplayPinCode(pincode); |
-} |
- |
-void BluetoothAdapterChromeOS::RequestPasskey( |
- const dbus::ObjectPath& device_path, |
- const PasskeyCallback& callback) { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << device_path.value() << ": RequestPasskey"; |
- |
- BluetoothPairingChromeOS* pairing = GetPairing(device_path); |
- if (!pairing) { |
- callback.Run(REJECTED, 0); |
- return; |
- } |
- |
- pairing->RequestPasskey(callback); |
-} |
- |
-void BluetoothAdapterChromeOS::DisplayPasskey( |
- const dbus::ObjectPath& device_path, |
- uint32 passkey, |
- uint16 entered) { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << device_path.value() << ": DisplayPasskey: " << passkey |
- << " (" << entered << " entered)"; |
- |
- BluetoothPairingChromeOS* pairing = GetPairing(device_path); |
- if (!pairing) |
- return; |
- |
- if (entered == 0) |
- pairing->DisplayPasskey(passkey); |
- |
- pairing->KeysEntered(entered); |
-} |
- |
-void BluetoothAdapterChromeOS::RequestConfirmation( |
- const dbus::ObjectPath& device_path, |
- uint32 passkey, |
- const ConfirmationCallback& callback) { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << device_path.value() << ": RequestConfirmation: " << passkey; |
- |
- BluetoothPairingChromeOS* pairing = GetPairing(device_path); |
- if (!pairing) { |
- callback.Run(REJECTED); |
- return; |
- } |
- |
- pairing->RequestConfirmation(passkey, callback); |
-} |
- |
-void BluetoothAdapterChromeOS::RequestAuthorization( |
- const dbus::ObjectPath& device_path, |
- const ConfirmationCallback& callback) { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << device_path.value() << ": RequestAuthorization"; |
- |
- BluetoothPairingChromeOS* pairing = GetPairing(device_path); |
- if (!pairing) { |
- callback.Run(REJECTED); |
- return; |
- } |
- |
- pairing->RequestAuthorization(callback); |
-} |
- |
-void BluetoothAdapterChromeOS::AuthorizeService( |
- const dbus::ObjectPath& device_path, |
- const std::string& uuid, |
- const ConfirmationCallback& callback) { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << device_path.value() << ": AuthorizeService: " << uuid; |
- |
- BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(device_path); |
- if (!device_chromeos) { |
- callback.Run(CANCELLED); |
- return; |
- } |
- |
- // We always set paired devices to Trusted, so the only reason that this |
- // method call would ever be called is in the case of a race condition where |
- // our "Set('Trusted', true)" method call is still pending in the Bluetooth |
- // daemon because it's busy handling the incoming connection. |
- if (device_chromeos->IsPaired()) { |
- callback.Run(SUCCESS); |
- return; |
- } |
- |
- // TODO(keybuk): reject service authorizations when not paired, determine |
- // whether this is acceptable long-term. |
- LOG(WARNING) << "Rejecting service connection from unpaired device " |
- << device_chromeos->GetAddress() << " for UUID " << uuid; |
- callback.Run(REJECTED); |
-} |
- |
-void BluetoothAdapterChromeOS::Cancel() { |
- DCHECK(IsPresent()); |
- DCHECK(agent_.get()); |
- VLOG(1) << "Cancel"; |
-} |
- |
-void BluetoothAdapterChromeOS::OnRegisterAgent() { |
- VLOG(1) << "Pairing agent registered, requesting to be made default"; |
- |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAgentManagerClient() |
- ->RequestDefaultAgent( |
- dbus::ObjectPath(kAgentPath), |
- base::Bind(&BluetoothAdapterChromeOS::OnRequestDefaultAgent, |
- weak_ptr_factory_.GetWeakPtr()), |
- base::Bind(&BluetoothAdapterChromeOS::OnRequestDefaultAgentError, |
- weak_ptr_factory_.GetWeakPtr())); |
-} |
- |
-void BluetoothAdapterChromeOS::OnRegisterAgentError( |
- const std::string& error_name, |
- const std::string& error_message) { |
- // Our agent being already registered isn't an error. |
- if (error_name == bluetooth_agent_manager::kErrorAlreadyExists) |
- return; |
- |
- LOG(WARNING) << ": Failed to register pairing agent: " |
- << error_name << ": " << error_message; |
-} |
- |
-void BluetoothAdapterChromeOS::OnRequestDefaultAgent() { |
- VLOG(1) << "Pairing agent now default"; |
-} |
- |
-void BluetoothAdapterChromeOS::OnRequestDefaultAgentError( |
- const std::string& error_name, |
- const std::string& error_message) { |
- LOG(WARNING) << ": Failed to make pairing agent default: " |
- << error_name << ": " << error_message; |
-} |
- |
-void BluetoothAdapterChromeOS::OnRegisterAudioSink( |
- const device::BluetoothAdapter::AcquiredCallback& callback, |
- const device::BluetoothAudioSink::ErrorCallback& error_callback, |
- scoped_refptr<BluetoothAudioSink> audio_sink) { |
- if (!IsPresent()) { |
- VLOG(1) << "Failed to register audio sink, adapter not present"; |
- error_callback.Run(BluetoothAudioSink::ERROR_INVALID_ADAPTER); |
- return; |
- } |
- DCHECK(audio_sink.get()); |
- callback.Run(audio_sink); |
-} |
- |
-BluetoothDeviceChromeOS* |
-BluetoothAdapterChromeOS::GetDeviceWithPath( |
- const dbus::ObjectPath& object_path) { |
- if (!IsPresent()) |
- return nullptr; |
- |
- for (DevicesMap::const_iterator iter = devices_.begin(); |
- iter != devices_.end(); ++iter) { |
- BluetoothDeviceChromeOS* device_chromeos = |
- static_cast<BluetoothDeviceChromeOS*>(iter->second); |
- if (device_chromeos->object_path() == object_path) |
- return device_chromeos; |
- } |
- |
- return nullptr; |
-} |
- |
-BluetoothPairingChromeOS* BluetoothAdapterChromeOS::GetPairing( |
- const dbus::ObjectPath& object_path) { |
- DCHECK(IsPresent()); |
- BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path); |
- if (!device_chromeos) { |
- LOG(WARNING) << "Pairing Agent request for unknown device: " |
- << object_path.value(); |
- return nullptr; |
- } |
- |
- BluetoothPairingChromeOS* pairing = device_chromeos->GetPairing(); |
- if (pairing) |
- return pairing; |
- |
- // The device doesn't have its own pairing context, so this is an incoming |
- // pairing request that should use our best default delegate (if we have one). |
- BluetoothDevice::PairingDelegate* pairing_delegate = DefaultPairingDelegate(); |
- if (!pairing_delegate) |
- return nullptr; |
- |
- return device_chromeos->BeginPairing(pairing_delegate); |
-} |
- |
-void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) { |
- DCHECK(!IsPresent()); |
- DCHECK(!dbus_is_shutdown_); |
- object_path_ = object_path; |
- |
- VLOG(1) << object_path_.value() << ": using adapter."; |
- |
- VLOG(1) << "Registering pairing agent"; |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAgentManagerClient() |
- ->RegisterAgent( |
- dbus::ObjectPath(kAgentPath), |
- bluetooth_agent_manager::kKeyboardDisplayCapability, |
- base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent, |
- weak_ptr_factory_.GetWeakPtr()), |
- base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError, |
- weak_ptr_factory_.GetWeakPtr())); |
- |
- SetDefaultAdapterName(); |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- |
- PresentChanged(true); |
- |
- if (properties->powered.value()) |
- PoweredChanged(true); |
- if (properties->discoverable.value()) |
- DiscoverableChanged(true); |
- if (properties->discovering.value()) |
- DiscoveringChanged(true); |
- |
- std::vector<dbus::ObjectPath> device_paths = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothDeviceClient() |
- ->GetDevicesForAdapter(object_path_); |
- |
- for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin(); |
- iter != device_paths.end(); ++iter) { |
- DeviceAdded(*iter); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::SetDefaultAdapterName() { |
- DCHECK(IsPresent()); |
- |
- std::string alias; |
- switch (chromeos::GetDeviceType()) { |
- case DeviceType::kChromebase: |
- alias = "Chromebase"; |
- break; |
- case DeviceType::kChromebit: |
- alias = "Chromebit"; |
- break; |
- case DeviceType::kChromebook: |
- alias = "Chromebook"; |
- break; |
- case DeviceType::kChromebox: |
- alias = "Chromebox"; |
- break; |
- case DeviceType::kUnknown: |
- alias = "Chromebook"; |
- break; |
- } |
- |
- SetName(alias, base::Bind(&base::DoNothing), base::Bind(&base::DoNothing)); |
-} |
- |
-void BluetoothAdapterChromeOS::RemoveAdapter() { |
- DCHECK(IsPresent()); |
- VLOG(1) << object_path_.value() << ": adapter removed."; |
- |
- bluez::BluetoothAdapterClient::Properties* properties = |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_); |
- |
- object_path_ = dbus::ObjectPath(""); |
- |
- if (properties->powered.value()) |
- PoweredChanged(false); |
- if (properties->discoverable.value()) |
- DiscoverableChanged(false); |
- if (properties->discovering.value()) |
- DiscoveringChanged(false); |
- |
- // Move all elements of the original devices list to a new list here, |
- // leaving the original list empty so that when we send DeviceRemoved(), |
- // GetDevices() returns no devices. |
- DevicesMap devices_swapped; |
- devices_swapped.swap(devices_); |
- |
- for (auto& iter : devices_swapped) { |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- DeviceRemoved(this, iter.second)); |
- } |
- |
- PresentChanged(false); |
-} |
- |
-void BluetoothAdapterChromeOS::PoweredChanged(bool powered) { |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- AdapterPoweredChanged(this, powered)); |
-} |
- |
-void BluetoothAdapterChromeOS::DiscoverableChanged(bool discoverable) { |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- AdapterDiscoverableChanged(this, discoverable)); |
-} |
- |
-void BluetoothAdapterChromeOS::DiscoveringChanged( |
- bool discovering) { |
- // If the adapter stopped discovery due to a reason other than a request by |
- // us, reset the count to 0. |
- VLOG(1) << "Discovering changed: " << discovering; |
- if (!discovering && !discovery_request_pending_ && |
- num_discovery_sessions_ > 0) { |
- VLOG(1) << "Marking sessions as inactive."; |
- num_discovery_sessions_ = 0; |
- MarkDiscoverySessionsAsInactive(); |
- } |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- AdapterDiscoveringChanged(this, discovering)); |
-} |
- |
-void BluetoothAdapterChromeOS::PresentChanged(bool present) { |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- AdapterPresentChanged(this, present)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyDeviceChanged( |
- BluetoothDeviceChromeOS* device) { |
- DCHECK(device); |
- DCHECK(device->adapter_ == this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- DeviceChanged(this, device)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyDeviceAddressChanged( |
- BluetoothDeviceChromeOS* device, |
- const std::string& old_address) { |
- DCHECK(device->adapter_ == this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- DeviceAddressChanged(this, device, old_address)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattServiceAdded( |
- BluetoothRemoteGattServiceChromeOS* service) { |
- DCHECK_EQ(service->GetAdapter(), this); |
- DCHECK_EQ( |
- static_cast<BluetoothDeviceChromeOS*>(service->GetDevice())->adapter_, |
- this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattServiceAdded(this, service->GetDevice(), service)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattServiceRemoved( |
- BluetoothRemoteGattServiceChromeOS* service) { |
- DCHECK_EQ(service->GetAdapter(), this); |
- DCHECK_EQ( |
- static_cast<BluetoothDeviceChromeOS*>(service->GetDevice())->adapter_, |
- this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattServiceRemoved(this, service->GetDevice(), service)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattServiceChanged( |
- BluetoothRemoteGattServiceChromeOS* service) { |
- DCHECK_EQ(service->GetAdapter(), this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattServiceChanged(this, service)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattServicesDiscovered( |
- BluetoothDeviceChromeOS* device) { |
- DCHECK(device->adapter_ == this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
- GattServicesDiscovered(this, device)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattDiscoveryComplete( |
- BluetoothRemoteGattServiceChromeOS* service) { |
- DCHECK_EQ(service->GetAdapter(), this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattDiscoveryCompleteForService(this, service)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattCharacteristicAdded( |
- BluetoothRemoteGattCharacteristicChromeOS* characteristic) { |
- DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( |
- characteristic->GetService())->GetAdapter(), |
- this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattCharacteristicAdded(this, characteristic)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattCharacteristicRemoved( |
- BluetoothRemoteGattCharacteristicChromeOS* characteristic) { |
- DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( |
- characteristic->GetService())->GetAdapter(), |
- this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattCharacteristicRemoved(this, characteristic)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattDescriptorAdded( |
- BluetoothRemoteGattDescriptorChromeOS* descriptor) { |
- DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( |
- descriptor->GetCharacteristic()->GetService())->GetAdapter(), |
- this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattDescriptorAdded(this, descriptor)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattDescriptorRemoved( |
- BluetoothRemoteGattDescriptorChromeOS* descriptor) { |
- DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( |
- descriptor->GetCharacteristic()->GetService())->GetAdapter(), |
- this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattDescriptorRemoved(this, descriptor)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattCharacteristicValueChanged( |
- BluetoothRemoteGattCharacteristicChromeOS* characteristic, |
- const std::vector<uint8>& value) { |
- DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( |
- characteristic->GetService())->GetAdapter(), |
- this); |
- |
- FOR_EACH_OBSERVER( |
- BluetoothAdapter::Observer, |
- observers_, |
- GattCharacteristicValueChanged(this, characteristic, value)); |
-} |
- |
-void BluetoothAdapterChromeOS::NotifyGattDescriptorValueChanged( |
- BluetoothRemoteGattDescriptorChromeOS* descriptor, |
- const std::vector<uint8>& value) { |
- DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( |
- descriptor->GetCharacteristic()->GetService())->GetAdapter(), |
- this); |
- |
- FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
- observers_, |
- GattDescriptorValueChanged(this, descriptor, value)); |
-} |
- |
-void BluetoothAdapterChromeOS::UseProfile( |
- const BluetoothUUID& uuid, |
- const dbus::ObjectPath& device_path, |
- const bluez::BluetoothProfileManagerClient::Options& options, |
- bluez::BluetoothProfileServiceProvider::Delegate* delegate, |
- const ProfileRegisteredCallback& success_callback, |
- const ErrorCompletionCallback& error_callback) { |
- DCHECK(delegate); |
- |
- if (!IsPresent()) { |
- VLOG(2) << "Adapter not present, erroring out"; |
- error_callback.Run("Adapter not present"); |
- return; |
- } |
- |
- if (profiles_.find(uuid) != profiles_.end()) { |
- // TODO(jamuraa) check that the options are the same and error when they are |
- // not. |
- SetProfileDelegate(uuid, device_path, delegate, success_callback, |
- error_callback); |
- return; |
- } |
- |
- if (profile_queues_.find(uuid) == profile_queues_.end()) { |
- BluetoothAdapterProfileChromeOS::Register( |
- uuid, options, |
- base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfile, this, uuid), |
- base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfileError, this, |
- uuid)); |
- |
- profile_queues_[uuid] = new std::vector<RegisterProfileCompletionPair>(); |
- } |
- |
- profile_queues_[uuid]->push_back(std::make_pair( |
- base::Bind(&BluetoothAdapterChromeOS::SetProfileDelegate, this, uuid, |
- device_path, delegate, success_callback, error_callback), |
- error_callback)); |
-} |
- |
-void BluetoothAdapterChromeOS::ReleaseProfile( |
- const dbus::ObjectPath& device_path, |
- BluetoothAdapterProfileChromeOS* profile) { |
- VLOG(2) << "Releasing Profile: " << profile->uuid().canonical_value() |
- << " from " << device_path.value(); |
- profile->RemoveDelegate( |
- device_path, base::Bind(&BluetoothAdapterChromeOS::RemoveProfile, |
- weak_ptr_factory_.GetWeakPtr(), profile->uuid())); |
-} |
- |
-void BluetoothAdapterChromeOS::RemoveProfile(const BluetoothUUID& uuid) { |
- VLOG(2) << "Remove Profile: " << uuid.canonical_value(); |
- |
- if (profiles_.find(uuid) != profiles_.end()) { |
- delete profiles_[uuid]; |
- profiles_.erase(uuid); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::OnRegisterProfile( |
- const BluetoothUUID& uuid, |
- scoped_ptr<BluetoothAdapterProfileChromeOS> profile) { |
- profiles_[uuid] = profile.release(); |
- |
- if (profile_queues_.find(uuid) == profile_queues_.end()) |
- return; |
- |
- for (auto& it : *profile_queues_[uuid]) |
- it.first.Run(); |
- delete profile_queues_[uuid]; |
- profile_queues_.erase(uuid); |
-} |
- |
-void BluetoothAdapterChromeOS::SetProfileDelegate( |
- const BluetoothUUID& uuid, |
- const dbus::ObjectPath& device_path, |
- bluez::BluetoothProfileServiceProvider::Delegate* delegate, |
- const ProfileRegisteredCallback& success_callback, |
- const ErrorCompletionCallback& error_callback) { |
- if (profiles_.find(uuid) == profiles_.end()) { |
- error_callback.Run("Cannot find profile!"); |
- return; |
- } |
- |
- if (profiles_[uuid]->SetDelegate(device_path, delegate)) { |
- success_callback.Run(profiles_[uuid]); |
- return; |
- } |
- // Already set |
- error_callback.Run(bluetooth_agent_manager::kErrorAlreadyExists); |
-} |
- |
-void BluetoothAdapterChromeOS::OnRegisterProfileError( |
- const BluetoothUUID& uuid, |
- const std::string& error_name, |
- const std::string& error_message) { |
- VLOG(2) << object_path_.value() << ": Failed to register profile: " |
- << error_name << ": " << error_message; |
- if (profile_queues_.find(uuid) == profile_queues_.end()) |
- return; |
- |
- for (auto& it : *profile_queues_[uuid]) |
- it.second.Run(error_message); |
- |
- delete profile_queues_[uuid]; |
- profile_queues_.erase(uuid); |
-} |
- |
-void BluetoothAdapterChromeOS::OnSetDiscoverable( |
- const base::Closure& callback, |
- const ErrorCallback& error_callback, |
- bool success) { |
- if (!IsPresent()) { |
- error_callback.Run(); |
- return; |
- } |
- |
- // Set the discoverable_timeout property to zero so the adapter remains |
- // discoverable forever. |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->GetProperties(object_path_) |
- ->discoverable_timeout.Set( |
- 0, |
- base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
-} |
- |
-void BluetoothAdapterChromeOS::OnPropertyChangeCompleted( |
- const base::Closure& callback, |
- const ErrorCallback& error_callback, |
- bool success) { |
- if (IsPresent() && success) { |
- callback.Run(); |
- } else { |
- error_callback.Run(); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::AddDiscoverySession( |
- BluetoothDiscoveryFilter* discovery_filter, |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback) { |
- if (!IsPresent()) { |
- error_callback.Run( |
- UMABluetoothDiscoverySessionOutcome::ADAPTER_NOT_PRESENT); |
- return; |
- } |
- VLOG(1) << __func__; |
- if (discovery_request_pending_) { |
- // The pending request is either to stop a previous session or to start a |
- // new one. Either way, queue this one. |
- DCHECK(num_discovery_sessions_ == 1 || num_discovery_sessions_ == 0); |
- VLOG(1) << "Pending request to start/stop device discovery. Queueing " |
- << "request to start a new discovery session."; |
- discovery_request_queue_.push( |
- std::make_tuple(discovery_filter, callback, error_callback)); |
- return; |
- } |
- |
- // The adapter is already discovering. |
- if (num_discovery_sessions_ > 0) { |
- DCHECK(IsDiscovering()); |
- DCHECK(!discovery_request_pending_); |
- num_discovery_sessions_++; |
- SetDiscoveryFilter(BluetoothDiscoveryFilter::Merge( |
- GetMergedDiscoveryFilter().get(), discovery_filter), |
- callback, error_callback); |
- return; |
- } |
- |
- // There are no active discovery sessions. |
- DCHECK_EQ(num_discovery_sessions_, 0); |
- |
- if (discovery_filter) { |
- discovery_request_pending_ = true; |
- |
- scoped_ptr<BluetoothDiscoveryFilter> df(new BluetoothDiscoveryFilter( |
- BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL)); |
- df->CopyFrom(*discovery_filter); |
- SetDiscoveryFilter( |
- df.Pass(), |
- base::Bind(&BluetoothAdapterChromeOS::OnPreSetDiscoveryFilter, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback), |
- base::Bind(&BluetoothAdapterChromeOS::OnPreSetDiscoveryFilterError, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
- return; |
- } else { |
- current_filter_.reset(); |
- } |
- |
- // This is the first request to start device discovery. |
- discovery_request_pending_ = true; |
- bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery( |
- object_path_, |
- base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback), |
- base::Bind(&BluetoothAdapterChromeOS::OnStartDiscoveryError, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
-} |
- |
-void BluetoothAdapterChromeOS::RemoveDiscoverySession( |
- BluetoothDiscoveryFilter* discovery_filter, |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback) { |
- if (!IsPresent()) { |
- error_callback.Run( |
- UMABluetoothDiscoverySessionOutcome::ADAPTER_NOT_PRESENT); |
- return; |
- } |
- |
- VLOG(1) << __func__; |
- // There are active sessions other than the one currently being removed. |
- if (num_discovery_sessions_ > 1) { |
- DCHECK(IsDiscovering()); |
- DCHECK(!discovery_request_pending_); |
- num_discovery_sessions_--; |
- |
- SetDiscoveryFilter(GetMergedDiscoveryFilterMasked(discovery_filter), |
- callback, error_callback); |
- return; |
- } |
- |
- // If there is a pending request to BlueZ, then queue this request. |
- if (discovery_request_pending_) { |
- VLOG(1) << "Pending request to start/stop device discovery. Queueing " |
- << "request to stop discovery session."; |
- error_callback.Run( |
- UMABluetoothDiscoverySessionOutcome::REMOVE_WITH_PENDING_REQUEST); |
- return; |
- } |
- |
- // There are no active sessions. Return error. |
- if (num_discovery_sessions_ == 0) { |
- // TODO(armansito): This should never happen once we have the |
- // DiscoverySession API. Replace this case with an assert once it's |
- // the deprecated methods have been removed. (See crbug.com/3445008). |
- VLOG(1) << "No active discovery sessions. Returning error."; |
- error_callback.Run( |
- UMABluetoothDiscoverySessionOutcome::ACTIVE_SESSION_NOT_IN_ADAPTER); |
- return; |
- } |
- |
- // There is exactly one active discovery session. Request BlueZ to stop |
- // discovery. |
- DCHECK_EQ(num_discovery_sessions_, 1); |
- discovery_request_pending_ = true; |
- bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StopDiscovery( |
- object_path_, base::Bind(&BluetoothAdapterChromeOS::OnStopDiscovery, |
- weak_ptr_factory_.GetWeakPtr(), callback), |
- base::Bind(&BluetoothAdapterChromeOS::OnStopDiscoveryError, |
- weak_ptr_factory_.GetWeakPtr(), error_callback)); |
-} |
- |
-void BluetoothAdapterChromeOS::SetDiscoveryFilter( |
- scoped_ptr<BluetoothDiscoveryFilter> discovery_filter, |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback) { |
- if (!IsPresent()) { |
- error_callback.Run(UMABluetoothDiscoverySessionOutcome::ADAPTER_REMOVED); |
- return; |
- } |
- |
- // If old and new filter are equal (null) then don't make request, just call |
- // succes callback |
- if (!current_filter_ && !discovery_filter.get()) { |
- callback.Run(); |
- return; |
- } |
- |
- // If old and new filter are not null and equal then don't make request, just |
- // call succes callback |
- if (current_filter_ && discovery_filter && |
- current_filter_->Equals(*discovery_filter)) { |
- callback.Run(); |
- return; |
- } |
- |
- current_filter_.reset(discovery_filter.release()); |
- |
- bluez::BluetoothAdapterClient::DiscoveryFilter dbus_discovery_filter; |
- |
- if (current_filter_.get()) { |
- uint16_t pathloss; |
- int16_t rssi; |
- uint8_t transport; |
- std::set<device::BluetoothUUID> uuids; |
- |
- if (current_filter_->GetPathloss(&pathloss)) |
- dbus_discovery_filter.pathloss.reset(new uint16_t(pathloss)); |
- |
- if (current_filter_->GetRSSI(&rssi)) |
- dbus_discovery_filter.rssi.reset(new int16_t(rssi)); |
- |
- transport = current_filter_->GetTransport(); |
- if (transport == BluetoothDiscoveryFilter::Transport::TRANSPORT_LE) { |
- dbus_discovery_filter.transport.reset(new std::string("le")); |
- } else if (transport == |
- BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC) { |
- dbus_discovery_filter.transport.reset(new std::string("bredr")); |
- } else if (transport == |
- BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL) { |
- dbus_discovery_filter.transport.reset(new std::string("auto")); |
- } |
- |
- current_filter_->GetUUIDs(uuids); |
- if (uuids.size()) { |
- dbus_discovery_filter.uuids = |
- scoped_ptr<std::vector<std::string>>(new std::vector<std::string>); |
- |
- for (const auto& it : uuids) |
- dbus_discovery_filter.uuids.get()->push_back(it.value()); |
- } |
- } |
- |
- bluez::BluezDBusManager::Get() |
- ->GetBluetoothAdapterClient() |
- ->SetDiscoveryFilter( |
- object_path_, dbus_discovery_filter, |
- base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilter, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback), |
- base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilterError, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
-} |
- |
-void BluetoothAdapterChromeOS::OnStartDiscovery( |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback) { |
- // Report success on the original request and increment the count. |
- VLOG(1) << __func__; |
- DCHECK(discovery_request_pending_); |
- DCHECK_EQ(num_discovery_sessions_, 0); |
- discovery_request_pending_ = false; |
- num_discovery_sessions_++; |
- if (IsPresent()) { |
- callback.Run(); |
- } else { |
- error_callback.Run(UMABluetoothDiscoverySessionOutcome::ADAPTER_REMOVED); |
- } |
- |
- // Try to add a new discovery session for each queued request. |
- ProcessQueuedDiscoveryRequests(); |
-} |
- |
-void BluetoothAdapterChromeOS::OnStartDiscoveryError( |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback, |
- const std::string& error_name, |
- const std::string& error_message) { |
- LOG(WARNING) << object_path_.value() << ": Failed to start discovery: " |
- << error_name << ": " << error_message; |
- |
- // Failed to start discovery. This can only happen if the count is at 0. |
- DCHECK_EQ(num_discovery_sessions_, 0); |
- DCHECK(discovery_request_pending_); |
- discovery_request_pending_ = false; |
- |
- // Discovery request may fail if discovery was previously initiated by Chrome, |
- // but the session were invalidated due to the discovery state unexpectedly |
- // changing to false and then back to true. In this case, report success. |
- if (IsPresent() && error_name == bluetooth_device::kErrorInProgress && |
- IsDiscovering()) { |
- VLOG(1) << "Discovery previously initiated. Reporting success."; |
- num_discovery_sessions_++; |
- callback.Run(); |
- } else { |
- error_callback.Run(TranslateDiscoveryErrorToUMA(error_name)); |
- } |
- |
- // Try to add a new discovery session for each queued request. |
- ProcessQueuedDiscoveryRequests(); |
-} |
- |
-void BluetoothAdapterChromeOS::OnStopDiscovery(const base::Closure& callback) { |
- // Report success on the original request and decrement the count. |
- VLOG(1) << __func__; |
- DCHECK(discovery_request_pending_); |
- DCHECK_EQ(num_discovery_sessions_, 1); |
- discovery_request_pending_ = false; |
- num_discovery_sessions_--; |
- callback.Run(); |
- |
- current_filter_.reset(); |
- |
- // Try to add a new discovery session for each queued request. |
- ProcessQueuedDiscoveryRequests(); |
-} |
- |
-void BluetoothAdapterChromeOS::OnStopDiscoveryError( |
- const DiscoverySessionErrorCallback& error_callback, |
- const std::string& error_name, |
- const std::string& error_message) { |
- LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: " |
- << error_name << ": " << error_message; |
- |
- // Failed to stop discovery. This can only happen if the count is at 1. |
- DCHECK(discovery_request_pending_); |
- DCHECK_EQ(num_discovery_sessions_, 1); |
- discovery_request_pending_ = false; |
- error_callback.Run(TranslateDiscoveryErrorToUMA(error_name)); |
- |
- // Try to add a new discovery session for each queued request. |
- ProcessQueuedDiscoveryRequests(); |
-} |
- |
-void BluetoothAdapterChromeOS::OnPreSetDiscoveryFilter( |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback) { |
- // This is the first request to start device discovery. |
- DCHECK(discovery_request_pending_); |
- DCHECK_EQ(num_discovery_sessions_, 0); |
- |
- bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery( |
- object_path_, |
- base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback), |
- base::Bind(&BluetoothAdapterChromeOS::OnStartDiscoveryError, |
- weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); |
-} |
- |
-void BluetoothAdapterChromeOS::OnPreSetDiscoveryFilterError( |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback, |
- UMABluetoothDiscoverySessionOutcome outcome) { |
- LOG(WARNING) << object_path_.value() |
- << ": Failed to pre set discovery filter."; |
- |
- // Failed to start discovery. This can only happen if the count is at 0. |
- DCHECK_EQ(num_discovery_sessions_, 0); |
- DCHECK(discovery_request_pending_); |
- discovery_request_pending_ = false; |
- |
- error_callback.Run(outcome); |
- |
- // Try to add a new discovery session for each queued request. |
- ProcessQueuedDiscoveryRequests(); |
-} |
- |
-void BluetoothAdapterChromeOS::OnSetDiscoveryFilter( |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback) { |
- // Report success on the original request and increment the count. |
- VLOG(1) << __func__; |
- if (IsPresent()) { |
- callback.Run(); |
- } else { |
- error_callback.Run(UMABluetoothDiscoverySessionOutcome::ADAPTER_REMOVED); |
- } |
-} |
- |
-void BluetoothAdapterChromeOS::OnSetDiscoveryFilterError( |
- const base::Closure& callback, |
- const DiscoverySessionErrorCallback& error_callback, |
- const std::string& error_name, |
- const std::string& error_message) { |
- LOG(WARNING) << object_path_.value() |
- << ": Failed to set discovery filter: " << error_name << ": " |
- << error_message; |
- |
- UMABluetoothDiscoverySessionOutcome outcome = |
- TranslateDiscoveryErrorToUMA(error_name); |
- if (outcome == UMABluetoothDiscoverySessionOutcome::FAILED) { |
- // bluez/doc/adapter-api.txt says "Failed" is returned from |
- // SetDiscoveryFilter when the controller doesn't support the requested |
- // transport. |
- outcome = UMABluetoothDiscoverySessionOutcome:: |
- CHROMEOS_DBUS_FAILED_MAYBE_UNSUPPORTED_TRANSPORT; |
- } |
- error_callback.Run(outcome); |
- |
- // Try to add a new discovery session for each queued request. |
- ProcessQueuedDiscoveryRequests(); |
-} |
- |
-void BluetoothAdapterChromeOS::ProcessQueuedDiscoveryRequests() { |
- while (!discovery_request_queue_.empty()) { |
- VLOG(1) << "Process queued discovery request."; |
- DiscoveryParamTuple params = discovery_request_queue_.front(); |
- discovery_request_queue_.pop(); |
- AddDiscoverySession(std::get<0>(params), std::get<1>(params), |
- std::get<2>(params)); |
- |
- // If the queued request resulted in a pending call, then let it |
- // asynchonously process the remaining queued requests once the pending |
- // call returns. |
- if (discovery_request_pending_) |
- return; |
- } |
-} |
- |
-} // namespace chromeos |