| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "device/bluetooth/bluetooth_socket_bluez.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include <memory> | |
| 10 #include <queue> | |
| 11 #include <string> | |
| 12 #include <utility> | |
| 13 | |
| 14 #include "base/bind.h" | |
| 15 #include "base/callback.h" | |
| 16 #include "base/logging.h" | |
| 17 #include "base/memory/linked_ptr.h" | |
| 18 #include "base/memory/ref_counted.h" | |
| 19 #include "base/message_loop/message_loop.h" | |
| 20 #include "base/sequenced_task_runner.h" | |
| 21 #include "base/strings/string_util.h" | |
| 22 #include "base/task_runner_util.h" | |
| 23 #include "base/threading/thread_restrictions.h" | |
| 24 #include "base/threading/worker_pool.h" | |
| 25 #include "dbus/bus.h" | |
| 26 #include "dbus/file_descriptor.h" | |
| 27 #include "dbus/object_path.h" | |
| 28 #include "device/bluetooth/bluetooth_adapter.h" | |
| 29 #include "device/bluetooth/bluetooth_adapter_bluez.h" | |
| 30 #include "device/bluetooth/bluetooth_adapter_profile_bluez.h" | |
| 31 #include "device/bluetooth/bluetooth_device.h" | |
| 32 #include "device/bluetooth/bluetooth_device_bluez.h" | |
| 33 #include "device/bluetooth/bluetooth_socket.h" | |
| 34 #include "device/bluetooth/bluetooth_socket_net.h" | |
| 35 #include "device/bluetooth/bluetooth_socket_thread.h" | |
| 36 #include "device/bluetooth/dbus/bluetooth_device_client.h" | |
| 37 #include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" | |
| 38 #include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" | |
| 39 #include "device/bluetooth/dbus/bluez_dbus_manager.h" | |
| 40 #include "net/base/ip_endpoint.h" | |
| 41 #include "net/base/net_errors.h" | |
| 42 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 43 | |
| 44 using device::BluetoothAdapter; | |
| 45 using device::BluetoothDevice; | |
| 46 using device::BluetoothSocketThread; | |
| 47 using device::BluetoothUUID; | |
| 48 | |
| 49 namespace { | |
| 50 | |
| 51 const char kAcceptFailed[] = "Failed to accept connection."; | |
| 52 const char kInvalidUUID[] = "Invalid UUID"; | |
| 53 const char kSocketNotListening[] = "Socket is not listening."; | |
| 54 | |
| 55 } // namespace | |
| 56 | |
| 57 namespace bluez { | |
| 58 | |
| 59 // static | |
| 60 scoped_refptr<BluetoothSocketBlueZ> BluetoothSocketBlueZ::CreateBluetoothSocket( | |
| 61 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, | |
| 62 scoped_refptr<BluetoothSocketThread> socket_thread) { | |
| 63 DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); | |
| 64 | |
| 65 return make_scoped_refptr( | |
| 66 new BluetoothSocketBlueZ(ui_task_runner, socket_thread)); | |
| 67 } | |
| 68 | |
| 69 BluetoothSocketBlueZ::AcceptRequest::AcceptRequest() {} | |
| 70 | |
| 71 BluetoothSocketBlueZ::AcceptRequest::~AcceptRequest() {} | |
| 72 | |
| 73 BluetoothSocketBlueZ::ConnectionRequest::ConnectionRequest() | |
| 74 : accepting(false), cancelled(false) {} | |
| 75 | |
| 76 BluetoothSocketBlueZ::ConnectionRequest::~ConnectionRequest() {} | |
| 77 | |
| 78 BluetoothSocketBlueZ::BluetoothSocketBlueZ( | |
| 79 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, | |
| 80 scoped_refptr<BluetoothSocketThread> socket_thread) | |
| 81 : BluetoothSocketNet(ui_task_runner, socket_thread), profile_(nullptr) {} | |
| 82 | |
| 83 BluetoothSocketBlueZ::~BluetoothSocketBlueZ() { | |
| 84 DCHECK(!profile_); | |
| 85 | |
| 86 if (adapter_.get()) { | |
| 87 adapter_->RemoveObserver(this); | |
| 88 adapter_ = nullptr; | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 void BluetoothSocketBlueZ::Connect( | |
| 93 const BluetoothDeviceBlueZ* device, | |
| 94 const BluetoothUUID& uuid, | |
| 95 SecurityLevel security_level, | |
| 96 const base::Closure& success_callback, | |
| 97 const ErrorCompletionCallback& error_callback) { | |
| 98 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 99 DCHECK(!profile_); | |
| 100 | |
| 101 if (!uuid.IsValid()) { | |
| 102 error_callback.Run(kInvalidUUID); | |
| 103 return; | |
| 104 } | |
| 105 | |
| 106 device_address_ = device->GetAddress(); | |
| 107 device_path_ = device->object_path(); | |
| 108 uuid_ = uuid; | |
| 109 options_.reset(new bluez::BluetoothProfileManagerClient::Options()); | |
| 110 if (security_level == SECURITY_LEVEL_LOW) | |
| 111 options_->require_authentication.reset(new bool(false)); | |
| 112 | |
| 113 adapter_ = device->adapter(); | |
| 114 | |
| 115 RegisterProfile(device->adapter(), success_callback, error_callback); | |
| 116 } | |
| 117 | |
| 118 void BluetoothSocketBlueZ::Listen( | |
| 119 scoped_refptr<BluetoothAdapter> adapter, | |
| 120 SocketType socket_type, | |
| 121 const BluetoothUUID& uuid, | |
| 122 const BluetoothAdapter::ServiceOptions& service_options, | |
| 123 const base::Closure& success_callback, | |
| 124 const ErrorCompletionCallback& error_callback) { | |
| 125 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 126 DCHECK(!profile_); | |
| 127 | |
| 128 if (!uuid.IsValid()) { | |
| 129 error_callback.Run(kInvalidUUID); | |
| 130 return; | |
| 131 } | |
| 132 | |
| 133 adapter_ = adapter; | |
| 134 adapter_->AddObserver(this); | |
| 135 | |
| 136 uuid_ = uuid; | |
| 137 options_.reset(new bluez::BluetoothProfileManagerClient::Options()); | |
| 138 if (service_options.name) | |
| 139 options_->name.reset(new std::string(*service_options.name)); | |
| 140 | |
| 141 switch (socket_type) { | |
| 142 case kRfcomm: | |
| 143 options_->channel.reset( | |
| 144 new uint16_t(service_options.channel ? *service_options.channel : 0)); | |
| 145 break; | |
| 146 case kL2cap: | |
| 147 options_->psm.reset( | |
| 148 new uint16_t(service_options.psm ? *service_options.psm : 0)); | |
| 149 break; | |
| 150 default: | |
| 151 NOTREACHED(); | |
| 152 } | |
| 153 | |
| 154 RegisterProfile(static_cast<BluetoothAdapterBlueZ*>(adapter.get()), | |
| 155 success_callback, error_callback); | |
| 156 } | |
| 157 | |
| 158 void BluetoothSocketBlueZ::Close() { | |
| 159 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 160 | |
| 161 if (profile_) | |
| 162 UnregisterProfile(); | |
| 163 | |
| 164 // In the case below, where an asynchronous task gets posted on the socket | |
| 165 // thread in BluetoothSocketNet::Close, a reference will be held to this | |
| 166 // socket by the callback. This may cause the BluetoothAdapter to outlive | |
| 167 // BluezDBusManager during shutdown if that callback executes too late. | |
| 168 if (adapter_.get()) { | |
| 169 adapter_->RemoveObserver(this); | |
| 170 adapter_ = nullptr; | |
| 171 } | |
| 172 | |
| 173 if (!device_path_.value().empty()) { | |
| 174 BluetoothSocketNet::Close(); | |
| 175 } else { | |
| 176 DoCloseListening(); | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 void BluetoothSocketBlueZ::Disconnect(const base::Closure& callback) { | |
| 181 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 182 | |
| 183 if (profile_) | |
| 184 UnregisterProfile(); | |
| 185 | |
| 186 if (!device_path_.value().empty()) { | |
| 187 BluetoothSocketNet::Disconnect(callback); | |
| 188 } else { | |
| 189 DoCloseListening(); | |
| 190 callback.Run(); | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 void BluetoothSocketBlueZ::Accept( | |
| 195 const AcceptCompletionCallback& success_callback, | |
| 196 const ErrorCompletionCallback& error_callback) { | |
| 197 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 198 | |
| 199 if (!device_path_.value().empty()) { | |
| 200 error_callback.Run(kSocketNotListening); | |
| 201 return; | |
| 202 } | |
| 203 | |
| 204 // Only one pending accept at a time | |
| 205 if (accept_request_.get()) { | |
| 206 error_callback.Run(net::ErrorToString(net::ERR_IO_PENDING)); | |
| 207 return; | |
| 208 } | |
| 209 | |
| 210 accept_request_.reset(new AcceptRequest); | |
| 211 accept_request_->success_callback = success_callback; | |
| 212 accept_request_->error_callback = error_callback; | |
| 213 | |
| 214 if (connection_request_queue_.size() >= 1) { | |
| 215 AcceptConnectionRequest(); | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 void BluetoothSocketBlueZ::RegisterProfile( | |
| 220 BluetoothAdapterBlueZ* adapter, | |
| 221 const base::Closure& success_callback, | |
| 222 const ErrorCompletionCallback& error_callback) { | |
| 223 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 224 DCHECK(!profile_); | |
| 225 DCHECK(adapter); | |
| 226 | |
| 227 // If the adapter is not present, this is a listening socket and the | |
| 228 // adapter isn't running yet. Report success and carry on; | |
| 229 // the profile will be registered when the daemon becomes available. | |
| 230 if (!adapter->IsPresent()) { | |
| 231 VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() | |
| 232 << ": Delaying profile registration."; | |
| 233 base::MessageLoop::current()->PostTask(FROM_HERE, success_callback); | |
| 234 return; | |
| 235 } | |
| 236 | |
| 237 VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() | |
| 238 << ": Acquiring profile."; | |
| 239 | |
| 240 adapter->UseProfile(uuid_, device_path_, *options_, this, | |
| 241 base::Bind(&BluetoothSocketBlueZ::OnRegisterProfile, this, | |
| 242 success_callback, error_callback), | |
| 243 base::Bind(&BluetoothSocketBlueZ::OnRegisterProfileError, | |
| 244 this, error_callback)); | |
| 245 } | |
| 246 | |
| 247 void BluetoothSocketBlueZ::OnRegisterProfile( | |
| 248 const base::Closure& success_callback, | |
| 249 const ErrorCompletionCallback& error_callback, | |
| 250 BluetoothAdapterProfileBlueZ* profile) { | |
| 251 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 252 DCHECK(!profile_); | |
| 253 | |
| 254 profile_ = profile; | |
| 255 | |
| 256 if (device_path_.value().empty()) { | |
| 257 VLOG(1) << uuid_.canonical_value() << ": Profile registered."; | |
| 258 success_callback.Run(); | |
| 259 return; | |
| 260 } | |
| 261 | |
| 262 VLOG(1) << uuid_.canonical_value() << ": Got profile, connecting to " | |
| 263 << device_path_.value(); | |
| 264 | |
| 265 bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( | |
| 266 device_path_, uuid_.canonical_value(), | |
| 267 base::Bind(&BluetoothSocketBlueZ::OnConnectProfile, this, | |
| 268 success_callback), | |
| 269 base::Bind(&BluetoothSocketBlueZ::OnConnectProfileError, this, | |
| 270 error_callback)); | |
| 271 } | |
| 272 | |
| 273 void BluetoothSocketBlueZ::OnRegisterProfileError( | |
| 274 const ErrorCompletionCallback& error_callback, | |
| 275 const std::string& error_message) { | |
| 276 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 277 | |
| 278 LOG(WARNING) << uuid_.canonical_value() | |
| 279 << ": Failed to register profile: " << error_message; | |
| 280 error_callback.Run(error_message); | |
| 281 } | |
| 282 | |
| 283 void BluetoothSocketBlueZ::OnConnectProfile( | |
| 284 const base::Closure& success_callback) { | |
| 285 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 286 DCHECK(profile_); | |
| 287 | |
| 288 VLOG(1) << profile_->object_path().value() << ": Profile connected."; | |
| 289 UnregisterProfile(); | |
| 290 success_callback.Run(); | |
| 291 } | |
| 292 | |
| 293 void BluetoothSocketBlueZ::OnConnectProfileError( | |
| 294 const ErrorCompletionCallback& error_callback, | |
| 295 const std::string& error_name, | |
| 296 const std::string& error_message) { | |
| 297 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 298 DCHECK(profile_); | |
| 299 | |
| 300 LOG(WARNING) << profile_->object_path().value() | |
| 301 << ": Failed to connect profile: " << error_name << ": " | |
| 302 << error_message; | |
| 303 UnregisterProfile(); | |
| 304 error_callback.Run(error_message); | |
| 305 } | |
| 306 | |
| 307 void BluetoothSocketBlueZ::AdapterPresentChanged(BluetoothAdapter* adapter, | |
| 308 bool present) { | |
| 309 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 310 | |
| 311 if (!present) { | |
| 312 // Adapter removed, we can't use the profile anymore. | |
| 313 UnregisterProfile(); | |
| 314 return; | |
| 315 } | |
| 316 | |
| 317 DCHECK(!profile_); | |
| 318 | |
| 319 VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value() | |
| 320 << ": Acquiring profile."; | |
| 321 | |
| 322 static_cast<BluetoothAdapterBlueZ*>(adapter)->UseProfile( | |
| 323 uuid_, device_path_, *options_, this, | |
| 324 base::Bind(&BluetoothSocketBlueZ::OnInternalRegisterProfile, this), | |
| 325 base::Bind(&BluetoothSocketBlueZ::OnInternalRegisterProfileError, this)); | |
| 326 } | |
| 327 | |
| 328 void BluetoothSocketBlueZ::OnInternalRegisterProfile( | |
| 329 BluetoothAdapterProfileBlueZ* profile) { | |
| 330 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 331 DCHECK(!profile_); | |
| 332 | |
| 333 profile_ = profile; | |
| 334 | |
| 335 VLOG(1) << uuid_.canonical_value() << ": Profile re-registered"; | |
| 336 } | |
| 337 | |
| 338 void BluetoothSocketBlueZ::OnInternalRegisterProfileError( | |
| 339 const std::string& error_message) { | |
| 340 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 341 | |
| 342 LOG(WARNING) << "Failed to re-register profile: " << error_message; | |
| 343 } | |
| 344 | |
| 345 void BluetoothSocketBlueZ::Released() { | |
| 346 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 347 DCHECK(profile_); | |
| 348 | |
| 349 VLOG(1) << profile_->object_path().value() << ": Release"; | |
| 350 } | |
| 351 | |
| 352 void BluetoothSocketBlueZ::NewConnection( | |
| 353 const dbus::ObjectPath& device_path, | |
| 354 std::unique_ptr<dbus::FileDescriptor> fd, | |
| 355 const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, | |
| 356 const ConfirmationCallback& callback) { | |
| 357 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 358 | |
| 359 VLOG(1) << uuid_.canonical_value() | |
| 360 << ": New connection from device: " << device_path.value(); | |
| 361 | |
| 362 if (!device_path_.value().empty()) { | |
| 363 DCHECK(device_path_ == device_path); | |
| 364 | |
| 365 socket_thread()->task_runner()->PostTask( | |
| 366 FROM_HERE, | |
| 367 base::Bind(&BluetoothSocketBlueZ::DoNewConnection, this, device_path_, | |
| 368 base::Passed(&fd), options, callback)); | |
| 369 } else { | |
| 370 linked_ptr<ConnectionRequest> request(new ConnectionRequest()); | |
| 371 request->device_path = device_path; | |
| 372 request->fd = std::move(fd); | |
| 373 request->options = options; | |
| 374 request->callback = callback; | |
| 375 | |
| 376 connection_request_queue_.push(request); | |
| 377 VLOG(1) << uuid_.canonical_value() << ": Connection is now pending."; | |
| 378 if (accept_request_) { | |
| 379 AcceptConnectionRequest(); | |
| 380 } | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 void BluetoothSocketBlueZ::RequestDisconnection( | |
| 385 const dbus::ObjectPath& device_path, | |
| 386 const ConfirmationCallback& callback) { | |
| 387 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 388 DCHECK(profile_); | |
| 389 | |
| 390 VLOG(1) << profile_->object_path().value() << ": Request disconnection"; | |
| 391 callback.Run(SUCCESS); | |
| 392 } | |
| 393 | |
| 394 void BluetoothSocketBlueZ::Cancel() { | |
| 395 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 396 DCHECK(profile_); | |
| 397 | |
| 398 VLOG(1) << profile_->object_path().value() << ": Cancel"; | |
| 399 | |
| 400 if (!connection_request_queue_.size()) | |
| 401 return; | |
| 402 | |
| 403 // If the front request is being accepted mark it as cancelled, otherwise | |
| 404 // just pop it from the queue. | |
| 405 linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); | |
| 406 if (!request->accepting) { | |
| 407 request->cancelled = true; | |
| 408 } else { | |
| 409 connection_request_queue_.pop(); | |
| 410 } | |
| 411 } | |
| 412 | |
| 413 void BluetoothSocketBlueZ::AcceptConnectionRequest() { | |
| 414 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 415 DCHECK(accept_request_.get()); | |
| 416 DCHECK(connection_request_queue_.size() >= 1); | |
| 417 DCHECK(profile_); | |
| 418 | |
| 419 VLOG(1) << profile_->object_path().value() | |
| 420 << ": Accepting pending connection."; | |
| 421 | |
| 422 linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); | |
| 423 request->accepting = true; | |
| 424 | |
| 425 BluetoothDeviceBlueZ* device = | |
| 426 static_cast<BluetoothAdapterBlueZ*>(adapter_.get()) | |
| 427 ->GetDeviceWithPath(request->device_path); | |
| 428 DCHECK(device); | |
| 429 | |
| 430 scoped_refptr<BluetoothSocketBlueZ> client_socket = | |
| 431 BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner(), | |
| 432 socket_thread()); | |
| 433 | |
| 434 client_socket->device_address_ = device->GetAddress(); | |
| 435 client_socket->device_path_ = request->device_path; | |
| 436 client_socket->uuid_ = uuid_; | |
| 437 | |
| 438 socket_thread()->task_runner()->PostTask( | |
| 439 FROM_HERE, | |
| 440 base::Bind(&BluetoothSocketBlueZ::DoNewConnection, client_socket, | |
| 441 request->device_path, base::Passed(&request->fd), | |
| 442 request->options, | |
| 443 base::Bind(&BluetoothSocketBlueZ::OnNewConnection, this, | |
| 444 client_socket, request->callback))); | |
| 445 } | |
| 446 | |
| 447 void BluetoothSocketBlueZ::DoNewConnection( | |
| 448 const dbus::ObjectPath& device_path, | |
| 449 std::unique_ptr<dbus::FileDescriptor> fd, | |
| 450 const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, | |
| 451 const ConfirmationCallback& callback) { | |
| 452 DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread()); | |
| 453 base::ThreadRestrictions::AssertIOAllowed(); | |
| 454 fd->CheckValidity(); | |
| 455 | |
| 456 VLOG(1) << uuid_.canonical_value() << ": Validity check complete."; | |
| 457 if (!fd->is_valid()) { | |
| 458 LOG(WARNING) << uuid_.canonical_value() << " :" << fd->value() | |
| 459 << ": Invalid file descriptor received from Bluetooth Daemon."; | |
| 460 ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED)); | |
| 461 return; | |
| 462 } | |
| 463 | |
| 464 if (tcp_socket()) { | |
| 465 LOG(WARNING) << uuid_.canonical_value() << ": Already connected"; | |
| 466 ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED)); | |
| 467 return; | |
| 468 } | |
| 469 | |
| 470 ResetTCPSocket(); | |
| 471 | |
| 472 // Note: We don't have a meaningful |IPEndPoint|, but that is ok since the | |
| 473 // TCPSocket implementation does not actually require one. | |
| 474 int net_result = | |
| 475 tcp_socket()->AdoptConnectedSocket(fd->value(), net::IPEndPoint()); | |
| 476 if (net_result != net::OK) { | |
| 477 LOG(WARNING) << uuid_.canonical_value() << ": Error adopting socket: " | |
| 478 << std::string(net::ErrorToString(net_result)); | |
| 479 ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED)); | |
| 480 return; | |
| 481 } | |
| 482 | |
| 483 VLOG(2) << uuid_.canonical_value() | |
| 484 << ": Taking descriptor, confirming success."; | |
| 485 fd->TakeValue(); | |
| 486 ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, SUCCESS)); | |
| 487 } | |
| 488 | |
| 489 void BluetoothSocketBlueZ::OnNewConnection( | |
| 490 scoped_refptr<BluetoothSocket> socket, | |
| 491 const ConfirmationCallback& callback, | |
| 492 Status status) { | |
| 493 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 494 DCHECK(accept_request_.get()); | |
| 495 DCHECK(connection_request_queue_.size() >= 1); | |
| 496 | |
| 497 linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); | |
| 498 if (status == SUCCESS && !request->cancelled) { | |
| 499 BluetoothDeviceBlueZ* device = | |
| 500 static_cast<BluetoothAdapterBlueZ*>(adapter_.get()) | |
| 501 ->GetDeviceWithPath(request->device_path); | |
| 502 DCHECK(device); | |
| 503 | |
| 504 accept_request_->success_callback.Run(device, socket); | |
| 505 } else { | |
| 506 accept_request_->error_callback.Run(kAcceptFailed); | |
| 507 } | |
| 508 | |
| 509 accept_request_.reset(nullptr); | |
| 510 connection_request_queue_.pop(); | |
| 511 | |
| 512 callback.Run(status); | |
| 513 } | |
| 514 | |
| 515 void BluetoothSocketBlueZ::DoCloseListening() { | |
| 516 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 517 | |
| 518 if (accept_request_) { | |
| 519 accept_request_->error_callback.Run( | |
| 520 net::ErrorToString(net::ERR_CONNECTION_CLOSED)); | |
| 521 accept_request_.reset(nullptr); | |
| 522 } | |
| 523 | |
| 524 while (connection_request_queue_.size() > 0) { | |
| 525 linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); | |
| 526 request->callback.Run(REJECTED); | |
| 527 connection_request_queue_.pop(); | |
| 528 } | |
| 529 } | |
| 530 | |
| 531 void BluetoothSocketBlueZ::UnregisterProfile() { | |
| 532 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); | |
| 533 DCHECK(profile_); | |
| 534 | |
| 535 VLOG(1) << profile_->object_path().value() << ": Release profile"; | |
| 536 | |
| 537 static_cast<BluetoothAdapterBlueZ*>(adapter_.get()) | |
| 538 ->ReleaseProfile(device_path_, profile_); | |
| 539 profile_ = nullptr; | |
| 540 } | |
| 541 | |
| 542 } // namespace bluez | |
| OLD | NEW |