| 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/IOBluetoothDeviceInquiry.h> | 8 #import <IOBluetooth/objc/IOBluetoothDeviceInquiry.h> |
| 9 #import <IOBluetooth/objc/IOBluetoothHostController.h> | 9 #import <IOBluetooth/objc/IOBluetoothHostController.h> |
| 10 | 10 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 - (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender; | 37 - (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender; |
| 38 - (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender | 38 - (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender |
| 39 device:(IOBluetoothDevice*)device; | 39 device:(IOBluetoothDevice*)device; |
| 40 - (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender | 40 - (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender |
| 41 error:(IOReturn)error | 41 error:(IOReturn)error |
| 42 aborted:(BOOL)aborted; | 42 aborted:(BOOL)aborted; |
| 43 @end | 43 @end |
| 44 | 44 |
| 45 #endif // MAC_OS_X_VERSION_10_7 | 45 #endif // MAC_OS_X_VERSION_10_7 |
| 46 | 46 |
| 47 @interface BluetoothAdapterMacDelegate | 47 @interface BluetoothDeviceInquiryDelegate |
| 48 : NSObject <IOBluetoothDeviceInquiryDelegate> { | 48 : NSObject<IOBluetoothDeviceInquiryDelegate> { |
| 49 @private | 49 @private |
| 50 device::BluetoothAdapterMac* adapter_; // weak | 50 device::BluetoothMacClassicDiscoveryManager* manager_; // weak |
| 51 } | 51 } |
| 52 | 52 |
| 53 - (id)initWithAdapter:(device::BluetoothAdapterMac*)adapter; | 53 - (id)initWithManager:(device::BluetoothMacClassicDiscoveryManager*)manager; |
| 54 | 54 |
| 55 @end | 55 @end |
| 56 | 56 |
| 57 @implementation BluetoothAdapterMacDelegate | 57 @implementation BluetoothDeviceInquiryDelegate |
| 58 | 58 |
| 59 - (id)initWithAdapter:(device::BluetoothAdapterMac*)adapter { | 59 - (id)initWithManager:(device::BluetoothMacClassicDiscoveryManager*)manager { |
| 60 if ((self = [super init])) | 60 if ((self = [super init])) |
| 61 adapter_ = adapter; | 61 manager_ = manager; |
| 62 | 62 |
| 63 return self; | 63 return self; |
| 64 } | 64 } |
| 65 | 65 |
| 66 - (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender { | 66 - (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender { |
| 67 adapter_->DeviceInquiryStarted(sender); | 67 manager_->DeviceInquiryStarted(sender); |
| 68 } | 68 } |
| 69 | 69 |
| 70 - (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender | 70 - (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender |
| 71 device:(IOBluetoothDevice*)device { | 71 device:(IOBluetoothDevice*)device { |
| 72 adapter_->DeviceFound(sender, device); | 72 manager_->DeviceFound(sender, device); |
| 73 } | 73 } |
| 74 | 74 |
| 75 - (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender | 75 - (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender |
| 76 error:(IOReturn)error | 76 error:(IOReturn)error |
| 77 aborted:(BOOL)aborted { | 77 aborted:(BOOL)aborted { |
| 78 adapter_->DeviceInquiryComplete(sender, error, aborted); | 78 manager_->DeviceInquiryComplete(sender, error, aborted); |
| 79 } | 79 } |
| 80 | 80 |
| 81 @end | 81 @end |
| 82 | 82 |
| 83 namespace { | 83 namespace { |
| 84 | 84 |
| 85 const int kPollIntervalMs = 500; | 85 const int kPollIntervalMs = 500; |
| 86 | 86 |
| 87 } // namespace | 87 } // namespace |
| 88 | 88 |
| 89 namespace device { | 89 namespace device { |
| 90 | 90 |
| 91 // static | 91 // static |
| 92 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( | 92 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( |
| 93 const InitCallback& init_callback) { | 93 const InitCallback& init_callback) { |
| 94 return BluetoothAdapterMac::CreateAdapter(); | 94 return BluetoothAdapterMac::CreateAdapter(); |
| 95 } | 95 } |
| 96 | 96 |
| 97 // static | 97 // static |
| 98 base::WeakPtr<BluetoothAdapter> BluetoothAdapterMac::CreateAdapter() { | 98 base::WeakPtr<BluetoothAdapter> BluetoothAdapterMac::CreateAdapter() { |
| 99 BluetoothAdapterMac* adapter = new BluetoothAdapterMac(); | 99 BluetoothAdapterMac* adapter = new BluetoothAdapterMac(); |
| 100 adapter->Init(); | 100 adapter->Init(); |
| 101 return adapter->weak_ptr_factory_.GetWeakPtr(); | 101 return adapter->weak_ptr_factory_.GetWeakPtr(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 BluetoothMacClassicDiscoveryManager::BluetoothMacClassicDiscoveryManager( |
| 105 BluetoothAdapterMac* adapter) |
| 106 : should_do_discovery_(false), |
| 107 inquiry_running_(false), |
| 108 adapter_(adapter), |
| 109 inquiry_delegate_( |
| 110 [[BluetoothDeviceInquiryDelegate alloc] initWithManager:this]), |
| 111 inquiry_([[IOBluetoothDeviceInquiry alloc] |
| 112 initWithDelegate:inquiry_delegate_]) { |
| 113 } |
| 114 |
| 115 BluetoothMacClassicDiscoveryManager::~BluetoothMacClassicDiscoveryManager() { |
| 116 } |
| 117 |
| 118 bool BluetoothMacClassicDiscoveryManager::IsDiscovering() const { |
| 119 return should_do_discovery_; |
| 120 } |
| 121 |
| 122 bool BluetoothMacClassicDiscoveryManager::StartDiscovery() { |
| 123 VLOG(1) << "Bluetooth Classic: StartDiscovery"; |
| 124 if (should_do_discovery_) { |
| 125 VLOG(1) << "Already discovering"; |
| 126 return true; |
| 127 } |
| 128 |
| 129 VLOG(1) << "Discovery requested"; |
| 130 should_do_discovery_ = true; |
| 131 |
| 132 if (inquiry_running_) { |
| 133 VLOG(1) << "Device inquiry already running"; |
| 134 return true; |
| 135 } |
| 136 |
| 137 VLOG(1) << "Requesting to start device inquiry"; |
| 138 if ([inquiry_ start] != kIOReturnSuccess) { |
| 139 VLOG(1) << "Failed to start device inquiry"; |
| 140 |
| 141 // Set |should_do_discovery_| to false here. Since we're reporting an |
| 142 // error, we're indicating that the adapter call StartDiscovery again |
| 143 // if needed. |
| 144 should_do_discovery_ = false; |
| 145 return false; |
| 146 } |
| 147 |
| 148 VLOG(1) << "Device inquiry start was successful"; |
| 149 return true; |
| 150 } |
| 151 |
| 152 bool BluetoothMacClassicDiscoveryManager::StopDiscovery() { |
| 153 VLOG(1) << "Bluetooth Classic: StopDiscovery"; |
| 154 if (!should_do_discovery_) { |
| 155 VLOG(1) << "Discovery already stopped"; |
| 156 return true; |
| 157 } |
| 158 |
| 159 should_do_discovery_ = false; |
| 160 |
| 161 if (!inquiry_running_) { |
| 162 VLOG(1) << "No device inquiry running; discovery stopped"; |
| 163 return true; |
| 164 } |
| 165 |
| 166 VLOG(1) << "Requesting to stop device inquiry"; |
| 167 IOReturn status = [inquiry_ stop]; |
| 168 if (status == kIOReturnSuccess) { |
| 169 VLOG(1) << "Device inquiry stop was successful"; |
| 170 return true; |
| 171 } |
| 172 |
| 173 if (status == kIOReturnNotPermitted) { |
| 174 VLOG(1) << "Device inquiry was already stopped"; |
| 175 return true; |
| 176 } |
| 177 |
| 178 LOG(WARNING) << "Failed to stop device inquiry"; |
| 179 return false; |
| 180 } |
| 181 |
| 182 void BluetoothMacClassicDiscoveryManager::DeviceInquiryStarted( |
| 183 IOBluetoothDeviceInquiry* inquiry) { |
| 184 DCHECK(!inquiry_running_); |
| 185 |
| 186 VLOG(1) << "Device inquiry started!"; |
| 187 |
| 188 // If discovery was requested to stop in the mean time, stop the inquiry. |
| 189 if (!should_do_discovery_) { |
| 190 VLOG(1) << "Discovery stop was requested earlier. Stopping inquiry"; |
| 191 [inquiry stop]; |
| 192 return; |
| 193 } |
| 194 |
| 195 inquiry_running_ = true; |
| 196 } |
| 197 |
| 198 void BluetoothMacClassicDiscoveryManager::DeviceFound( |
| 199 IOBluetoothDeviceInquiry* inquiry, |
| 200 IOBluetoothDevice* device) { |
| 201 adapter_->DeviceFound(device); |
| 202 } |
| 203 |
| 204 void BluetoothMacClassicDiscoveryManager::DeviceInquiryComplete( |
| 205 IOBluetoothDeviceInquiry* inquiry, |
| 206 IOReturn error, |
| 207 bool aborted) { |
| 208 DCHECK_EQ(inquiry_, inquiry); |
| 209 VLOG(1) << "Device inquiry complete"; |
| 210 inquiry_running_ = false; |
| 211 |
| 212 // Automatically restart device inquiry if discovery is still desired. |
| 213 if (!should_do_discovery_) { |
| 214 adapter_->ClassicDiscoveryStopped(false /* unexpected */); |
| 215 return; |
| 216 } |
| 217 |
| 218 if (error != kIOReturnSuccess) { |
| 219 VLOG(1) << "Inquiry has stopped with an error: " << error; |
| 220 should_do_discovery_ = false; |
| 221 adapter_->ClassicDiscoveryStopped(true /* unexpected */); |
| 222 return; |
| 223 } |
| 224 |
| 225 VLOG(1) << "Restarting device inquiry"; |
| 226 |
| 227 if ([inquiry_ start] == kIOReturnSuccess) { |
| 228 VLOG(1) << "Device inquiry restart was successful"; |
| 229 return; |
| 230 } |
| 231 |
| 232 VLOG(1) << "Failed to restart discovery"; |
| 233 should_do_discovery_ = false; |
| 234 adapter_->ClassicDiscoveryStopped(true /* unexpected */); |
| 235 } |
| 236 |
| 104 BluetoothAdapterMac::BluetoothAdapterMac() | 237 BluetoothAdapterMac::BluetoothAdapterMac() |
| 105 : BluetoothAdapter(), | 238 : BluetoothAdapter(), |
| 106 powered_(false), | 239 powered_(false), |
| 107 discovery_status_(NOT_DISCOVERING), | 240 num_discovery_sessions_(0), |
| 108 adapter_delegate_( | 241 classic_discovery_session_manager_( |
| 109 [[BluetoothAdapterMacDelegate alloc] initWithAdapter:this]), | 242 new BluetoothMacClassicDiscoveryManager(this)), |
| 110 device_inquiry_( | |
| 111 [[IOBluetoothDeviceInquiry | |
| 112 inquiryWithDelegate:adapter_delegate_] retain]), | |
| 113 weak_ptr_factory_(this) { | 243 weak_ptr_factory_(this) { |
| 114 } | 244 } |
| 115 | 245 |
| 116 BluetoothAdapterMac::~BluetoothAdapterMac() { | 246 BluetoothAdapterMac::~BluetoothAdapterMac() { |
| 117 } | 247 } |
| 118 | 248 |
| 119 void BluetoothAdapterMac::AddObserver(BluetoothAdapter::Observer* observer) { | 249 void BluetoothAdapterMac::AddObserver(BluetoothAdapter::Observer* observer) { |
| 120 DCHECK(observer); | 250 DCHECK(observer); |
| 121 observers_.AddObserver(observer); | 251 observers_.AddObserver(observer); |
| 122 } | 252 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 294 } |
| 165 | 295 |
| 166 void BluetoothAdapterMac::SetDiscoverable( | 296 void BluetoothAdapterMac::SetDiscoverable( |
| 167 bool discoverable, | 297 bool discoverable, |
| 168 const base::Closure& callback, | 298 const base::Closure& callback, |
| 169 const ErrorCallback& error_callback) { | 299 const ErrorCallback& error_callback) { |
| 170 NOTIMPLEMENTED(); | 300 NOTIMPLEMENTED(); |
| 171 } | 301 } |
| 172 | 302 |
| 173 bool BluetoothAdapterMac::IsDiscovering() const { | 303 bool BluetoothAdapterMac::IsDiscovering() const { |
| 174 return discovery_status_ == DISCOVERING || | 304 return classic_discovery_session_manager_->IsDiscovering(); |
| 175 discovery_status_ == DISCOVERY_STOPPING; | |
| 176 } | 305 } |
| 177 | 306 |
| 178 void BluetoothAdapterMac::CreateRfcommService( | 307 void BluetoothAdapterMac::CreateRfcommService( |
| 179 const BluetoothUUID& uuid, | 308 const BluetoothUUID& uuid, |
| 180 int channel, | 309 int channel, |
| 181 bool insecure, | 310 bool insecure, |
| 182 const CreateServiceCallback& callback, | 311 const CreateServiceCallback& callback, |
| 183 const CreateServiceErrorCallback& error_callback) { | 312 const CreateServiceErrorCallback& error_callback) { |
| 184 // TODO(keybuk): implement. | 313 // TODO(keybuk): implement. |
| 185 NOTIMPLEMENTED(); | 314 NOTIMPLEMENTED(); |
| 186 } | 315 } |
| 187 | 316 |
| 188 void BluetoothAdapterMac::CreateL2capService( | 317 void BluetoothAdapterMac::CreateL2capService( |
| 189 const BluetoothUUID& uuid, | 318 const BluetoothUUID& uuid, |
| 190 int psm, | 319 int psm, |
| 191 const CreateServiceCallback& callback, | 320 const CreateServiceCallback& callback, |
| 192 const CreateServiceErrorCallback& error_callback) { | 321 const CreateServiceErrorCallback& error_callback) { |
| 193 // TODO(keybuk): implement. | 322 // TODO(keybuk): implement. |
| 194 NOTIMPLEMENTED(); | 323 NOTIMPLEMENTED(); |
| 195 } | 324 } |
| 196 | 325 |
| 326 void BluetoothAdapterMac::DeviceFound(IOBluetoothDevice* device) { |
| 327 std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); |
| 328 if (discovered_devices_.find(device_address) == discovered_devices_.end()) { |
| 329 BluetoothDeviceMac device_mac(device); |
| 330 FOR_EACH_OBSERVER( |
| 331 BluetoothAdapter::Observer, observers_, DeviceAdded(this, &device_mac)); |
| 332 discovered_devices_.insert(device_address); |
| 333 } |
| 334 } |
| 335 |
| 336 void BluetoothAdapterMac::ClassicDiscoveryStopped(bool unexpected) { |
| 337 if (unexpected) { |
| 338 VLOG(1) << "Discovery stopped unexpectedly"; |
| 339 num_discovery_sessions_ = 0; |
| 340 MarkDiscoverySessionsAsInactive(); |
| 341 } |
| 342 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
| 343 observers_, |
| 344 AdapterDiscoveringChanged(this, false)); |
| 345 } |
| 346 |
| 197 void BluetoothAdapterMac::AddDiscoverySession( | 347 void BluetoothAdapterMac::AddDiscoverySession( |
| 198 const base::Closure& callback, | 348 const base::Closure& callback, |
| 199 const ErrorCallback& error_callback) { | 349 const ErrorCallback& error_callback) { |
| 200 if (discovery_status_ == DISCOVERING) { | 350 VLOG(1) << __func__; |
| 201 num_discovery_listeners_++; | 351 if (num_discovery_sessions_ > 0) { |
| 352 DCHECK(IsDiscovering()); |
| 353 num_discovery_sessions_++; |
| 202 callback.Run(); | 354 callback.Run(); |
| 203 return; | 355 return; |
| 204 } | 356 } |
| 205 on_start_discovery_callbacks_.push_back( | 357 |
| 206 std::make_pair(callback, error_callback)); | 358 DCHECK(num_discovery_sessions_ == 0); |
| 207 MaybeStartDeviceInquiry(); | 359 |
| 360 if (!classic_discovery_session_manager_->StartDiscovery()) { |
| 361 VLOG(1) << "Failed to add a discovery session"; |
| 362 error_callback.Run(); |
| 363 return; |
| 364 } |
| 365 |
| 366 VLOG(1) << "Added a discovery session"; |
| 367 num_discovery_sessions_++; |
| 368 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
| 369 observers_, |
| 370 AdapterDiscoveringChanged(this, true)); |
| 371 callback.Run(); |
| 208 } | 372 } |
| 209 | 373 |
| 210 void BluetoothAdapterMac::RemoveDiscoverySession( | 374 void BluetoothAdapterMac::RemoveDiscoverySession( |
| 211 const base::Closure& callback, | 375 const base::Closure& callback, |
| 212 const ErrorCallback& error_callback) { | 376 const ErrorCallback& error_callback) { |
| 213 if (discovery_status_ == NOT_DISCOVERING) { | 377 VLOG(1) << __func__; |
| 378 |
| 379 // There are active sessions other than the one currently being removed. |
| 380 if (num_discovery_sessions_ > 1) { |
| 381 DCHECK(IsDiscovering()); |
| 382 num_discovery_sessions_--; |
| 383 callback.Run(); |
| 384 return; |
| 385 } |
| 386 |
| 387 if (num_discovery_sessions_ == 0) { |
| 388 VLOG(1) << "No active discovery sessions. Returning error."; |
| 214 error_callback.Run(); | 389 error_callback.Run(); |
| 215 return; | 390 return; |
| 216 } | 391 } |
| 217 on_stop_discovery_callbacks_.push_back( | 392 |
| 218 std::make_pair(callback, error_callback)); | 393 if (!classic_discovery_session_manager_->StopDiscovery()) { |
| 219 MaybeStopDeviceInquiry(); | 394 VLOG(1) << "Failed to stop discovery"; |
| 395 error_callback.Run(); |
| 396 return; |
| 397 } |
| 398 |
| 399 VLOG(1) << "Discovery stopped"; |
| 400 num_discovery_sessions_--; |
| 401 callback.Run(); |
| 220 } | 402 } |
| 221 | 403 |
| 222 void BluetoothAdapterMac::RemovePairingDelegateInternal( | 404 void BluetoothAdapterMac::RemovePairingDelegateInternal( |
| 223 BluetoothDevice::PairingDelegate* pairing_delegate) { | 405 BluetoothDevice::PairingDelegate* pairing_delegate) { |
| 224 } | 406 } |
| 225 | 407 |
| 226 void BluetoothAdapterMac::Init() { | 408 void BluetoothAdapterMac::Init() { |
| 227 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 409 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 228 PollAdapter(); | 410 PollAdapter(); |
| 229 } | 411 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 } | 457 } |
| 276 | 458 |
| 277 ui_task_runner_->PostDelayedTask( | 459 ui_task_runner_->PostDelayedTask( |
| 278 FROM_HERE, | 460 FROM_HERE, |
| 279 base::Bind(&BluetoothAdapterMac::PollAdapter, | 461 base::Bind(&BluetoothAdapterMac::PollAdapter, |
| 280 weak_ptr_factory_.GetWeakPtr()), | 462 weak_ptr_factory_.GetWeakPtr()), |
| 281 base::TimeDelta::FromMilliseconds(kPollIntervalMs)); | 463 base::TimeDelta::FromMilliseconds(kPollIntervalMs)); |
| 282 } | 464 } |
| 283 | 465 |
| 284 void BluetoothAdapterMac::UpdateDevices(NSArray* devices) { | 466 void BluetoothAdapterMac::UpdateDevices(NSArray* devices) { |
| 467 // TODO(armansito): This code never calls |
| 468 // BluetoothAdapter::Observer::DeviceRemoved. It should, if a device |
| 469 // no longer exists. |
| 285 STLDeleteValues(&devices_); | 470 STLDeleteValues(&devices_); |
| 286 for (IOBluetoothDevice* device in devices) { | 471 for (IOBluetoothDevice* device in devices) { |
| 287 std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); | 472 std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); |
| 288 devices_[device_address] = new BluetoothDeviceMac(device); | 473 devices_[device_address] = new BluetoothDeviceMac(device); |
| 289 } | 474 } |
| 290 } | 475 } |
| 291 | 476 |
| 292 void BluetoothAdapterMac::DeviceInquiryStarted( | |
| 293 IOBluetoothDeviceInquiry* inquiry) { | |
| 294 DCHECK_EQ(device_inquiry_, inquiry); | |
| 295 if (discovery_status_ == DISCOVERING) | |
| 296 return; | |
| 297 | |
| 298 discovery_status_ = DISCOVERING; | |
| 299 RunCallbacks(on_start_discovery_callbacks_, true); | |
| 300 num_discovery_listeners_ = on_start_discovery_callbacks_.size(); | |
| 301 on_start_discovery_callbacks_.clear(); | |
| 302 | |
| 303 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | |
| 304 AdapterDiscoveringChanged(this, true)); | |
| 305 MaybeStopDeviceInquiry(); | |
| 306 } | |
| 307 | |
| 308 void BluetoothAdapterMac::DeviceFound(IOBluetoothDeviceInquiry* inquiry, | |
| 309 IOBluetoothDevice* device) { | |
| 310 DCHECK_EQ(device_inquiry_, inquiry); | |
| 311 std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); | |
| 312 if (discovered_devices_.find(device_address) == discovered_devices_.end()) { | |
| 313 BluetoothDeviceMac device_mac(device); | |
| 314 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | |
| 315 DeviceAdded(this, &device_mac)); | |
| 316 discovered_devices_.insert(device_address); | |
| 317 } | |
| 318 } | |
| 319 | |
| 320 void BluetoothAdapterMac::DeviceInquiryComplete( | |
| 321 IOBluetoothDeviceInquiry* inquiry, | |
| 322 IOReturn error, | |
| 323 bool aborted) { | |
| 324 DCHECK_EQ(device_inquiry_, inquiry); | |
| 325 if (discovery_status_ == DISCOVERING && | |
| 326 [device_inquiry_ start] == kIOReturnSuccess) { | |
| 327 return; | |
| 328 } | |
| 329 | |
| 330 // Device discovery is done. | |
| 331 discovered_devices_.clear(); | |
| 332 discovery_status_ = NOT_DISCOVERING; | |
| 333 RunCallbacks(on_stop_discovery_callbacks_, error == kIOReturnSuccess); | |
| 334 num_discovery_listeners_ = 0; | |
| 335 on_stop_discovery_callbacks_.clear(); | |
| 336 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | |
| 337 AdapterDiscoveringChanged(this, false)); | |
| 338 MaybeStartDeviceInquiry(); | |
| 339 } | |
| 340 | |
| 341 void BluetoothAdapterMac::MaybeStartDeviceInquiry() { | |
| 342 if (discovery_status_ == NOT_DISCOVERING && | |
| 343 !on_start_discovery_callbacks_.empty()) { | |
| 344 discovery_status_ = DISCOVERY_STARTING; | |
| 345 if ([device_inquiry_ start] != kIOReturnSuccess) { | |
| 346 discovery_status_ = NOT_DISCOVERING; | |
| 347 RunCallbacks(on_start_discovery_callbacks_, false); | |
| 348 on_start_discovery_callbacks_.clear(); | |
| 349 } | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 void BluetoothAdapterMac::MaybeStopDeviceInquiry() { | |
| 354 if (discovery_status_ != DISCOVERING) | |
| 355 return; | |
| 356 | |
| 357 if (on_stop_discovery_callbacks_.size() < num_discovery_listeners_) { | |
| 358 RunCallbacks(on_stop_discovery_callbacks_, true); | |
| 359 num_discovery_listeners_ -= on_stop_discovery_callbacks_.size(); | |
| 360 on_stop_discovery_callbacks_.clear(); | |
| 361 return; | |
| 362 } | |
| 363 | |
| 364 discovery_status_ = DISCOVERY_STOPPING; | |
| 365 if ([device_inquiry_ stop] != kIOReturnSuccess) { | |
| 366 RunCallbacks(on_stop_discovery_callbacks_, false); | |
| 367 on_stop_discovery_callbacks_.clear(); | |
| 368 } | |
| 369 } | |
| 370 | |
| 371 void BluetoothAdapterMac::RunCallbacks( | |
| 372 const DiscoveryCallbackList& callback_list, bool success) const { | |
| 373 for (DiscoveryCallbackList::const_iterator iter = callback_list.begin(); | |
| 374 iter != callback_list.end(); | |
| 375 ++iter) { | |
| 376 if (success) | |
| 377 ui_task_runner_->PostTask(FROM_HERE, iter->first); | |
| 378 else | |
| 379 ui_task_runner_->PostTask(FROM_HERE, iter->second); | |
| 380 } | |
| 381 } | |
| 382 | |
| 383 } // namespace device | 477 } // namespace device |
| OLD | NEW |