Chromium Code Reviews| Index: device/bluetooth/bluetooth_socket_mac.mm |
| diff --git a/device/bluetooth/bluetooth_socket_mac.mm b/device/bluetooth/bluetooth_socket_mac.mm |
| index 2eb4ff460e1f52b2206307f8d17cfe8fa58f5587..c33243040bcb4e2c2671ff6c0e3114517b83f4f7 100644 |
| --- a/device/bluetooth/bluetooth_socket_mac.mm |
| +++ b/device/bluetooth/bluetooth_socket_mac.mm |
| @@ -4,15 +4,14 @@ |
| #include "device/bluetooth/bluetooth_socket_mac.h" |
| -#import <IOBluetooth/objc/IOBluetoothDevice.h> |
| -#import <IOBluetooth/objc/IOBluetoothRFCOMMChannel.h> |
| -#import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h> |
| +#import <IOBluetooth/IOBluetooth.h> |
| #include <limits> |
| #include <sstream> |
| #include <string> |
| #include "base/basictypes.h" |
| +#include "base/bind.h" |
| #include "base/callback_helpers.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/numerics/safe_conversions.h" |
| @@ -107,16 +106,26 @@ BluetoothSocketMac::ConnectCallbacks::ConnectCallbacks() {} |
| BluetoothSocketMac::ConnectCallbacks::~ConnectCallbacks() {} |
| // static |
| -scoped_refptr<BluetoothSocketMac> BluetoothSocketMac::CreateBluetoothSocket( |
| - IOBluetoothSDPServiceRecord* record) { |
| - return new BluetoothSocketMac(record); |
| +void BluetoothSocketMac::Connect( |
| + IOBluetoothSDPServiceRecord* record, |
| + const ConnectSuccessCallback& success_callback, |
| + const ErrorCompletionCallback& error_callback) { |
| + scoped_refptr<BluetoothSocketMac> socket(new BluetoothSocketMac()); |
| + socket->ConnectImpl(record, success_callback, error_callback); |
| } |
| -BluetoothSocketMac::BluetoothSocketMac( |
| - IOBluetoothSDPServiceRecord* record) |
| - : record_([record retain]), |
| - delegate_([[BluetoothRFCOMMChannelDelegate alloc] initWithSocket:this]) { |
| - DCHECK(thread_checker_.CalledOnValidThread()); |
| +// static |
| +void BluetoothSocketMac::AcceptConnection( |
| + IOBluetoothRFCOMMChannel* rfcomm_channel, |
| + const ConnectSuccessCallback& success_callback, |
| + const ErrorCompletionCallback& error_callback) { |
| + scoped_refptr<BluetoothSocketMac> socket(new BluetoothSocketMac()); |
| + socket->AcceptConnectionImpl( |
| + rfcomm_channel, success_callback, error_callback); |
| +} |
|
rpaquay
2014/04/23 22:15:55
There is little common code between a client and a
Ilya Sherman
2014/04/24 06:50:10
I actually originally planned to create a separate
|
| + |
| +BluetoothSocketMac::BluetoothSocketMac() |
| + : delegate_([[BluetoothRFCOMMChannelDelegate alloc] initWithSocket:this]) { |
| } |
| BluetoothSocketMac::~BluetoothSocketMac() { |
| @@ -140,8 +149,9 @@ void BluetoothSocketMac::ReleaseChannel() { |
| empty_queue(send_queue_); |
| } |
| -void BluetoothSocketMac::Connect( |
| - const base::Closure& success_callback, |
| +void BluetoothSocketMac::ConnectImpl( |
| + IOBluetoothSDPServiceRecord* record, |
| + const ConnectSuccessCallback& success_callback, |
| const ErrorCompletionCallback& error_callback) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -156,14 +166,14 @@ void BluetoothSocketMac::Connect( |
| } |
| uint8 rfcomm_channel_id; |
| - IOReturn status = [record_ getRFCOMMChannelID:&rfcomm_channel_id]; |
| + IOReturn status = [record getRFCOMMChannelID:&rfcomm_channel_id]; |
| if (status != kIOReturnSuccess) { |
| // TODO(youngki) add support for L2CAP sockets as well. |
| error_callback.Run(kL2CAPNotSupported); |
| return; |
| } |
| - IOBluetoothDevice* device = [record_ device]; |
| + IOBluetoothDevice* device = [record device]; |
| IOBluetoothRFCOMMChannel* rfcomm_channel; |
| status = [device openRFCOMMChannelAsync:&rfcomm_channel |
| withChannelID:rfcomm_channel_id |
| @@ -177,10 +187,22 @@ void BluetoothSocketMac::Connect( |
| return; |
| } |
| + AcceptConnectionImpl(rfcomm_channel, success_callback, error_callback); |
| +} |
| + |
| +void BluetoothSocketMac::AcceptConnectionImpl( |
| + IOBluetoothRFCOMMChannel* rfcomm_channel, |
| + const ConnectSuccessCallback& success_callback, |
| + const ErrorCompletionCallback& error_callback) { |
| connect_callbacks_.reset(new ConnectCallbacks()); |
| - connect_callbacks_->success_callback = success_callback; |
| + connect_callbacks_->success_callback = |
| + base::Bind(success_callback, scoped_refptr<BluetoothSocketMac>(this)); |
| connect_callbacks_->error_callback = error_callback; |
| - rfcomm_channel_.reset(rfcomm_channel); |
| + |
| + // Note: It's important to set the connect callbacks *prior* to setting the |
| + // delegate, as setting the delegate can synchronously call into |
| + // OnChannelOpened(). |
| + rfcomm_channel_.reset([rfcomm_channel retain]); |
| [rfcomm_channel_ setDelegate:delegate_]; |
| } |
| @@ -196,7 +218,8 @@ void BluetoothSocketMac::OnChannelOpened( |
| ReleaseChannel(); |
| std::stringstream error; |
| error << "Failed to connect bluetooth socket (" |
| - << base::SysNSStringToUTF8([[record_ device] addressString]) << "): (" |
| + << base::SysNSStringToUTF8( |
| + [[rfcomm_channel_ getDevice] addressString]) << "): (" |
| << status << ")"; |
| temp->error_callback.Run(error.str()); |
| return; |
| @@ -316,7 +339,8 @@ void BluetoothSocketMac::Send(scoped_refptr<net::IOBuffer> buffer, |
| if (status != kIOReturnSuccess) { |
| std::stringstream error; |
| error << "Failed to connect bluetooth socket (" |
| - << base::SysNSStringToUTF8([[record_ device] addressString]) |
| + << base::SysNSStringToUTF8( |
| + [[rfcomm_channel_ getDevice] addressString]) |
| << "): (" << status << ")"; |
| // Remember the first error only |
| if (request->status == kIOReturnSuccess) |
| @@ -371,7 +395,8 @@ void BluetoothSocketMac::OnChannelWriteComplete( |
| if (!request->error_signaled) { |
| std::stringstream error; |
| error << "Failed to connect bluetooth socket (" |
| - << base::SysNSStringToUTF8([[record_ device] addressString]) |
| + << base::SysNSStringToUTF8( |
| + [[rfcomm_channel_ getDevice] addressString]) |
| << "): (" << status << ")"; |
| request->error_signaled = true; |
| request->error_callback.Run(error.str()); |