| Index: device/bluetooth/bluetooth_discovery_manager_mac.mm
|
| diff --git a/device/bluetooth/bluetooth_discovery_manager_mac.mm b/device/bluetooth/bluetooth_discovery_manager_mac.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..528e22dc77bb9c9fe9666f8acb7f1fbc7873db5f
|
| --- /dev/null
|
| +++ b/device/bluetooth/bluetooth_discovery_manager_mac.mm
|
| @@ -0,0 +1,222 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "device/bluetooth/bluetooth_discovery_manager_mac.h"
|
| +
|
| +#import <IOBluetooth/objc/IOBluetoothDevice.h>
|
| +#import <IOBluetooth/objc/IOBluetoothDeviceInquiry.h>
|
| +
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#include "base/mac/sdk_forward_declarations.h"
|
| +#include "base/logging.h"
|
| +
|
| +namespace device {
|
| +
|
| +class BluetoothDiscoveryManagerMacClassic;
|
| +
|
| +} // namespace device
|
| +
|
| +// IOBluetoothDeviceInquiryDelegate implementation.
|
| +@interface BluetoothDeviceInquiryDelegate
|
| + : NSObject<IOBluetoothDeviceInquiryDelegate> {
|
| + @private
|
| + device::BluetoothDiscoveryManagerMacClassic* manager_; // weak
|
| +}
|
| +
|
| +- (id)initWithManager:(device::BluetoothDiscoveryManagerMacClassic*)manager;
|
| +
|
| +@end
|
| +
|
| +namespace device {
|
| +
|
| +// ementation of BluetoothDiscoveryManagerMac for Bluetooth classic device
|
| +// discovery, using the IOBluetooth framework.
|
| +class BluetoothDiscoveryManagerMacClassic
|
| + : public BluetoothDiscoveryManagerMac {
|
| + public:
|
| + explicit BluetoothDiscoveryManagerMacClassic(Observer* observer)
|
| + : BluetoothDiscoveryManagerMac(observer),
|
| + should_do_discovery_(false),
|
| + inquiry_running_(false),
|
| + inquiry_delegate_(
|
| + [[BluetoothDeviceInquiryDelegate alloc] initWithManager:this]),
|
| + inquiry_([[IOBluetoothDeviceInquiry alloc]
|
| + initWithDelegate:inquiry_delegate_]) {}
|
| +
|
| + virtual ~BluetoothDiscoveryManagerMacClassic() {}
|
| +
|
| + // BluetoothDiscoveryManagerMac override.
|
| + virtual bool IsDiscovering() const OVERRIDE { return should_do_discovery_; }
|
| +
|
| + // BluetoothDiscoveryManagerMac override.
|
| + virtual bool StartDiscovery() OVERRIDE {
|
| + DVLOG(1) << "Bluetooth Classic: StartDiscovery";
|
| + DCHECK(!should_do_discovery_);
|
| +
|
| + DVLOG(1) << "Discovery requested";
|
| + should_do_discovery_ = true;
|
| +
|
| + if (inquiry_running_) {
|
| + DVLOG(1) << "Device inquiry already running";
|
| + return true;
|
| + }
|
| +
|
| + DVLOG(1) << "Requesting to start device inquiry";
|
| + if ([inquiry_ start] != kIOReturnSuccess) {
|
| + DVLOG(1) << "Failed to start device inquiry";
|
| +
|
| + // Set |should_do_discovery_| to false here. Since we're reporting an
|
| + // error, we're indicating that the adapter call StartDiscovery again
|
| + // if needed.
|
| + should_do_discovery_ = false;
|
| + return false;
|
| + }
|
| +
|
| + DVLOG(1) << "Device inquiry start was successful";
|
| + return true;
|
| + }
|
| +
|
| + // BluetoothDiscoveryManagerMac override.
|
| + virtual bool StopDiscovery() OVERRIDE {
|
| + DVLOG(1) << "Bluetooth Classic: StopDiscovery";
|
| + DCHECK(should_do_discovery_);
|
| +
|
| + should_do_discovery_ = false;
|
| +
|
| + if (!inquiry_running_) {
|
| + DVLOG(1) << "No device inquiry running; discovery stopped";
|
| + return true;
|
| + }
|
| +
|
| + DVLOG(1) << "Requesting to stop device inquiry";
|
| + IOReturn status = [inquiry_ stop];
|
| + if (status == kIOReturnSuccess) {
|
| + DVLOG(1) << "Device inquiry stop was successful";
|
| + return true;
|
| + }
|
| +
|
| + if (status == kIOReturnNotPermitted) {
|
| + DVLOG(1) << "Device inquiry was already stopped";
|
| + return true;
|
| + }
|
| +
|
| + LOG(WARNING) << "Failed to stop device inquiry";
|
| + return false;
|
| + }
|
| +
|
| + // Called by BluetoothDeviceInquiryDelegate.
|
| + void DeviceInquiryStarted(IOBluetoothDeviceInquiry* inquiry) {
|
| + DCHECK(!inquiry_running_);
|
| +
|
| + DVLOG(1) << "Device inquiry started!";
|
| +
|
| + // If discovery was requested to stop in the mean time, stop the inquiry.
|
| + if (!should_do_discovery_) {
|
| + DVLOG(1) << "Discovery stop was requested earlier. Stopping inquiry";
|
| + [inquiry stop];
|
| + return;
|
| + }
|
| +
|
| + inquiry_running_ = true;
|
| + }
|
| +
|
| + void DeviceFound(IOBluetoothDeviceInquiry* inquiry,
|
| + IOBluetoothDevice* device) {
|
| + DCHECK(observer_);
|
| + observer_->DeviceFound(this, device);
|
| + }
|
| +
|
| + void DeviceInquiryComplete(IOBluetoothDeviceInquiry* inquiry,
|
| + IOReturn error,
|
| + bool aborted) {
|
| + DCHECK_EQ(inquiry_, inquiry);
|
| + DCHECK(observer_);
|
| + DVLOG(1) << "Device inquiry complete";
|
| + inquiry_running_ = false;
|
| +
|
| + // If discovery is no longer desired, notify observers that discovery
|
| + // has stopped and return.
|
| + if (!should_do_discovery_) {
|
| + observer_->DiscoveryStopped(this, false /* unexpected */);
|
| + return;
|
| + }
|
| +
|
| + // If discovery has stopped due to an unexpected reason, notify the
|
| + // observers and return.
|
| + if (error != kIOReturnSuccess) {
|
| + DVLOG(1) << "Inquiry has stopped with an error: " << error;
|
| + should_do_discovery_ = false;
|
| + observer_->DiscoveryStopped(this, true /* unexpected */);
|
| + return;
|
| + }
|
| +
|
| + DVLOG(1) << "Restarting device inquiry";
|
| +
|
| + if ([inquiry_ start] == kIOReturnSuccess) {
|
| + DVLOG(1) << "Device inquiry restart was successful";
|
| + return;
|
| + }
|
| +
|
| + DVLOG(1) << "Failed to restart discovery";
|
| + should_do_discovery_ = false;
|
| + DCHECK(observer_);
|
| + observer_->DiscoveryStopped(this, true /* unexpected */);
|
| + }
|
| +
|
| + private:
|
| + // The requested discovery state.
|
| + bool should_do_discovery_;
|
| +
|
| + // The current inquiry state.
|
| + bool inquiry_running_;
|
| +
|
| + // Objective-C objects for running and tracking device inquiry.
|
| + base::scoped_nsobject<BluetoothDeviceInquiryDelegate> inquiry_delegate_;
|
| + base::scoped_nsobject<IOBluetoothDeviceInquiry> inquiry_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoveryManagerMacClassic);
|
| +};
|
| +
|
| +BluetoothDiscoveryManagerMac::BluetoothDiscoveryManagerMac(
|
| + Observer* observer) : observer_(observer) {
|
| + DCHECK(observer);
|
| +}
|
| +
|
| +BluetoothDiscoveryManagerMac::~BluetoothDiscoveryManagerMac() {
|
| +}
|
| +
|
| +// static
|
| +BluetoothDiscoveryManagerMac* BluetoothDiscoveryManagerMac::CreateClassic(
|
| + Observer* observer) {
|
| + return new BluetoothDiscoveryManagerMacClassic(observer);
|
| +}
|
| +
|
| +} // namespace device
|
| +
|
| +@implementation BluetoothDeviceInquiryDelegate
|
| +
|
| +- (id)initWithManager:
|
| + (device::BluetoothDiscoveryManagerMacClassic*)manager {
|
| + if ((self = [super init]))
|
| + manager_ = manager;
|
| +
|
| + return self;
|
| +}
|
| +
|
| +- (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender {
|
| + manager_->DeviceInquiryStarted(sender);
|
| +}
|
| +
|
| +- (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender
|
| + device:(IOBluetoothDevice*)device {
|
| + manager_->DeviceFound(sender, device);
|
| +}
|
| +
|
| +- (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender
|
| + error:(IOReturn)error
|
| + aborted:(BOOL)aborted {
|
| + manager_->DeviceInquiryComplete(sender, error, aborted);
|
| +}
|
| +
|
| +@end
|
|
|