| Index: device/bluetooth/bluetooth_socket_chromeos.cc
|
| diff --git a/device/bluetooth/bluetooth_socket_chromeos.cc b/device/bluetooth/bluetooth_socket_chromeos.cc
|
| index c281a595100d29a1905ed956431ddaccae168dd7..bf0efa0eb82224e6d8c2cf416730681ed647e6a5 100644
|
| --- a/device/bluetooth/bluetooth_socket_chromeos.cc
|
| +++ b/device/bluetooth/bluetooth_socket_chromeos.cc
|
| @@ -4,22 +4,49 @@
|
|
|
| #include "device/bluetooth/bluetooth_socket_chromeos.h"
|
|
|
| +#include <queue>
|
| #include <string>
|
|
|
| +#include "base/basictypes.h"
|
| +#include "base/bind.h"
|
| +#include "base/callback.h"
|
| #include "base/logging.h"
|
| +#include "base/memory/linked_ptr.h"
|
| #include "base/memory/ref_counted.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "base/sequenced_task_runner.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "base/task_runner_util.h"
|
| #include "base/threading/thread_restrictions.h"
|
| +#include "base/threading/worker_pool.h"
|
| +#include "chromeos/dbus/bluetooth_device_client.h"
|
| +#include "chromeos/dbus/bluetooth_profile_manager_client.h"
|
| +#include "chromeos/dbus/bluetooth_profile_service_provider.h"
|
| +#include "chromeos/dbus/dbus_thread_manager.h"
|
| +#include "dbus/bus.h"
|
| #include "dbus/file_descriptor.h"
|
| +#include "dbus/object_path.h"
|
| +#include "device/bluetooth/bluetooth_adapter.h"
|
| +#include "device/bluetooth/bluetooth_adapter_chromeos.h"
|
| +#include "device/bluetooth/bluetooth_device.h"
|
| +#include "device/bluetooth/bluetooth_device_chromeos.h"
|
| #include "device/bluetooth/bluetooth_socket.h"
|
| #include "device/bluetooth/bluetooth_socket_net.h"
|
| #include "device/bluetooth/bluetooth_socket_thread.h"
|
| #include "net/base/ip_endpoint.h"
|
| #include "net/base/net_errors.h"
|
| +#include "third_party/cros_system_api/dbus/service_constants.h"
|
| +
|
| +using device::BluetoothAdapter;
|
| +using device::BluetoothDevice;
|
| +using device::BluetoothSocketThread;
|
| +using device::BluetoothUUID;
|
|
|
| namespace {
|
|
|
| -const char kSocketAlreadyConnected[] = "Socket is already connected.";
|
| +const char kAcceptFailed[] = "Failed to accept connection.";
|
| +const char kInvalidUUID[] = "Invalid UUID";
|
| +const char kSocketNotListening[] = "Socket is not listening.";
|
|
|
| } // namespace
|
|
|
| @@ -29,7 +56,7 @@ namespace chromeos {
|
| scoped_refptr<BluetoothSocketChromeOS>
|
| BluetoothSocketChromeOS::CreateBluetoothSocket(
|
| scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
|
| - scoped_refptr<device::BluetoothSocketThread> socket_thread,
|
| + scoped_refptr<BluetoothSocketThread> socket_thread,
|
| net::NetLog* net_log,
|
| const net::NetLog::Source& source) {
|
| DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
|
| @@ -39,53 +66,425 @@ BluetoothSocketChromeOS::CreateBluetoothSocket(
|
| ui_task_runner, socket_thread, net_log, source));
|
| }
|
|
|
| +BluetoothSocketChromeOS::AcceptRequest::AcceptRequest() {}
|
| +
|
| +BluetoothSocketChromeOS::AcceptRequest::~AcceptRequest() {}
|
| +
|
| +BluetoothSocketChromeOS::ConnectionRequest::ConnectionRequest()
|
| + : accepting(false),
|
| + cancelled(false) {}
|
| +
|
| +BluetoothSocketChromeOS::ConnectionRequest::~ConnectionRequest() {}
|
| +
|
| BluetoothSocketChromeOS::BluetoothSocketChromeOS(
|
| scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
|
| - scoped_refptr<device::BluetoothSocketThread> socket_thread,
|
| + scoped_refptr<BluetoothSocketThread> socket_thread,
|
| net::NetLog* net_log,
|
| const net::NetLog::Source& source)
|
| : BluetoothSocketNet(ui_task_runner, socket_thread, net_log, source) {
|
| }
|
|
|
| BluetoothSocketChromeOS::~BluetoothSocketChromeOS() {
|
| + DCHECK(object_path_.value().empty());
|
| + DCHECK(profile_.get() == NULL);
|
| +
|
| + if (adapter_.get()) {
|
| + adapter_->RemoveObserver(this);
|
| + adapter_ = NULL;
|
| + }
|
| }
|
|
|
| void BluetoothSocketChromeOS::Connect(
|
| - scoped_ptr<dbus::FileDescriptor> fd,
|
| + const BluetoothDeviceChromeOS* device,
|
| + const BluetoothUUID& uuid,
|
| const base::Closure& success_callback,
|
| const ErrorCompletionCallback& error_callback) {
|
| DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(object_path_.value().empty());
|
| + DCHECK(!profile_.get());
|
|
|
| - socket_thread()->task_runner()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(
|
| - &BluetoothSocketChromeOS::DoConnect,
|
| - this,
|
| - base::Passed(&fd),
|
| - base::Bind(&BluetoothSocketChromeOS::PostSuccess,
|
| - this,
|
| - success_callback),
|
| - base::Bind(&BluetoothSocketChromeOS::PostErrorCompletion,
|
| - this,
|
| - error_callback)));
|
| + if (!uuid.IsValid()) {
|
| + error_callback.Run(kInvalidUUID);
|
| + return;
|
| + }
|
| +
|
| + device_address_ = device->GetAddress();
|
| + device_path_ = device->object_path();
|
| + uuid_ = uuid;
|
| + options_.reset(new BluetoothProfileManagerClient::Options());
|
| +
|
| + RegisterProfile(success_callback, error_callback);
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::Listen(
|
| + scoped_refptr<BluetoothAdapter> adapter,
|
| + SocketType socket_type,
|
| + const BluetoothUUID& uuid,
|
| + int psm_or_channel,
|
| + bool insecure,
|
| + const base::Closure& success_callback,
|
| + const ErrorCompletionCallback& error_callback) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(object_path_.value().empty());
|
| + DCHECK(!profile_.get());
|
| +
|
| + if (!uuid.IsValid()) {
|
| + error_callback.Run(kInvalidUUID);
|
| + return;
|
| + }
|
| +
|
| + adapter_ = adapter;
|
| + adapter_->AddObserver(this);
|
| +
|
| + uuid_ = uuid;
|
| + options_.reset(new BluetoothProfileManagerClient::Options());
|
| +
|
| + switch (socket_type) {
|
| + case kRfcomm:
|
| + options_->channel.reset(new uint16(
|
| + psm_or_channel == BluetoothAdapter::kChannelAuto
|
| + ? 0 : psm_or_channel));
|
| + break;
|
| + case kL2cap:
|
| + options_->psm.reset(new uint16(
|
| + psm_or_channel == BluetoothAdapter::kPsmAuto
|
| + ? 0 : psm_or_channel));
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +
|
| + if (insecure)
|
| + options_->require_authentication.reset(new bool(false));
|
| +
|
| + RegisterProfile(success_callback, error_callback);
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::Close() {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| +
|
| + if (profile_)
|
| + UnregisterProfile();
|
| +
|
| + if (!device_path_.value().empty()) {
|
| + BluetoothSocketNet::Close();
|
| + } else {
|
| + DoCloseListening();
|
| + }
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::Disconnect(const base::Closure& callback) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| +
|
| + if (profile_)
|
| + UnregisterProfile();
|
| +
|
| + if (!device_path_.value().empty()) {
|
| + BluetoothSocketNet::Disconnect(callback);
|
| + } else {
|
| + DoCloseListening();
|
| + callback.Run();
|
| + }
|
| }
|
|
|
| void BluetoothSocketChromeOS::Accept(
|
| const AcceptCompletionCallback& success_callback,
|
| const ErrorCompletionCallback& error_callback) {
|
| - NOTIMPLEMENTED();
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| +
|
| + if (!device_path_.value().empty()) {
|
| + error_callback.Run(kSocketNotListening);
|
| + return;
|
| + }
|
| +
|
| + // Only one pending accept at a time
|
| + if (accept_request_.get()) {
|
| + error_callback.Run(net::ErrorToString(net::ERR_IO_PENDING));
|
| + return;
|
| + }
|
| +
|
| + accept_request_.reset(new AcceptRequest);
|
| + accept_request_->success_callback = success_callback;
|
| + accept_request_->error_callback = error_callback;
|
| +
|
| + if (connection_request_queue_.size() >= 1) {
|
| + AcceptConnectionRequest();
|
| + }
|
| }
|
|
|
| -void BluetoothSocketChromeOS::DoConnect(
|
| - scoped_ptr<dbus::FileDescriptor> fd,
|
| +void BluetoothSocketChromeOS::RegisterProfile(
|
| const base::Closure& success_callback,
|
| const ErrorCompletionCallback& error_callback) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(object_path_.value().empty());
|
| + DCHECK(!profile_.get());
|
| +
|
| + // The object path is relatively meaningless, but has to be unique, so for
|
| + // connecting profiles use a combination of the device address and profile
|
| + // UUID.
|
| + std::string device_address_path, uuid_path;
|
| + base::ReplaceChars(device_address_, ":-", "_", &device_address_path);
|
| + base::ReplaceChars(uuid_.canonical_value(), ":-", "_", &uuid_path);
|
| + if (!device_address_path.empty()) {
|
| + object_path_ = dbus::ObjectPath("/org/chromium/bluetooth_profile/" +
|
| + device_address_path + "/" + uuid_path);
|
| + } else {
|
| + object_path_ = dbus::ObjectPath("/org/chromium/bluetooth_profile/" +
|
| + uuid_path);
|
| + }
|
| +
|
| + // Create the service provider for the profile object.
|
| + dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
|
| + profile_.reset(BluetoothProfileServiceProvider::Create(
|
| + system_bus, object_path_, this));
|
| + DCHECK(profile_.get());
|
| +
|
| + // Before reaching out to the Bluetooth Daemon to register a listening socket,
|
| + // make sure it's actually running. If not, report success and carry on;
|
| + // the profile will be registered when the daemon becomes available.
|
| + if (adapter_ && !adapter_->IsPresent()) {
|
| + VLOG(1) << object_path_.value() << ": Delaying profile registration.";
|
| + success_callback.Run();
|
| + return;
|
| + }
|
| +
|
| + VLOG(1) << object_path_.value() << ": Registering profile.";
|
| + DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->
|
| + RegisterProfile(
|
| + object_path_,
|
| + uuid_.canonical_value(),
|
| + *options_,
|
| + base::Bind(&BluetoothSocketChromeOS::OnRegisterProfile,
|
| + this,
|
| + success_callback,
|
| + error_callback),
|
| + base::Bind(&BluetoothSocketChromeOS::OnRegisterProfileError,
|
| + this,
|
| + error_callback));
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnRegisterProfile(
|
| + const base::Closure& success_callback,
|
| + const ErrorCompletionCallback& error_callback) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + if (!device_path_.value().empty()) {
|
| + VLOG(1) << object_path_.value() << ": Profile registered, connecting to "
|
| + << device_path_.value();
|
| +
|
| + DBusThreadManager::Get()->GetBluetoothDeviceClient()->
|
| + ConnectProfile(
|
| + device_path_,
|
| + uuid_.canonical_value(),
|
| + base::Bind(
|
| + &BluetoothSocketChromeOS::OnConnectProfile,
|
| + this,
|
| + success_callback),
|
| + base::Bind(
|
| + &BluetoothSocketChromeOS::OnConnectProfileError,
|
| + this,
|
| + error_callback));
|
| + } else {
|
| + VLOG(1) << object_path_.value() << ": Profile registered.";
|
| + success_callback.Run();
|
| + }
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnRegisterProfileError(
|
| + const ErrorCompletionCallback& error_callback,
|
| + const std::string& error_name,
|
| + const std::string& error_message) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + LOG(WARNING) << object_path_.value() << ": Failed to register profile: "
|
| + << error_name << ": " << error_message;
|
| + error_callback.Run(error_message);
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnConnectProfile(
|
| + const base::Closure& success_callback) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + VLOG(1) << object_path_.value() << ": Profile connected.";
|
| + UnregisterProfile();
|
| + success_callback.Run();
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnConnectProfileError(
|
| + const ErrorCompletionCallback& error_callback,
|
| + const std::string& error_name,
|
| + const std::string& error_message) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + LOG(WARNING) << object_path_.value() << ": Failed to connect profile: "
|
| + << error_name << ": " << error_message;
|
| + UnregisterProfile();
|
| + error_callback.Run(error_message);
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::AdapterPresentChanged(BluetoothAdapter* adapter,
|
| + bool present) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(!object_path_.value().empty());
|
| + DCHECK(profile_.get());
|
| +
|
| + if (!present)
|
| + return;
|
| +
|
| + VLOG(1) << object_path_.value() << ": Re-register profile.";
|
| + DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->
|
| + RegisterProfile(
|
| + object_path_,
|
| + uuid_.canonical_value(),
|
| + *options_,
|
| + base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfile,
|
| + this),
|
| + base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfileError,
|
| + this));
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnInternalRegisterProfile() {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| +
|
| + VLOG(1) << object_path_.value() << ": Profile re-registered";
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnInternalRegisterProfileError(
|
| + const std::string& error_name,
|
| + const std::string& error_message) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| +
|
| + // It's okay if the profile already exists, it means we registered it on
|
| + // initialization.
|
| + if (error_name == bluetooth_profile_manager::kErrorAlreadyExists)
|
| + return;
|
| +
|
| + LOG(WARNING) << object_path_.value() << ": Failed to re-register profile: "
|
| + << error_name << ": " << error_message;
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::Released() {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + VLOG(1) << object_path_.value() << ": Release";
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::NewConnection(
|
| + const dbus::ObjectPath& device_path,
|
| + scoped_ptr<dbus::FileDescriptor> fd,
|
| + const BluetoothProfileServiceProvider::Delegate::Options& options,
|
| + const ConfirmationCallback& callback) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + VLOG(1) << object_path_.value() << ": New connection from device: "
|
| + << device_path.value();
|
| +
|
| + if (!device_path_.value().empty()) {
|
| + DCHECK(device_path_ == device_path);
|
| +
|
| + socket_thread()->task_runner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &BluetoothSocketChromeOS::DoNewConnection,
|
| + this,
|
| + device_path_,
|
| + base::Passed(&fd),
|
| + options,
|
| + callback));
|
| + } else {
|
| + linked_ptr<ConnectionRequest> request(new ConnectionRequest());
|
| + request->device_path = device_path;
|
| + request->fd = fd.Pass();
|
| + request->options = options;
|
| + request->callback = callback;
|
| +
|
| + connection_request_queue_.push(request);
|
| + VLOG(1) << object_path_.value() << ": Connection is now pending.";
|
| + if (accept_request_) {
|
| + AcceptConnectionRequest();
|
| + }
|
| + }
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::RequestDisconnection(
|
| + const dbus::ObjectPath& device_path,
|
| + const ConfirmationCallback& callback) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + VLOG(1) << object_path_.value() << ": Request disconnection";
|
| + callback.Run(SUCCESS);
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::Cancel() {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + VLOG(1) << object_path_.value() << ": Cancel";
|
| +
|
| + if (!connection_request_queue_.size())
|
| + return;
|
| +
|
| + // If the front request is being accepted mark it as cancelled, otherwise
|
| + // just pop it from the queue.
|
| + linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
|
| + if (!request->accepting) {
|
| + request->cancelled = true;
|
| + } else {
|
| + connection_request_queue_.pop();
|
| + }
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::AcceptConnectionRequest() {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(accept_request_.get());
|
| + DCHECK(connection_request_queue_.size() >= 1);
|
| +
|
| + VLOG(1) << object_path_.value() << ": Accepting pending connection.";
|
| +
|
| + linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
|
| + request->accepting = true;
|
| +
|
| + BluetoothDeviceChromeOS* device =
|
| + static_cast<BluetoothAdapterChromeOS*>(adapter_.get())->
|
| + GetDeviceWithPath(request->device_path);
|
| + DCHECK(device);
|
| +
|
| + scoped_refptr<BluetoothSocketChromeOS> client_socket =
|
| + BluetoothSocketChromeOS::CreateBluetoothSocket(
|
| + ui_task_runner(),
|
| + socket_thread(),
|
| + net_log(),
|
| + source());
|
| +
|
| + client_socket->device_address_ = device->GetAddress();
|
| + client_socket->device_path_ = request->device_path;
|
| + client_socket->uuid_ = uuid_;
|
| +
|
| + socket_thread()->task_runner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &BluetoothSocketChromeOS::DoNewConnection,
|
| + client_socket,
|
| + request->device_path,
|
| + base::Passed(&request->fd),
|
| + request->options,
|
| + base::Bind(&BluetoothSocketChromeOS::OnNewConnection,
|
| + this,
|
| + client_socket,
|
| + request->callback)));
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::DoNewConnection(
|
| + const dbus::ObjectPath& device_path,
|
| + scoped_ptr<dbus::FileDescriptor> fd,
|
| + const BluetoothProfileServiceProvider::Delegate::Options& options,
|
| + const ConfirmationCallback& callback) {
|
| DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
|
| base::ThreadRestrictions::AssertIOAllowed();
|
| - DCHECK(fd->is_valid());
|
| + fd->CheckValidity();
|
| +
|
| + VLOG(1) << object_path_.value() << ": Validity check complete.";
|
| + if (!fd->is_valid()) {
|
| + ui_task_runner()->PostTask(FROM_HERE,
|
| + base::Bind(callback, REJECTED));;
|
| + return;
|
| + }
|
|
|
| if (tcp_socket()) {
|
| - error_callback.Run(kSocketAlreadyConnected);
|
| + LOG(WARNING) << object_path_.value() << ": Already connected";
|
| + ui_task_runner()->PostTask(FROM_HERE,
|
| + base::Bind(callback, REJECTED));;
|
| return;
|
| }
|
|
|
| @@ -96,13 +495,96 @@ void BluetoothSocketChromeOS::DoConnect(
|
| int net_result = tcp_socket()->AdoptConnectedSocket(fd->value(),
|
| net::IPEndPoint());
|
| if (net_result != net::OK) {
|
| - error_callback.Run("Error connecting to socket: " +
|
| - std::string(net::ErrorToString(net_result)));
|
| + LOG(WARNING) << object_path_.value() << ": Error adopting socket: "
|
| + << std::string(net::ErrorToString(net_result));
|
| + ui_task_runner()->PostTask(FROM_HERE,
|
| + base::Bind(callback, REJECTED));;
|
| return;
|
| }
|
|
|
| fd->TakeValue();
|
| - success_callback.Run();
|
| + ui_task_runner()->PostTask(FROM_HERE,
|
| + base::Bind(callback, SUCCESS));;
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnNewConnection(
|
| + scoped_refptr<BluetoothSocket> socket,
|
| + const ConfirmationCallback& callback,
|
| + Status status) {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(accept_request_.get());
|
| + DCHECK(connection_request_queue_.size() >= 1);
|
| +
|
| + linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
|
| + if (status == SUCCESS && !request->cancelled) {
|
| + BluetoothDeviceChromeOS* device =
|
| + static_cast<BluetoothAdapterChromeOS*>(adapter_.get())->
|
| + GetDeviceWithPath(request->device_path);
|
| + DCHECK(device);
|
| +
|
| + accept_request_->success_callback.Run(device, socket);
|
| + } else {
|
| + accept_request_->error_callback.Run(kAcceptFailed);
|
| + }
|
| +
|
| + accept_request_.reset(NULL);
|
| + connection_request_queue_.pop();
|
| +
|
| + callback.Run(status);
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::DoCloseListening() {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| +
|
| + if (accept_request_) {
|
| + accept_request_->error_callback.Run(
|
| + net::ErrorToString(net::ERR_CONNECTION_CLOSED));
|
| + accept_request_.reset(NULL);
|
| + }
|
| +
|
| + while (connection_request_queue_.size() > 0) {
|
| + linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
|
| + request->callback.Run(REJECTED);
|
| + connection_request_queue_.pop();
|
| + }
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::UnregisterProfile() {
|
| + DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(!object_path_.value().empty());
|
| + DCHECK(profile_.get());
|
| +
|
| + VLOG(1) << object_path_.value() << ": Unregister profile";
|
| + DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->
|
| + UnregisterProfile(
|
| + object_path_,
|
| + base::Bind(&BluetoothSocketChromeOS::OnUnregisterProfile,
|
| + this,
|
| + object_path_),
|
| + base::Bind(&BluetoothSocketChromeOS::OnUnregisterProfileError,
|
| + this,
|
| + object_path_));
|
| +
|
| + profile_.reset();
|
| + object_path_ = dbus::ObjectPath("");
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnUnregisterProfile(
|
| + const dbus::ObjectPath& object_path) {
|
| + VLOG(1) << object_path.value() << ": Profile unregistered";
|
| +}
|
| +
|
| +void BluetoothSocketChromeOS::OnUnregisterProfileError(
|
| + const dbus::ObjectPath& object_path,
|
| + const std::string& error_name,
|
| + const std::string& error_message) {
|
| + // It's okay if the profile doesn't exist, it means we haven't registered it
|
| + // yet.
|
| + if (error_name == bluetooth_profile_manager::kErrorDoesNotExist)
|
| + return;
|
| +
|
| + LOG(WARNING) << object_path_.value() << ": Failed to unregister profile: "
|
| + << error_name << ": " << error_message;
|
| }
|
|
|
| } // namespace chromeos
|
|
|