Index: device/bluetooth/bluetooth_socket_bluez.cc |
diff --git a/device/bluetooth/bluetooth_socket_bluez.cc b/device/bluetooth/bluetooth_socket_bluez.cc |
deleted file mode 100644 |
index 941a904014651b7c8e69e48e81934f38f94143d2..0000000000000000000000000000000000000000 |
--- a/device/bluetooth/bluetooth_socket_bluez.cc |
+++ /dev/null |
@@ -1,542 +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_socket_bluez.h" |
- |
-#include <stdint.h> |
- |
-#include <memory> |
-#include <queue> |
-#include <string> |
-#include <utility> |
- |
-#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/message_loop/message_loop.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 "dbus/bus.h" |
-#include "dbus/file_descriptor.h" |
-#include "dbus/object_path.h" |
-#include "device/bluetooth/bluetooth_adapter.h" |
-#include "device/bluetooth/bluetooth_adapter_bluez.h" |
-#include "device/bluetooth/bluetooth_adapter_profile_bluez.h" |
-#include "device/bluetooth/bluetooth_device.h" |
-#include "device/bluetooth/bluetooth_device_bluez.h" |
-#include "device/bluetooth/bluetooth_socket.h" |
-#include "device/bluetooth/bluetooth_socket_net.h" |
-#include "device/bluetooth/bluetooth_socket_thread.h" |
-#include "device/bluetooth/dbus/bluetooth_device_client.h" |
-#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" |
-#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" |
-#include "device/bluetooth/dbus/bluez_dbus_manager.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 kAcceptFailed[] = "Failed to accept connection."; |
-const char kInvalidUUID[] = "Invalid UUID"; |
-const char kSocketNotListening[] = "Socket is not listening."; |
- |
-} // namespace |
- |
-namespace bluez { |
- |
-// static |
-scoped_refptr<BluetoothSocketBlueZ> BluetoothSocketBlueZ::CreateBluetoothSocket( |
- scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
- scoped_refptr<BluetoothSocketThread> socket_thread) { |
- DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); |
- |
- return make_scoped_refptr( |
- new BluetoothSocketBlueZ(ui_task_runner, socket_thread)); |
-} |
- |
-BluetoothSocketBlueZ::AcceptRequest::AcceptRequest() {} |
- |
-BluetoothSocketBlueZ::AcceptRequest::~AcceptRequest() {} |
- |
-BluetoothSocketBlueZ::ConnectionRequest::ConnectionRequest() |
- : accepting(false), cancelled(false) {} |
- |
-BluetoothSocketBlueZ::ConnectionRequest::~ConnectionRequest() {} |
- |
-BluetoothSocketBlueZ::BluetoothSocketBlueZ( |
- scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
- scoped_refptr<BluetoothSocketThread> socket_thread) |
- : BluetoothSocketNet(ui_task_runner, socket_thread), profile_(nullptr) {} |
- |
-BluetoothSocketBlueZ::~BluetoothSocketBlueZ() { |
- DCHECK(!profile_); |
- |
- if (adapter_.get()) { |
- adapter_->RemoveObserver(this); |
- adapter_ = nullptr; |
- } |
-} |
- |
-void BluetoothSocketBlueZ::Connect( |
- const BluetoothDeviceBlueZ* device, |
- const BluetoothUUID& uuid, |
- SecurityLevel security_level, |
- const base::Closure& success_callback, |
- const ErrorCompletionCallback& error_callback) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(!profile_); |
- |
- if (!uuid.IsValid()) { |
- error_callback.Run(kInvalidUUID); |
- return; |
- } |
- |
- device_address_ = device->GetAddress(); |
- device_path_ = device->object_path(); |
- uuid_ = uuid; |
- options_.reset(new bluez::BluetoothProfileManagerClient::Options()); |
- if (security_level == SECURITY_LEVEL_LOW) |
- options_->require_authentication.reset(new bool(false)); |
- |
- adapter_ = device->adapter(); |
- |
- RegisterProfile(device->adapter(), success_callback, error_callback); |
-} |
- |
-void BluetoothSocketBlueZ::Listen( |
- scoped_refptr<BluetoothAdapter> adapter, |
- SocketType socket_type, |
- const BluetoothUUID& uuid, |
- const BluetoothAdapter::ServiceOptions& service_options, |
- const base::Closure& success_callback, |
- const ErrorCompletionCallback& error_callback) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(!profile_); |
- |
- if (!uuid.IsValid()) { |
- error_callback.Run(kInvalidUUID); |
- return; |
- } |
- |
- adapter_ = adapter; |
- adapter_->AddObserver(this); |
- |
- uuid_ = uuid; |
- options_.reset(new bluez::BluetoothProfileManagerClient::Options()); |
- if (service_options.name) |
- options_->name.reset(new std::string(*service_options.name)); |
- |
- switch (socket_type) { |
- case kRfcomm: |
- options_->channel.reset( |
- new uint16_t(service_options.channel ? *service_options.channel : 0)); |
- break; |
- case kL2cap: |
- options_->psm.reset( |
- new uint16_t(service_options.psm ? *service_options.psm : 0)); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- |
- RegisterProfile(static_cast<BluetoothAdapterBlueZ*>(adapter.get()), |
- success_callback, error_callback); |
-} |
- |
-void BluetoothSocketBlueZ::Close() { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- |
- if (profile_) |
- UnregisterProfile(); |
- |
- // In the case below, where an asynchronous task gets posted on the socket |
- // thread in BluetoothSocketNet::Close, a reference will be held to this |
- // socket by the callback. This may cause the BluetoothAdapter to outlive |
- // BluezDBusManager during shutdown if that callback executes too late. |
- if (adapter_.get()) { |
- adapter_->RemoveObserver(this); |
- adapter_ = nullptr; |
- } |
- |
- if (!device_path_.value().empty()) { |
- BluetoothSocketNet::Close(); |
- } else { |
- DoCloseListening(); |
- } |
-} |
- |
-void BluetoothSocketBlueZ::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 BluetoothSocketBlueZ::Accept( |
- const AcceptCompletionCallback& success_callback, |
- const ErrorCompletionCallback& error_callback) { |
- 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 BluetoothSocketBlueZ::RegisterProfile( |
- BluetoothAdapterBlueZ* adapter, |
- const base::Closure& success_callback, |
- const ErrorCompletionCallback& error_callback) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(!profile_); |
- DCHECK(adapter); |
- |
- // If the adapter is not present, this is a listening socket and the |
- // adapter isn't running yet. Report success and carry on; |
- // the profile will be registered when the daemon becomes available. |
- if (!adapter->IsPresent()) { |
- VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() |
- << ": Delaying profile registration."; |
- base::MessageLoop::current()->PostTask(FROM_HERE, success_callback); |
- return; |
- } |
- |
- VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() |
- << ": Acquiring profile."; |
- |
- adapter->UseProfile(uuid_, device_path_, *options_, this, |
- base::Bind(&BluetoothSocketBlueZ::OnRegisterProfile, this, |
- success_callback, error_callback), |
- base::Bind(&BluetoothSocketBlueZ::OnRegisterProfileError, |
- this, error_callback)); |
-} |
- |
-void BluetoothSocketBlueZ::OnRegisterProfile( |
- const base::Closure& success_callback, |
- const ErrorCompletionCallback& error_callback, |
- BluetoothAdapterProfileBlueZ* profile) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(!profile_); |
- |
- profile_ = profile; |
- |
- if (device_path_.value().empty()) { |
- VLOG(1) << uuid_.canonical_value() << ": Profile registered."; |
- success_callback.Run(); |
- return; |
- } |
- |
- VLOG(1) << uuid_.canonical_value() << ": Got profile, connecting to " |
- << device_path_.value(); |
- |
- bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( |
- device_path_, uuid_.canonical_value(), |
- base::Bind(&BluetoothSocketBlueZ::OnConnectProfile, this, |
- success_callback), |
- base::Bind(&BluetoothSocketBlueZ::OnConnectProfileError, this, |
- error_callback)); |
-} |
- |
-void BluetoothSocketBlueZ::OnRegisterProfileError( |
- const ErrorCompletionCallback& error_callback, |
- const std::string& error_message) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- |
- LOG(WARNING) << uuid_.canonical_value() |
- << ": Failed to register profile: " << error_message; |
- error_callback.Run(error_message); |
-} |
- |
-void BluetoothSocketBlueZ::OnConnectProfile( |
- const base::Closure& success_callback) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(profile_); |
- |
- VLOG(1) << profile_->object_path().value() << ": Profile connected."; |
- UnregisterProfile(); |
- success_callback.Run(); |
-} |
- |
-void BluetoothSocketBlueZ::OnConnectProfileError( |
- const ErrorCompletionCallback& error_callback, |
- const std::string& error_name, |
- const std::string& error_message) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(profile_); |
- |
- LOG(WARNING) << profile_->object_path().value() |
- << ": Failed to connect profile: " << error_name << ": " |
- << error_message; |
- UnregisterProfile(); |
- error_callback.Run(error_message); |
-} |
- |
-void BluetoothSocketBlueZ::AdapterPresentChanged(BluetoothAdapter* adapter, |
- bool present) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- |
- if (!present) { |
- // Adapter removed, we can't use the profile anymore. |
- UnregisterProfile(); |
- return; |
- } |
- |
- DCHECK(!profile_); |
- |
- VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() |
- << ": Acquiring profile."; |
- |
- static_cast<BluetoothAdapterBlueZ*>(adapter)->UseProfile( |
- uuid_, device_path_, *options_, this, |
- base::Bind(&BluetoothSocketBlueZ::OnInternalRegisterProfile, this), |
- base::Bind(&BluetoothSocketBlueZ::OnInternalRegisterProfileError, this)); |
-} |
- |
-void BluetoothSocketBlueZ::OnInternalRegisterProfile( |
- BluetoothAdapterProfileBlueZ* profile) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(!profile_); |
- |
- profile_ = profile; |
- |
- VLOG(1) << uuid_.canonical_value() << ": Profile re-registered"; |
-} |
- |
-void BluetoothSocketBlueZ::OnInternalRegisterProfileError( |
- const std::string& error_message) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- |
- LOG(WARNING) << "Failed to re-register profile: " << error_message; |
-} |
- |
-void BluetoothSocketBlueZ::Released() { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(profile_); |
- |
- VLOG(1) << profile_->object_path().value() << ": Release"; |
-} |
- |
-void BluetoothSocketBlueZ::NewConnection( |
- const dbus::ObjectPath& device_path, |
- std::unique_ptr<dbus::FileDescriptor> fd, |
- const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, |
- const ConfirmationCallback& callback) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- |
- VLOG(1) << uuid_.canonical_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(&BluetoothSocketBlueZ::DoNewConnection, this, device_path_, |
- base::Passed(&fd), options, callback)); |
- } else { |
- linked_ptr<ConnectionRequest> request(new ConnectionRequest()); |
- request->device_path = device_path; |
- request->fd = std::move(fd); |
- request->options = options; |
- request->callback = callback; |
- |
- connection_request_queue_.push(request); |
- VLOG(1) << uuid_.canonical_value() << ": Connection is now pending."; |
- if (accept_request_) { |
- AcceptConnectionRequest(); |
- } |
- } |
-} |
- |
-void BluetoothSocketBlueZ::RequestDisconnection( |
- const dbus::ObjectPath& device_path, |
- const ConfirmationCallback& callback) { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(profile_); |
- |
- VLOG(1) << profile_->object_path().value() << ": Request disconnection"; |
- callback.Run(SUCCESS); |
-} |
- |
-void BluetoothSocketBlueZ::Cancel() { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(profile_); |
- |
- VLOG(1) << profile_->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 BluetoothSocketBlueZ::AcceptConnectionRequest() { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(accept_request_.get()); |
- DCHECK(connection_request_queue_.size() >= 1); |
- DCHECK(profile_); |
- |
- VLOG(1) << profile_->object_path().value() |
- << ": Accepting pending connection."; |
- |
- linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); |
- request->accepting = true; |
- |
- BluetoothDeviceBlueZ* device = |
- static_cast<BluetoothAdapterBlueZ*>(adapter_.get()) |
- ->GetDeviceWithPath(request->device_path); |
- DCHECK(device); |
- |
- scoped_refptr<BluetoothSocketBlueZ> client_socket = |
- BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner(), |
- socket_thread()); |
- |
- 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(&BluetoothSocketBlueZ::DoNewConnection, client_socket, |
- request->device_path, base::Passed(&request->fd), |
- request->options, |
- base::Bind(&BluetoothSocketBlueZ::OnNewConnection, this, |
- client_socket, request->callback))); |
-} |
- |
-void BluetoothSocketBlueZ::DoNewConnection( |
- const dbus::ObjectPath& device_path, |
- std::unique_ptr<dbus::FileDescriptor> fd, |
- const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, |
- const ConfirmationCallback& callback) { |
- DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread()); |
- base::ThreadRestrictions::AssertIOAllowed(); |
- fd->CheckValidity(); |
- |
- VLOG(1) << uuid_.canonical_value() << ": Validity check complete."; |
- if (!fd->is_valid()) { |
- LOG(WARNING) << uuid_.canonical_value() << " :" << fd->value() |
- << ": Invalid file descriptor received from Bluetooth Daemon."; |
- ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED)); |
- return; |
- } |
- |
- if (tcp_socket()) { |
- LOG(WARNING) << uuid_.canonical_value() << ": Already connected"; |
- ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED)); |
- return; |
- } |
- |
- ResetTCPSocket(); |
- |
- // Note: We don't have a meaningful |IPEndPoint|, but that is ok since the |
- // TCPSocket implementation does not actually require one. |
- int net_result = |
- tcp_socket()->AdoptConnectedSocket(fd->value(), net::IPEndPoint()); |
- if (net_result != net::OK) { |
- LOG(WARNING) << uuid_.canonical_value() << ": Error adopting socket: " |
- << std::string(net::ErrorToString(net_result)); |
- ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED)); |
- return; |
- } |
- |
- VLOG(2) << uuid_.canonical_value() |
- << ": Taking descriptor, confirming success."; |
- fd->TakeValue(); |
- ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, SUCCESS)); |
-} |
- |
-void BluetoothSocketBlueZ::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) { |
- BluetoothDeviceBlueZ* device = |
- static_cast<BluetoothAdapterBlueZ*>(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(nullptr); |
- connection_request_queue_.pop(); |
- |
- callback.Run(status); |
-} |
- |
-void BluetoothSocketBlueZ::DoCloseListening() { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- |
- if (accept_request_) { |
- accept_request_->error_callback.Run( |
- net::ErrorToString(net::ERR_CONNECTION_CLOSED)); |
- accept_request_.reset(nullptr); |
- } |
- |
- while (connection_request_queue_.size() > 0) { |
- linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); |
- request->callback.Run(REJECTED); |
- connection_request_queue_.pop(); |
- } |
-} |
- |
-void BluetoothSocketBlueZ::UnregisterProfile() { |
- DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(profile_); |
- |
- VLOG(1) << profile_->object_path().value() << ": Release profile"; |
- |
- static_cast<BluetoothAdapterBlueZ*>(adapter_.get()) |
- ->ReleaseProfile(device_path_, profile_); |
- profile_ = nullptr; |
-} |
- |
-} // namespace bluez |