OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/bluetooth/bluetooth_device_experimental_chromeos.h" | 5 #include "device/bluetooth/bluetooth_device_experimental_chromeos.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "chromeos/dbus/dbus_thread_manager.h" | 8 #include "chromeos/dbus/dbus_thread_manager.h" |
9 #include "chromeos/dbus/experimental_bluetooth_adapter_client.h" | 9 #include "chromeos/dbus/experimental_bluetooth_adapter_client.h" |
10 #include "chromeos/dbus/experimental_bluetooth_agent_manager_client.h" | 10 #include "chromeos/dbus/experimental_bluetooth_agent_manager_client.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 | 67 |
68 return properties->address.value(); | 68 return properties->address.value(); |
69 } | 69 } |
70 | 70 |
71 bool BluetoothDeviceExperimentalChromeOS::IsPaired() const { | 71 bool BluetoothDeviceExperimentalChromeOS::IsPaired() const { |
72 ExperimentalBluetoothDeviceClient::Properties* properties = | 72 ExperimentalBluetoothDeviceClient::Properties* properties = |
73 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> | 73 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
74 GetProperties(object_path_); | 74 GetProperties(object_path_); |
75 DCHECK(properties); | 75 DCHECK(properties); |
76 | 76 |
77 return properties->paired.value(); | 77 // Trusted devices are devices that don't support pairing but that the |
| 78 // user has explicitly connected; it makes no sense for UI purposes to |
| 79 // treat them differently from each other. |
| 80 return properties->paired.value() || properties->trusted.value(); |
78 } | 81 } |
79 | 82 |
80 bool BluetoothDeviceExperimentalChromeOS::IsConnected() const { | 83 bool BluetoothDeviceExperimentalChromeOS::IsConnected() const { |
81 ExperimentalBluetoothDeviceClient::Properties* properties = | 84 ExperimentalBluetoothDeviceClient::Properties* properties = |
82 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> | 85 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
83 GetProperties(object_path_); | 86 GetProperties(object_path_); |
84 DCHECK(properties); | 87 DCHECK(properties); |
85 | 88 |
86 return properties->connected.value(); | 89 return properties->connected.value(); |
87 } | 90 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 } | 135 } |
133 | 136 |
134 void BluetoothDeviceExperimentalChromeOS::Connect( | 137 void BluetoothDeviceExperimentalChromeOS::Connect( |
135 BluetoothDevice::PairingDelegate* pairing_delegate, | 138 BluetoothDevice::PairingDelegate* pairing_delegate, |
136 const base::Closure& callback, | 139 const base::Closure& callback, |
137 const ConnectErrorCallback& error_callback) { | 140 const ConnectErrorCallback& error_callback) { |
138 ++num_connecting_calls_; | 141 ++num_connecting_calls_; |
139 VLOG(1) << object_path_.value() << ": Connecting, " << num_connecting_calls_ | 142 VLOG(1) << object_path_.value() << ": Connecting, " << num_connecting_calls_ |
140 << " in progress"; | 143 << " in progress"; |
141 | 144 |
142 if (IsPaired() || IsConnected() || !pairing_delegate) { | 145 if (IsPaired() || IsConnected() || !pairing_delegate || !IsPairable()) { |
143 // No need to pair, skip straight to connection. | 146 // No need to pair, or unable to, skip straight to connection. |
144 ConnectInternal(callback, error_callback); | 147 ConnectInternal(callback, error_callback); |
145 } else { | 148 } else { |
146 // Initiate high-security connection with pairing. | 149 // Initiate high-security connection with pairing. |
147 DCHECK(!pairing_delegate_); | 150 DCHECK(!pairing_delegate_); |
148 DCHECK(agent_.get() == NULL); | 151 DCHECK(agent_.get() == NULL); |
149 | 152 |
150 pairing_delegate_ = pairing_delegate; | 153 pairing_delegate_ = pairing_delegate; |
151 | 154 |
152 // The agent path is relatively meaningless since BlueZ only supports | 155 // The agent path is relatively meaningless since BlueZ only supports |
153 // one per application at a time. | 156 // one per application at a time. |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 error_callback)); | 392 error_callback)); |
390 } | 393 } |
391 | 394 |
392 void BluetoothDeviceExperimentalChromeOS::OnConnect( | 395 void BluetoothDeviceExperimentalChromeOS::OnConnect( |
393 const base::Closure& callback) { | 396 const base::Closure& callback) { |
394 --num_connecting_calls_; | 397 --num_connecting_calls_; |
395 DCHECK(num_connecting_calls_ >= 0); | 398 DCHECK(num_connecting_calls_ >= 0); |
396 VLOG(1) << object_path_.value() << ": Connected, " << num_connecting_calls_ | 399 VLOG(1) << object_path_.value() << ": Connected, " << num_connecting_calls_ |
397 << " still in progress"; | 400 << " still in progress"; |
398 | 401 |
| 402 SetTrusted(); |
| 403 |
399 callback.Run(); | 404 callback.Run(); |
400 } | 405 } |
401 | 406 |
402 void BluetoothDeviceExperimentalChromeOS::OnConnectError( | 407 void BluetoothDeviceExperimentalChromeOS::OnConnectError( |
403 const ConnectErrorCallback& error_callback, | 408 const ConnectErrorCallback& error_callback, |
404 const std::string& error_name, | 409 const std::string& error_name, |
405 const std::string& error_message) { | 410 const std::string& error_message) { |
406 --num_connecting_calls_; | 411 --num_connecting_calls_; |
407 DCHECK(num_connecting_calls_ >= 0); | 412 DCHECK(num_connecting_calls_ >= 0); |
408 LOG(WARNING) << object_path_.value() << ": Failed to connect device: " | 413 LOG(WARNING) << object_path_.value() << ": Failed to connect device: " |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 if (error_name == bluetooth_adapter::kErrorAlreadyExists) | 463 if (error_name == bluetooth_adapter::kErrorAlreadyExists) |
459 error_code = ERROR_INPROGRESS; | 464 error_code = ERROR_INPROGRESS; |
460 | 465 |
461 error_callback.Run(error_code); | 466 error_callback.Run(error_code); |
462 } | 467 } |
463 | 468 |
464 void BluetoothDeviceExperimentalChromeOS::OnPair( | 469 void BluetoothDeviceExperimentalChromeOS::OnPair( |
465 const base::Closure& callback, | 470 const base::Closure& callback, |
466 const ConnectErrorCallback& error_callback) { | 471 const ConnectErrorCallback& error_callback) { |
467 VLOG(1) << object_path_.value() << ": Paired"; | 472 VLOG(1) << object_path_.value() << ": Paired"; |
468 | |
469 // Now that we're paired, we need to set the device as trusted so that | |
470 // incoming connections will be accepted. This should only ever fail if | |
471 // the device is removed mid-pairing, so do it in the background while | |
472 // we connect and don't worry about errors. | |
473 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> | |
474 GetProperties(object_path_)->trusted.Set( | |
475 true, | |
476 base::Bind( | |
477 &BluetoothDeviceExperimentalChromeOS::OnSetTrusted, | |
478 weak_ptr_factory_.GetWeakPtr())); | |
479 | |
480 UnregisterAgent(); | 473 UnregisterAgent(); |
481 | 474 SetTrusted(); |
482 // Now we can connect to the device! | |
483 ConnectInternal(callback, error_callback); | 475 ConnectInternal(callback, error_callback); |
484 } | 476 } |
485 | 477 |
486 void BluetoothDeviceExperimentalChromeOS::OnPairError( | 478 void BluetoothDeviceExperimentalChromeOS::OnPairError( |
487 const ConnectErrorCallback& error_callback, | 479 const ConnectErrorCallback& error_callback, |
488 const std::string& error_name, | 480 const std::string& error_name, |
489 const std::string& error_message) { | 481 const std::string& error_message) { |
490 --num_connecting_calls_; | 482 --num_connecting_calls_; |
491 DCHECK(num_connecting_calls_ >= 0); | 483 DCHECK(num_connecting_calls_ >= 0); |
492 LOG(WARNING) << object_path_.value() << ": Failed to pair device: " | 484 LOG(WARNING) << object_path_.value() << ": Failed to pair device: " |
(...skipping 20 matching lines...) Expand all Loading... |
513 error_callback.Run(error_code); | 505 error_callback.Run(error_code); |
514 } | 506 } |
515 | 507 |
516 void BluetoothDeviceExperimentalChromeOS::OnCancelPairingError( | 508 void BluetoothDeviceExperimentalChromeOS::OnCancelPairingError( |
517 const std::string& error_name, | 509 const std::string& error_name, |
518 const std::string& error_message) { | 510 const std::string& error_message) { |
519 LOG(WARNING) << object_path_.value() << ": Failed to cancel pairing: " | 511 LOG(WARNING) << object_path_.value() << ": Failed to cancel pairing: " |
520 << error_name << ": " << error_message; | 512 << error_name << ": " << error_message; |
521 } | 513 } |
522 | 514 |
| 515 void BluetoothDeviceExperimentalChromeOS::SetTrusted() { |
| 516 // Unconditionally send the property change, rather than checking the value |
| 517 // first; there's no harm in doing this and it solves any race conditions |
| 518 // with the property becoming true or false and this call happening before |
| 519 // we get the D-Bus signal about the earlier change. |
| 520 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()-> |
| 521 GetProperties(object_path_)->trusted.Set( |
| 522 true, |
| 523 base::Bind( |
| 524 &BluetoothDeviceExperimentalChromeOS::OnSetTrusted, |
| 525 weak_ptr_factory_.GetWeakPtr())); |
| 526 } |
| 527 |
523 void BluetoothDeviceExperimentalChromeOS::OnSetTrusted(bool success) { | 528 void BluetoothDeviceExperimentalChromeOS::OnSetTrusted(bool success) { |
524 LOG_IF(WARNING, !success) << object_path_.value() | 529 LOG_IF(WARNING, !success) << object_path_.value() |
525 << ": Failed to set device as trusted"; | 530 << ": Failed to set device as trusted"; |
526 } | 531 } |
527 | 532 |
528 void BluetoothDeviceExperimentalChromeOS::UnregisterAgent() { | 533 void BluetoothDeviceExperimentalChromeOS::UnregisterAgent() { |
529 DCHECK(agent_.get()); | 534 DCHECK(agent_.get()); |
530 DCHECK(pairing_delegate_); | 535 DCHECK(pairing_delegate_); |
531 | 536 |
532 DCHECK(pincode_callback_.is_null()); | 537 DCHECK(pincode_callback_.is_null()); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 if (!confirmation_callback_.is_null()) { | 605 if (!confirmation_callback_.is_null()) { |
601 confirmation_callback_.Run(status); | 606 confirmation_callback_.Run(status); |
602 confirmation_callback_.Reset(); | 607 confirmation_callback_.Reset(); |
603 callback_run = true; | 608 callback_run = true; |
604 } | 609 } |
605 | 610 |
606 return callback_run; | 611 return callback_run; |
607 } | 612 } |
608 | 613 |
609 } // namespace chromeos | 614 } // namespace chromeos |
OLD | NEW |