OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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_adapter_mac.h" | 5 #include "device/bluetooth/bluetooth_adapter_mac.h" |
6 | 6 |
7 #import <IOBluetooth/objc/IOBluetoothDevice.h> | 7 #import <IOBluetooth/objc/IOBluetoothDevice.h> |
8 #import <IOBluetooth/objc/IOBluetoothHostController.h> | 8 #import <IOBluetooth/objc/IOBluetoothHostController.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 return BluetoothAdapterMac::CreateAdapter(); | 47 return BluetoothAdapterMac::CreateAdapter(); |
48 } | 48 } |
49 | 49 |
50 // static | 50 // static |
51 base::WeakPtr<BluetoothAdapter> BluetoothAdapterMac::CreateAdapter() { | 51 base::WeakPtr<BluetoothAdapter> BluetoothAdapterMac::CreateAdapter() { |
52 BluetoothAdapterMac* adapter = new BluetoothAdapterMac(); | 52 BluetoothAdapterMac* adapter = new BluetoothAdapterMac(); |
53 adapter->Init(); | 53 adapter->Init(); |
54 return adapter->weak_ptr_factory_.GetWeakPtr(); | 54 return adapter->weak_ptr_factory_.GetWeakPtr(); |
55 } | 55 } |
56 | 56 |
| 57 // static |
| 58 base::WeakPtr<BluetoothAdapter> BluetoothAdapterMac::CreateAdapterForTest( |
| 59 std::string name, |
| 60 std::string address, |
| 61 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) { |
| 62 BluetoothAdapterMac* adapter = new BluetoothAdapterMac(); |
| 63 adapter->InitForTest(ui_task_runner); |
| 64 adapter->name_ = name; |
| 65 adapter->address_ = address; |
| 66 return adapter->weak_ptr_factory_.GetWeakPtr(); |
| 67 } |
| 68 |
57 BluetoothAdapterMac::BluetoothAdapterMac() | 69 BluetoothAdapterMac::BluetoothAdapterMac() |
58 : BluetoothAdapter(), | 70 : BluetoothAdapter(), |
59 powered_(false), | 71 classic_powered_(false), |
60 num_discovery_sessions_(0), | 72 num_discovery_sessions_(0), |
61 classic_discovery_manager_( | 73 classic_discovery_manager_( |
62 BluetoothDiscoveryManagerMac::CreateClassic(this)), | 74 BluetoothDiscoveryManagerMac::CreateClassic(this)), |
63 weak_ptr_factory_(this) { | 75 weak_ptr_factory_(this) { |
64 if (IsLowEnergyAvailable()) { | 76 if (IsLowEnergyAvailable()) { |
65 low_energy_discovery_manager_.reset( | 77 low_energy_discovery_manager_.reset( |
66 BluetoothLowEnergyDiscoveryManagerMac::Create(this)); | 78 BluetoothLowEnergyDiscoveryManagerMac::Create(this)); |
67 low_energy_central_manager_delegate_.reset( | 79 low_energy_central_manager_delegate_.reset( |
68 [[BluetoothLowEnergyCentralManagerDelegate alloc] | 80 [[BluetoothLowEnergyCentralManagerDelegate alloc] |
69 initWithDiscoveryManager:low_energy_discovery_manager_.get() | 81 initWithDiscoveryManager:low_energy_discovery_manager_.get() |
(...skipping 23 matching lines...) Expand all Loading... |
93 const base::Closure& callback, | 105 const base::Closure& callback, |
94 const ErrorCallback& error_callback) { | 106 const ErrorCallback& error_callback) { |
95 NOTIMPLEMENTED(); | 107 NOTIMPLEMENTED(); |
96 } | 108 } |
97 | 109 |
98 bool BluetoothAdapterMac::IsInitialized() const { | 110 bool BluetoothAdapterMac::IsInitialized() const { |
99 return true; | 111 return true; |
100 } | 112 } |
101 | 113 |
102 bool BluetoothAdapterMac::IsPresent() const { | 114 bool BluetoothAdapterMac::IsPresent() const { |
103 return !address_.empty(); | 115 bool is_present = !address_.empty(); |
| 116 if (IsLowEnergyAvailable()) { |
| 117 is_present = is_present || ([low_energy_central_manager_ state] == |
| 118 CBCentralManagerStatePoweredOn); |
| 119 } |
| 120 return is_present; |
104 } | 121 } |
105 | 122 |
106 bool BluetoothAdapterMac::IsPowered() const { | 123 bool BluetoothAdapterMac::IsPowered() const { |
107 return powered_; | 124 bool is_powered = classic_powered_; |
| 125 if (IsLowEnergyAvailable()) { |
| 126 is_powered = is_powered || ([low_energy_central_manager_ state] == |
| 127 CBCentralManagerStatePoweredOn); |
| 128 } |
| 129 return is_powered; |
108 } | 130 } |
109 | 131 |
110 void BluetoothAdapterMac::SetPowered(bool powered, | 132 void BluetoothAdapterMac::SetPowered(bool powered, |
111 const base::Closure& callback, | 133 const base::Closure& callback, |
112 const ErrorCallback& error_callback) { | 134 const ErrorCallback& error_callback) { |
113 NOTIMPLEMENTED(); | 135 NOTIMPLEMENTED(); |
114 } | 136 } |
115 | 137 |
116 bool BluetoothAdapterMac::IsDiscoverable() const { | 138 bool BluetoothAdapterMac::IsDiscoverable() const { |
117 NOTIMPLEMENTED(); | 139 NOTIMPLEMENTED(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 DVLOG(1) << "Adapter registered a new connection from device with address: " | 212 DVLOG(1) << "Adapter registered a new connection from device with address: " |
191 << BluetoothClassicDeviceMac::GetDeviceAddress(device); | 213 << BluetoothClassicDeviceMac::GetDeviceAddress(device); |
192 ClassicDeviceAdded(device); | 214 ClassicDeviceAdded(device); |
193 } | 215 } |
194 | 216 |
195 // static | 217 // static |
196 bool BluetoothAdapterMac::IsLowEnergyAvailable() { | 218 bool BluetoothAdapterMac::IsLowEnergyAvailable() { |
197 return base::mac::IsOSYosemiteOrLater(); | 219 return base::mac::IsOSYosemiteOrLater(); |
198 } | 220 } |
199 | 221 |
| 222 void BluetoothAdapterMac::SetCentralManagerForTesting( |
| 223 CBCentralManager* central_manager) { |
| 224 CHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); |
| 225 [central_manager performSelector:@selector(setDelegate:) |
| 226 withObject:low_energy_central_manager_delegate_]; |
| 227 low_energy_central_manager_.reset(central_manager); |
| 228 low_energy_discovery_manager_->SetCentralManager( |
| 229 low_energy_central_manager_.get()); |
| 230 } |
| 231 |
200 void BluetoothAdapterMac::RemovePairingDelegateInternal( | 232 void BluetoothAdapterMac::RemovePairingDelegateInternal( |
201 BluetoothDevice::PairingDelegate* pairing_delegate) { | 233 BluetoothDevice::PairingDelegate* pairing_delegate) { |
202 } | 234 } |
203 | 235 |
204 void BluetoothAdapterMac::AddDiscoverySession( | 236 void BluetoothAdapterMac::AddDiscoverySession( |
205 BluetoothDiscoveryFilter* discovery_filter, | 237 BluetoothDiscoveryFilter* discovery_filter, |
206 const base::Closure& callback, | 238 const base::Closure& callback, |
207 const ErrorCallback& error_callback) { | 239 const ErrorCallback& error_callback) { |
208 DVLOG(1) << __func__; | 240 DVLOG(1) << __func__; |
209 if (num_discovery_sessions_ > 0) { | 241 if (num_discovery_sessions_ > 0) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 } | 356 } |
325 | 357 |
326 void BluetoothAdapterMac::PollAdapter() { | 358 void BluetoothAdapterMac::PollAdapter() { |
327 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 | 359 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 |
328 // is fixed. | 360 // is fixed. |
329 tracked_objects::ScopedTracker tracking_profile1( | 361 tracked_objects::ScopedTracker tracking_profile1( |
330 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 362 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
331 "461181 BluetoothAdapterMac::PollAdapter::Start")); | 363 "461181 BluetoothAdapterMac::PollAdapter::Start")); |
332 bool was_present = IsPresent(); | 364 bool was_present = IsPresent(); |
333 std::string address; | 365 std::string address; |
334 bool powered = false; | 366 bool classic_powered = false; |
335 IOBluetoothHostController* controller = | 367 IOBluetoothHostController* controller = |
336 [IOBluetoothHostController defaultController]; | 368 [IOBluetoothHostController defaultController]; |
337 | 369 |
338 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 | 370 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 |
339 // is fixed. | 371 // is fixed. |
340 tracked_objects::ScopedTracker tracking_profile2( | 372 tracked_objects::ScopedTracker tracking_profile2( |
341 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 373 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
342 "461181 BluetoothAdapterMac::PollAdapter::GetControllerStats")); | 374 "461181 BluetoothAdapterMac::PollAdapter::GetControllerStats")); |
343 if (controller != nil) { | 375 if (controller != nil) { |
344 address = BluetoothDevice::CanonicalizeAddress( | 376 address = BluetoothDevice::CanonicalizeAddress( |
345 base::SysNSStringToUTF8([controller addressAsString])); | 377 base::SysNSStringToUTF8([controller addressAsString])); |
346 powered = ([controller powerState] == kBluetoothHCIPowerStateON); | 378 classic_powered = ([controller powerState] == kBluetoothHCIPowerStateON); |
347 | 379 |
348 // For performance reasons, cache the adapter's name. It's not uncommon for | 380 // For performance reasons, cache the adapter's name. It's not uncommon for |
349 // a call to [controller nameAsString] to take tens of milliseconds. Note | 381 // a call to [controller nameAsString] to take tens of milliseconds. Note |
350 // that this caching strategy might result in clients receiving a stale | 382 // that this caching strategy might result in clients receiving a stale |
351 // name. If this is a significant issue, then some more sophisticated | 383 // name. If this is a significant issue, then some more sophisticated |
352 // workaround for the performance bottleneck will be needed. For additional | 384 // workaround for the performance bottleneck will be needed. For additional |
353 // context, see http://crbug.com/461181 and http://crbug.com/467316 | 385 // context, see http://crbug.com/461181 and http://crbug.com/467316 |
354 if (address != address_ || (!address.empty() && name_.empty())) | 386 if (address != address_ || (!address.empty() && name_.empty())) |
355 name_ = base::SysNSStringToUTF8([controller nameAsString]); | 387 name_ = base::SysNSStringToUTF8([controller nameAsString]); |
356 } | 388 } |
357 | 389 |
358 bool is_present = !address.empty(); | 390 bool is_present = !address.empty(); |
359 address_ = address; | 391 address_ = address; |
360 | 392 |
361 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 | 393 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 |
362 // is fixed. | 394 // is fixed. |
363 tracked_objects::ScopedTracker tracking_profile3( | 395 tracked_objects::ScopedTracker tracking_profile3( |
364 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 396 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
365 "461181 BluetoothAdapterMac::PollAdapter::AdapterPresentChanged")); | 397 "461181 BluetoothAdapterMac::PollAdapter::AdapterPresentChanged")); |
366 if (was_present != is_present) { | 398 if (was_present != is_present) { |
367 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 399 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
368 AdapterPresentChanged(this, is_present)); | 400 AdapterPresentChanged(this, is_present)); |
369 } | 401 } |
370 | 402 |
371 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 | 403 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 |
372 // is fixed. | 404 // is fixed. |
373 tracked_objects::ScopedTracker tracking_profile4( | 405 tracked_objects::ScopedTracker tracking_profile4( |
374 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 406 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
375 "461181 BluetoothAdapterMac::PollAdapter::AdapterPowerChanged")); | 407 "461181 BluetoothAdapterMac::PollAdapter::AdapterPowerChanged")); |
376 if (powered_ != powered) { | 408 if (classic_powered_ != classic_powered) { |
377 powered_ = powered; | 409 classic_powered_ = classic_powered; |
378 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 410 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
379 AdapterPoweredChanged(this, powered_)); | 411 AdapterPoweredChanged(this, classic_powered_)); |
380 } | 412 } |
381 | 413 |
382 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 | 414 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 |
383 // is fixed. | 415 // is fixed. |
384 tracked_objects::ScopedTracker tracking_profile5( | 416 tracked_objects::ScopedTracker tracking_profile5( |
385 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 417 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
386 "461181 BluetoothAdapterMac::PollAdapter::RemoveTimedOutDevices")); | 418 "461181 BluetoothAdapterMac::PollAdapter::RemoveTimedOutDevices")); |
387 RemoveTimedOutDevices(); | 419 RemoveTimedOutDevices(); |
388 | 420 |
389 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 | 421 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/461181 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 } | 514 } |
483 } | 515 } |
484 | 516 |
485 void BluetoothAdapterMac::AddPairedDevices() { | 517 void BluetoothAdapterMac::AddPairedDevices() { |
486 // Add any new paired devices. | 518 // Add any new paired devices. |
487 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { | 519 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { |
488 ClassicDeviceAdded(device); | 520 ClassicDeviceAdded(device); |
489 } | 521 } |
490 } | 522 } |
491 | 523 |
492 void BluetoothAdapterMac::SetCentralManagerForTesting( | |
493 CBCentralManager* central_manager) { | |
494 CHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); | |
495 [central_manager performSelector:@selector(setDelegate:) | |
496 withObject:low_energy_central_manager_delegate_]; | |
497 low_energy_central_manager_.reset(central_manager); | |
498 low_energy_discovery_manager_->SetCentralManager( | |
499 low_energy_central_manager_.get()); | |
500 } | |
501 | |
502 } // namespace device | 524 } // namespace device |
OLD | NEW |