Index: device/bluetooth/bluetooth_socket_chromeos.cc |
diff --git a/device/bluetooth/bluetooth_socket_chromeos.cc b/device/bluetooth/bluetooth_socket_chromeos.cc |
index e401a3d6536acde93933ace5f7a8fcc2a5fa2da0..b2958f2fc85a68ae9835cb478b495bcdf7dd4cb4 100644 |
--- a/device/bluetooth/bluetooth_socket_chromeos.cc |
+++ b/device/bluetooth/bluetooth_socket_chromeos.cc |
@@ -28,6 +28,7 @@ |
#include "dbus/object_path.h" |
#include "device/bluetooth/bluetooth_adapter.h" |
#include "device/bluetooth/bluetooth_adapter_chromeos.h" |
+#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h" |
#include "device/bluetooth/bluetooth_device.h" |
#include "device/bluetooth/bluetooth_device_chromeos.h" |
#include "device/bluetooth/bluetooth_socket.h" |
@@ -76,12 +77,11 @@ BluetoothSocketChromeOS::ConnectionRequest::~ConnectionRequest() {} |
BluetoothSocketChromeOS::BluetoothSocketChromeOS( |
scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
scoped_refptr<BluetoothSocketThread> socket_thread) |
- : BluetoothSocketNet(ui_task_runner, socket_thread) { |
+ : BluetoothSocketNet(ui_task_runner, socket_thread), profile_(nullptr) { |
} |
BluetoothSocketChromeOS::~BluetoothSocketChromeOS() { |
- DCHECK(object_path_.value().empty()); |
- DCHECK(profile_.get() == NULL); |
+ DCHECK(!profile_); |
if (adapter_.get()) { |
adapter_->RemoveObserver(this); |
@@ -96,8 +96,7 @@ void BluetoothSocketChromeOS::Connect( |
const base::Closure& success_callback, |
const ErrorCompletionCallback& error_callback) { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(object_path_.value().empty()); |
- DCHECK(!profile_.get()); |
+ DCHECK(!profile_); |
if (!uuid.IsValid()) { |
error_callback.Run(kInvalidUUID); |
@@ -111,7 +110,7 @@ void BluetoothSocketChromeOS::Connect( |
if (security_level == SECURITY_LEVEL_LOW) |
options_->require_authentication.reset(new bool(false)); |
- RegisterProfile(success_callback, error_callback); |
+ RegisterProfile(device->adapter(), success_callback, error_callback); |
} |
void BluetoothSocketChromeOS::Listen( |
@@ -122,8 +121,7 @@ void BluetoothSocketChromeOS::Listen( |
const base::Closure& success_callback, |
const ErrorCompletionCallback& error_callback) { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(object_path_.value().empty()); |
- DCHECK(!profile_.get()); |
+ DCHECK(!profile_); |
if (!uuid.IsValid()) { |
error_callback.Run(kInvalidUUID); |
@@ -151,7 +149,8 @@ void BluetoothSocketChromeOS::Listen( |
NOTREACHED(); |
} |
- RegisterProfile(success_callback, error_callback); |
+ RegisterProfile(static_cast<BluetoothAdapterChromeOS*>(adapter_.get()), |
+ success_callback, error_callback); |
} |
void BluetoothSocketChromeOS::Close() { |
@@ -216,96 +215,76 @@ void BluetoothSocketChromeOS::Accept( |
} |
void BluetoothSocketChromeOS::RegisterProfile( |
+ BluetoothAdapterChromeOS* adapter, |
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()); |
+ DCHECK(!profile_); |
+ DCHECK(adapter); |
- // 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; |
+ // 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_.get() && !adapter_->IsPresent()) { |
- VLOG(1) << object_path_.value() << ": Delaying profile registration."; |
- success_callback.Run(); |
+ 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) << 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)); |
+ VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() |
+ << ": Acquiring profile."; |
+ |
+ adapter->UseProfile( |
+ uuid_, device_path_, *options_, this, |
+ 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) { |
+ const ErrorCompletionCallback& error_callback, |
+ BluetoothAdapterProfileChromeOS* profile) { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- if (!device_path_.value().empty()) { |
- VLOG(1) << object_path_.value() << ": Profile registered, connecting to " |
- << device_path_.value(); |
+ DCHECK(!profile_); |
- 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."; |
+ 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(); |
+ |
+ DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( |
+ device_path_, uuid_.canonical_value(), |
+ base::Bind(&BluetoothSocketChromeOS::OnConnectProfile, this, |
+ success_callback), |
+ base::Bind(&BluetoothSocketChromeOS::OnConnectProfileError, this, |
+ error_callback)); |
} |
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; |
+ |
+ LOG(WARNING) << uuid_.canonical_value() |
+ << ": Failed to register profile: " << 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."; |
+ DCHECK(profile_); |
+ |
+ VLOG(1) << profile_->object_path().value() << ": Profile connected."; |
UnregisterProfile(); |
success_callback.Run(); |
} |
@@ -315,8 +294,11 @@ void BluetoothSocketChromeOS::OnConnectProfileError( |
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; |
+ DCHECK(profile_); |
+ |
+ LOG(WARNING) << profile_->object_path().value() |
+ << ": Failed to connect profile: " << error_name << ": " |
+ << error_message; |
UnregisterProfile(); |
error_callback.Run(error_message); |
} |
@@ -324,47 +306,47 @@ void BluetoothSocketChromeOS::OnConnectProfileError( |
void BluetoothSocketChromeOS::AdapterPresentChanged(BluetoothAdapter* adapter, |
bool present) { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- DCHECK(!object_path_.value().empty()); |
- DCHECK(profile_.get()); |
- if (!present) |
+ if (!present) { |
+ // Adapter removed, the profile is now invalid. |
+ UnregisterProfile(); |
return; |
+ } |
+ |
+ DCHECK(!profile_); |
- 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)); |
+ VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() |
+ << ": Acquiring profile."; |
+ |
+ static_cast<BluetoothAdapterChromeOS*>(adapter)->UseProfile( |
+ uuid_, device_path_, *options_, this, |
+ base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfile, this), |
+ base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfileError, |
+ this)); |
} |
-void BluetoothSocketChromeOS::OnInternalRegisterProfile() { |
+void BluetoothSocketChromeOS::OnInternalRegisterProfile( |
+ BluetoothAdapterProfileChromeOS* profile) { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
+ DCHECK(!profile_); |
+ |
+ profile_ = profile; |
- VLOG(1) << object_path_.value() << ": Profile re-registered"; |
+ VLOG(1) << uuid_.canonical_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; |
+ LOG(WARNING) << "Failed to re-register profile: " << error_message; |
} |
void BluetoothSocketChromeOS::Released() { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- VLOG(1) << object_path_.value() << ": Release"; |
+ DCHECK(profile_); |
+ |
+ VLOG(1) << profile_->object_path().value() << ": Release"; |
} |
void BluetoothSocketChromeOS::NewConnection( |
@@ -373,8 +355,9 @@ void BluetoothSocketChromeOS::NewConnection( |
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(); |
+ |
+ VLOG(1) << uuid_.canonical_value() |
+ << ": New connection from device: " << device_path.value(); |
if (!device_path_.value().empty()) { |
DCHECK(device_path_ == device_path); |
@@ -396,7 +379,7 @@ void BluetoothSocketChromeOS::NewConnection( |
request->callback = callback; |
connection_request_queue_.push(request); |
- VLOG(1) << object_path_.value() << ": Connection is now pending."; |
+ VLOG(1) << uuid_.canonical_value() << ": Connection is now pending."; |
if (accept_request_) { |
AcceptConnectionRequest(); |
} |
@@ -407,13 +390,17 @@ void BluetoothSocketChromeOS::RequestDisconnection( |
const dbus::ObjectPath& device_path, |
const ConfirmationCallback& callback) { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- VLOG(1) << object_path_.value() << ": Request disconnection"; |
+ DCHECK(profile_); |
+ |
+ VLOG(1) << profile_->object_path().value() << ": Request disconnection"; |
callback.Run(SUCCESS); |
} |
void BluetoothSocketChromeOS::Cancel() { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
- VLOG(1) << object_path_.value() << ": Cancel"; |
+ DCHECK(profile_); |
+ |
+ VLOG(1) << profile_->object_path().value() << ": Cancel"; |
if (!connection_request_queue_.size()) |
return; |
@@ -432,8 +419,10 @@ void BluetoothSocketChromeOS::AcceptConnectionRequest() { |
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); |
DCHECK(accept_request_.get()); |
DCHECK(connection_request_queue_.size() >= 1); |
+ DCHECK(profile_); |
- VLOG(1) << object_path_.value() << ": Accepting pending connection."; |
+ VLOG(1) << profile_->object_path().value() |
+ << ": Accepting pending connection."; |
linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); |
request->accepting = true; |
@@ -474,9 +463,9 @@ void BluetoothSocketChromeOS::DoNewConnection( |
base::ThreadRestrictions::AssertIOAllowed(); |
fd->CheckValidity(); |
- VLOG(1) << object_path_.value() << ": Validity check complete."; |
+ VLOG(1) << uuid_.canonical_value() << ": Validity check complete."; |
if (!fd->is_valid()) { |
- LOG(WARNING) << object_path_.value() << " :" << fd->value() |
+ LOG(WARNING) << uuid_.canonical_value() << " :" << fd->value() |
<< ": Invalid file descriptor received from Bluetooth Daemon."; |
ui_task_runner()->PostTask(FROM_HERE, |
base::Bind(callback, REJECTED));; |
@@ -484,7 +473,7 @@ void BluetoothSocketChromeOS::DoNewConnection( |
} |
if (tcp_socket()) { |
- LOG(WARNING) << object_path_.value() << ": Already connected"; |
+ LOG(WARNING) << uuid_.canonical_value() << ": Already connected"; |
ui_task_runner()->PostTask(FROM_HERE, |
base::Bind(callback, REJECTED));; |
return; |
@@ -497,14 +486,15 @@ void BluetoothSocketChromeOS::DoNewConnection( |
int net_result = tcp_socket()->AdoptConnectedSocket(fd->value(), |
net::IPEndPoint()); |
if (net_result != net::OK) { |
- LOG(WARNING) << object_path_.value() << ": Error adopting socket: " |
+ 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) << object_path_.value() << ": Taking descriptor, confirming success."; |
+ VLOG(2) << uuid_.canonical_value() |
+ << ": Taking descriptor, confirming success."; |
fd->TakeValue(); |
ui_task_runner()->PostTask(FROM_HERE, |
base::Bind(callback, SUCCESS));; |
@@ -554,40 +544,24 @@ void BluetoothSocketChromeOS::DoCloseListening() { |
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_)); |
+ DCHECK(profile_); |
- profile_.reset(); |
- object_path_ = dbus::ObjectPath(""); |
-} |
+ VLOG(1) << profile_->object_path().value() << ": Release profile"; |
-void BluetoothSocketChromeOS::OnUnregisterProfile( |
- const dbus::ObjectPath& object_path) { |
- VLOG(1) << object_path.value() << ": Profile unregistered"; |
-} |
+ profile_->RemoveDelegate( |
+ device_path_, |
+ base::Bind(&BluetoothSocketChromeOS::ReleaseProfile, this, profile_)); |
-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; |
+ profile_ = nullptr; |
+} |
- LOG(WARNING) << object_path_.value() << ": Failed to unregister profile: " |
- << error_name << ": " << error_message; |
+void BluetoothSocketChromeOS::ReleaseProfile( |
+ BluetoothAdapterProfileChromeOS* profile) { |
+ if (adapter_) |
+ static_cast<BluetoothAdapterChromeOS*>(adapter_.get()) |
+ ->ReleaseProfile(uuid_); |
+ else |
+ delete profile; |
} |
} // namespace chromeos |