OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_chromeos.h" | 5 #include "device/bluetooth/bluetooth_device_chromeos.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... | |
39 using device::BluetoothSocket; | 39 using device::BluetoothSocket; |
40 | 40 |
41 namespace chromeos { | 41 namespace chromeos { |
42 | 42 |
43 BluetoothDeviceChromeOS::BluetoothDeviceChromeOS( | 43 BluetoothDeviceChromeOS::BluetoothDeviceChromeOS( |
44 BluetoothAdapterChromeOS* adapter) | 44 BluetoothAdapterChromeOS* adapter) |
45 : BluetoothDevice(), | 45 : BluetoothDevice(), |
46 adapter_(adapter), | 46 adapter_(adapter), |
47 pairing_delegate_(NULL), | 47 pairing_delegate_(NULL), |
48 connecting_applications_counter_(0), | 48 connecting_applications_counter_(0), |
49 service_records_loaded_(false), | |
49 weak_ptr_factory_(this) { | 50 weak_ptr_factory_(this) { |
50 } | 51 } |
51 | 52 |
52 BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() { | 53 BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() { |
53 } | 54 } |
54 | 55 |
55 bool BluetoothDeviceChromeOS::IsPaired() const { | 56 bool BluetoothDeviceChromeOS::IsPaired() const { |
56 return !object_path_.value().empty(); | 57 return !object_path_.value().empty(); |
57 } | 58 } |
58 | 59 |
59 const BluetoothDevice::ServiceList& | 60 const BluetoothDevice::ServiceList& |
60 BluetoothDeviceChromeOS::GetServices() const { | 61 BluetoothDeviceChromeOS::GetServices() const { |
61 return service_uuids_; | 62 return service_uuids_; |
62 } | 63 } |
63 | 64 |
64 void BluetoothDeviceChromeOS::GetServiceRecords( | 65 void BluetoothDeviceChromeOS::GetServiceRecords( |
65 const ServiceRecordsCallback& callback, | 66 const ServiceRecordsCallback& callback, |
66 const ErrorCallback& error_callback) { | 67 const ErrorCallback& error_callback) { |
67 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> | 68 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> |
68 DiscoverServices( | 69 DiscoverServices( |
69 object_path_, | 70 object_path_, |
70 "", // empty pattern to browse all services | 71 "", // empty pattern to browse all services |
71 base::Bind(&BluetoothDeviceChromeOS::CollectServiceRecordsCallback, | 72 base::Bind(&BluetoothDeviceChromeOS::CollectServiceRecordsCallback, |
72 weak_ptr_factory_.GetWeakPtr(), | 73 weak_ptr_factory_.GetWeakPtr(), |
73 callback, | 74 callback, |
74 error_callback)); | 75 base::Bind( |
76 &BluetoothDeviceChromeOS::OnGetServiceRecordsError, | |
77 weak_ptr_factory_.GetWeakPtr(), | |
78 callback, | |
79 error_callback))); | |
75 } | 80 } |
76 | 81 |
77 bool BluetoothDeviceChromeOS::ProvidesServiceWithUUID( | 82 bool BluetoothDeviceChromeOS::ProvidesServiceWithUUID( |
78 const std::string& uuid) const { | 83 const std::string& uuid) const { |
79 const BluetoothDevice::ServiceList& services = GetServices(); | 84 const BluetoothDevice::ServiceList& services = GetServices(); |
80 for (BluetoothDevice::ServiceList::const_iterator iter = services.begin(); | 85 for (BluetoothDevice::ServiceList::const_iterator iter = services.begin(); |
81 iter != services.end(); | 86 iter != services.end(); |
82 ++iter) { | 87 ++iter) { |
83 if (device::bluetooth_utils::CanonicalUuid(*iter) == uuid) | 88 if (device::bluetooth_utils::CanonicalUuid(*iter) == uuid) |
84 return true; | 89 return true; |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 | 367 |
363 // Mark the device trusted so it can connect to us automatically, and | 368 // Mark the device trusted so it can connect to us automatically, and |
364 // we can connect after rebooting. This information is part of the | 369 // we can connect after rebooting. This information is part of the |
365 // pairing information of the device, and is unique to the combination | 370 // pairing information of the device, and is unique to the combination |
366 // of our bluetooth address and the device's bluetooth address. A | 371 // of our bluetooth address and the device's bluetooth address. A |
367 // different host needs a new pairing, so it's not useful to sync. | 372 // different host needs a new pairing, so it's not useful to sync. |
368 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> | 373 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> |
369 GetProperties(object_path_)->trusted.Set( | 374 GetProperties(object_path_)->trusted.Set( |
370 true, | 375 true, |
371 base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted, | 376 base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted, |
372 weak_ptr_factory_.GetWeakPtr(), | 377 weak_ptr_factory_.GetWeakPtr())); |
373 callback, | |
374 base::Bind(error_callback, | |
375 ERROR_UNKNOWN))); | |
376 // TODO(deymo): Replace ERROR_UNKNOWN with an appropriate new constant. | |
377 | 378 |
378 // Connect application-layer protocols. | 379 // In parallel with the |trusted| property change, call GetServiceRecords to |
379 ConnectApplications(callback, error_callback); | 380 // retrieve the SDP from the device and then, either on success or failure, |
381 // call ConnectApplications. | |
382 GetServiceRecords( | |
383 base::Bind(&BluetoothDeviceChromeOS::OnInitialGetServiceRecords, | |
384 weak_ptr_factory_.GetWeakPtr(), | |
385 callback, | |
386 error_callback), | |
387 base::Bind(&BluetoothDeviceChromeOS::OnInitialGetServiceRecordsError, | |
388 weak_ptr_factory_.GetWeakPtr(), | |
389 callback, | |
390 error_callback)); | |
380 } | 391 } |
381 | 392 |
382 void BluetoothDeviceChromeOS::OnCreateDeviceError( | 393 void BluetoothDeviceChromeOS::OnCreateDeviceError( |
383 const ConnectErrorCallback& error_callback, | 394 const ConnectErrorCallback& error_callback, |
384 const std::string& error_name, | 395 const std::string& error_name, |
385 const std::string& error_message) { | 396 const std::string& error_message) { |
386 // The default |error_code| is an unknown error. | 397 // The default |error_code| is an unknown error. |
387 ConnectErrorCode error_code = ERROR_UNKNOWN; | 398 ConnectErrorCode error_code = ERROR_UNKNOWN; |
388 | 399 |
389 // Report any error in the log, even if we know the possible source of it. | 400 // Report any error in the log, even if we know the possible source of it. |
(...skipping 19 matching lines...) Expand all Loading... | |
409 const ServiceRecordsCallback& callback, | 420 const ServiceRecordsCallback& callback, |
410 const ErrorCallback& error_callback, | 421 const ErrorCallback& error_callback, |
411 const dbus::ObjectPath& device_path, | 422 const dbus::ObjectPath& device_path, |
412 const BluetoothDeviceClient::ServiceMap& service_map, | 423 const BluetoothDeviceClient::ServiceMap& service_map, |
413 bool success) { | 424 bool success) { |
414 if (!success) { | 425 if (!success) { |
415 error_callback.Run(); | 426 error_callback.Run(); |
416 return; | 427 return; |
417 } | 428 } |
418 | 429 |
419 ScopedVector<BluetoothServiceRecord> records; | 430 // Update the cache. No other thread is executing a GetServiceRecords |
431 // callback, so it is safe to delete the previous objects here. | |
432 service_records_.clear(); | |
433 // TODO(deymo): Perhaps don't update the cache if the new SDP information is | |
434 // empty and we had something before. Some devices only answer this | |
435 // information while paired, and this callback could be called in any order if | |
436 // several calls to GetServiceRecords are made while initial pairing with the | |
437 // device. This requires more investigation. | |
420 for (BluetoothDeviceClient::ServiceMap::const_iterator i = | 438 for (BluetoothDeviceClient::ServiceMap::const_iterator i = |
421 service_map.begin(); i != service_map.end(); ++i) { | 439 service_map.begin(); i != service_map.end(); ++i) { |
422 records.push_back( | 440 service_records_.push_back( |
423 new BluetoothServiceRecordChromeOS(address(), i->second)); | 441 new BluetoothServiceRecordChromeOS(address(), i->second)); |
424 } | 442 } |
425 callback.Run(records); | 443 service_records_loaded_ = true; |
444 OnServiceRecordsChanged(); | |
445 | |
446 callback.Run(service_records_); | |
426 } | 447 } |
427 | 448 |
428 void BluetoothDeviceChromeOS::OnSetTrusted(const base::Closure& callback, | 449 void BluetoothDeviceChromeOS::OnServiceRecordsChanged(void) { |
429 const ErrorCallback& error_callback, | 450 // Update the BluetoothDevice::connectable_ property. |
430 bool success) { | 451 bool hid_normally_connectable = true; |
431 if (success) { | 452 bool hid_reconnect_initiate = true; |
432 callback.Run(); | 453 for (ServiceRecordList::const_iterator it = service_records_.begin(); |
454 it != service_records_.end(); ++it) { | |
455 if ((*it)->SupportsHid()) { | |
456 hid_normally_connectable = | |
457 hid_normally_connectable && (*it)->hid_normally_connectable(); | |
458 hid_reconnect_initiate = | |
459 hid_reconnect_initiate && (*it)->hid_reconnect_initiate(); | |
460 } | |
461 } | |
462 // The Bluetooth HID spec states that if HIDNormallyConnectable or | |
463 // HIDReconnectInitiate are not present in a HID profile, the value is false. | |
464 // Nevertheless, a device with both properties in false can't reconnect to the | |
465 // adapter and can't be reconnected from the adapter. To avoid problems with | |
466 // devices that don't export this properties we asume they are connectable. | |
467 connectable_ = hid_normally_connectable || !hid_reconnect_initiate; | |
468 DVLOG(1) << "ServiceRecordsUpdated for " << address_ | |
469 << ": connectable = " << connectable_; | |
470 } | |
471 | |
472 void BluetoothDeviceChromeOS::OnSetTrusted(bool success) { | |
473 if (!success) { | |
474 LOG(WARNING) << "Failed to set device as trusted: " << address_; | |
475 } | |
keybuk
2013/02/22 23:50:03
nit: use LOG_IF(WARNING, !success) instead
deymo
2013/02/23 00:43:16
Done.
| |
476 } | |
477 | |
478 void BluetoothDeviceChromeOS::OnInitialGetServiceRecords( | |
479 const base::Closure& callback, | |
480 const ConnectErrorCallback& error_callback, | |
481 const ServiceRecordList& list) { | |
482 // Connect application-layer protocols. | |
483 ConnectApplications(callback, error_callback); | |
484 } | |
485 | |
486 void BluetoothDeviceChromeOS::OnInitialGetServiceRecordsError( | |
487 const base::Closure& callback, | |
488 const ConnectErrorCallback& error_callback) { | |
489 // Ignore the error retrieving the service records and continue. | |
490 LOG(WARNING) << "Error retrieving SDP for " << address_ << " after pairing."; | |
491 // Connect application-layer protocols. | |
492 ConnectApplications(callback, error_callback); | |
493 } | |
494 | |
495 void BluetoothDeviceChromeOS::OnGetServiceRecordsError( | |
496 const ServiceRecordsCallback& callback, | |
497 const ErrorCallback& error_callback) { | |
498 if (service_records_loaded_) { | |
499 callback.Run(service_records_); | |
433 } else { | 500 } else { |
434 LOG(WARNING) << "Failed to set device as trusted: " << address_; | |
435 error_callback.Run(); | 501 error_callback.Run(); |
436 } | 502 } |
437 } | 503 } |
438 | 504 |
439 void BluetoothDeviceChromeOS::ConnectApplications( | 505 void BluetoothDeviceChromeOS::ConnectApplications( |
440 const base::Closure& callback, | 506 const base::Closure& callback, |
441 const ConnectErrorCallback& error_callback) { | 507 const ConnectErrorCallback& error_callback) { |
442 // Introspect the device object to determine supported applications. | 508 // Introspect the device object to determine supported applications. |
443 DBusThreadManager::Get()->GetIntrospectableClient()-> | 509 DBusThreadManager::Get()->GetIntrospectableClient()-> |
444 Introspect(bluetooth_device::kBluetoothDeviceServiceName, | 510 Introspect(bluetooth_device::kBluetoothDeviceServiceName, |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 } | 808 } |
743 | 809 |
744 | 810 |
745 // static | 811 // static |
746 BluetoothDeviceChromeOS* BluetoothDeviceChromeOS::Create( | 812 BluetoothDeviceChromeOS* BluetoothDeviceChromeOS::Create( |
747 BluetoothAdapterChromeOS* adapter) { | 813 BluetoothAdapterChromeOS* adapter) { |
748 return new BluetoothDeviceChromeOS(adapter); | 814 return new BluetoothDeviceChromeOS(adapter); |
749 } | 815 } |
750 | 816 |
751 } // namespace chromeos | 817 } // namespace chromeos |
OLD | NEW |