Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1734)

Unified Diff: device/bluetooth/bluetooth_adapter_chromeos.cc

Issue 1415573014: Reland "Add Linux support for the Bluetooth API" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: build fix. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698