diff options
author | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 09:06:51 +0000 |
---|---|---|
committer | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 09:06:51 +0000 |
commit | 476f29d45584c022e523b81708775e19df7ab48e (patch) | |
tree | aa83f7e77ceca8bc3037fd99fbad5297ce4f60b9 /device | |
parent | d95e9d1f3d5a55f65c0150735afd7ca291813034 (diff) | |
download | chromium_src-476f29d45584c022e523b81708775e19df7ab48e.zip chromium_src-476f29d45584c022e523b81708775e19df7ab48e.tar.gz chromium_src-476f29d45584c022e523b81708775e19df7ab48e.tar.bz2 |
Implemented BluetoothDeviceMac::ConnectToProfile().
This CL implements BluetoothProfileMac::Connect(), which makes an explicit outgoing connection to the device.
I will add unittests once I get a preliminary review from reviewers.
BUG=229636
Review URL: https://chromiumcodereview.appspot.com/14405008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196099 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r-- | device/bluetooth/bluetooth_device.h | 4 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_chromeos.cc | 1 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_chromeos.h | 1 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_experimental_chromeos.cc | 1 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_experimental_chromeos.h | 1 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_mac.h | 1 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_mac.mm | 9 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_win.cc | 1 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_device_win.h | 1 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_profile.cc | 16 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_profile.h | 3 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_profile_mac.h | 46 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_profile_mac.mm | 80 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_socket_mac.h | 7 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_socket_mac.mm | 39 | ||||
-rw-r--r-- | device/bluetooth/test/mock_bluetooth_device.h | 3 | ||||
-rw-r--r-- | device/device.gyp | 2 |
17 files changed, 209 insertions, 7 deletions
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h index d022ea9..abf15d3 100644 --- a/device/bluetooth/bluetooth_device.h +++ b/device/bluetooth/bluetooth_device.h @@ -321,8 +321,10 @@ class BluetoothDevice { // Attempts to initiate an outgoing connection to this device for the profile // identified by |profile|, on success the profile's connection callback - // wil be called; on failure |error_callback| will be called. + // will be called as well as |callback|; on failure |error_callback| will be + // called. virtual void ConnectToProfile(BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) = 0; // Sets the Out Of Band pairing data for this device to |data|. Exactly one diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc index 9eb3f4a..9d18de0 100644 --- a/device/bluetooth/bluetooth_device_chromeos.cc +++ b/device/bluetooth/bluetooth_device_chromeos.cc @@ -331,6 +331,7 @@ void BluetoothDeviceChromeOS::ConnectToService(const std::string& service_uuid, void BluetoothDeviceChromeOS::ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) { // TODO(keybuk): implement } diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h index 939ca06..baa1f6e 100644 --- a/device/bluetooth/bluetooth_device_chromeos.h +++ b/device/bluetooth/bluetooth_device_chromeos.h @@ -73,6 +73,7 @@ class BluetoothDeviceChromeOS const SocketCallback& callback) OVERRIDE; virtual void ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) OVERRIDE; virtual void SetOutOfBandPairingData( const device::BluetoothOutOfBandPairingData& data, diff --git a/device/bluetooth/bluetooth_device_experimental_chromeos.cc b/device/bluetooth/bluetooth_device_experimental_chromeos.cc index 9183803..09c1ddf 100644 --- a/device/bluetooth/bluetooth_device_experimental_chromeos.cc +++ b/device/bluetooth/bluetooth_device_experimental_chromeos.cc @@ -269,6 +269,7 @@ void BluetoothDeviceExperimentalChromeOS::ConnectToService( void BluetoothDeviceExperimentalChromeOS::ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) { // TODO(keybuk): implement error_callback.Run(); diff --git a/device/bluetooth/bluetooth_device_experimental_chromeos.h b/device/bluetooth/bluetooth_device_experimental_chromeos.h index 8433f8e..a260bec 100644 --- a/device/bluetooth/bluetooth_device_experimental_chromeos.h +++ b/device/bluetooth/bluetooth_device_experimental_chromeos.h @@ -60,6 +60,7 @@ class BluetoothDeviceExperimentalChromeOS const SocketCallback& callback) OVERRIDE; virtual void ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) OVERRIDE; virtual void SetOutOfBandPairingData( const device::BluetoothOutOfBandPairingData& data, diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h index e61676a..81ae518 100644 --- a/device/bluetooth/bluetooth_device_mac.h +++ b/device/bluetooth/bluetooth_device_mac.h @@ -57,6 +57,7 @@ class BluetoothDeviceMac : public BluetoothDevice { const SocketCallback& callback) OVERRIDE; virtual void ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) OVERRIDE; virtual void SetOutOfBandPairingData( const BluetoothOutOfBandPairingData& data, diff --git a/device/bluetooth/bluetooth_device_mac.mm b/device/bluetooth/bluetooth_device_mac.mm index 85d1426..2042eaf 100644 --- a/device/bluetooth/bluetooth_device_mac.mm +++ b/device/bluetooth/bluetooth_device_mac.mm @@ -17,12 +17,13 @@ #include "base/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" +#include "device/bluetooth/bluetooth_profile_mac.h" #include "device/bluetooth/bluetooth_service_record_mac.h" #include "device/bluetooth/bluetooth_socket_mac.h" // Replicate specific 10.7 SDK declarations for building with prior SDKs. #if !defined(MAC_OS_X_VERSION_10_7) || \ -MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 @interface IOBluetoothDevice (LionSDKDeclarations) - (NSString*)addressString; @@ -198,8 +199,12 @@ void BluetoothDeviceMac::ConnectToService( void BluetoothDeviceMac::ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) { - // TODO(keybuk): implement + if (static_cast<BluetoothProfileMac*>(profile)->Connect(device_)) + callback.Run(); + else + error_callback.Run(); } void BluetoothDeviceMac::SetOutOfBandPairingData( diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc index 4af740b..cfe9ac9 100644 --- a/device/bluetooth/bluetooth_device_win.cc +++ b/device/bluetooth/bluetooth_device_win.cc @@ -183,6 +183,7 @@ void BluetoothDeviceWin::ConnectToService( void BluetoothDeviceWin::ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) { // TODO(keybuk): implement } diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h index 89cb78d..be0e257 100644 --- a/device/bluetooth/bluetooth_device_win.h +++ b/device/bluetooth/bluetooth_device_win.h @@ -56,6 +56,7 @@ class BluetoothDeviceWin : public BluetoothDevice { const SocketCallback& callback) OVERRIDE; virtual void ConnectToProfile( device::BluetoothProfile* profile, + const base::Closure& callback, const ErrorCallback& error_callback) OVERRIDE; virtual void SetOutOfBandPairingData( const BluetoothOutOfBandPairingData& data, diff --git a/device/bluetooth/bluetooth_profile.cc b/device/bluetooth/bluetooth_profile.cc index 320979d..73f1128 100644 --- a/device/bluetooth/bluetooth_profile.cc +++ b/device/bluetooth/bluetooth_profile.cc @@ -4,6 +4,11 @@ #include "device/bluetooth/bluetooth_profile.h" +#if defined(OS_MACOSX) +#include "base/mac/mac_util.h" +#include "device/bluetooth/bluetooth_profile_mac.h" +#endif + #include <string> namespace device { @@ -36,9 +41,14 @@ BluetoothProfile::~BluetoothProfile() { void BluetoothProfile::Register(const std::string& uuid, const Options& options, const ProfileCallback& callback) { - // TODO(keybuk): Implement selection of the appropriate BluetoothProfile - // subclass just like BluetoothAdapterFactory - callback.Run(NULL); + BluetoothProfile* profile = NULL; + +#if defined(OS_MACOSX) + if (base::mac::IsOSLionOrLater()) + profile = new BluetoothProfileMac(uuid, options.name); +#endif + + callback.Run(profile); } } // namespace device diff --git a/device/bluetooth/bluetooth_profile.h b/device/bluetooth/bluetooth_profile.h index 306db8fe..466bdf2 100644 --- a/device/bluetooth/bluetooth_profile.h +++ b/device/bluetooth/bluetooth_profile.h @@ -12,6 +12,7 @@ namespace device { +class BluetoothProfileMac; class BluetoothSocket; // BluetoothProfile represents an implementation of either a client or server @@ -95,6 +96,8 @@ class BluetoothProfile { virtual void SetConnectionCallback(const SocketCallback& callback) = 0; private: + friend class BluetoothProfileMac; + BluetoothProfile(); virtual ~BluetoothProfile(); }; diff --git a/device/bluetooth/bluetooth_profile_mac.h b/device/bluetooth/bluetooth_profile_mac.h new file mode 100644 index 0000000..34b6b34 --- /dev/null +++ b/device/bluetooth/bluetooth_profile_mac.h @@ -0,0 +1,46 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_MAC_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_MAC_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "device/bluetooth/bluetooth_profile.h" + +#ifdef __OBJC__ +@class IOBluetoothDevice; +#else +class IOBluetoothDevice; +#endif + +namespace device { + +class BluetoothProfileMac : public BluetoothProfile { + public: + // BluetoothProfile override. + virtual void Unregister() OVERRIDE; + virtual void SetConnectionCallback(const SocketCallback& callback) OVERRIDE; + + // Makes an outgoing connection to |device|. + // This method runs |socket_callback_| with the socket and returns true if the + // connection is made successfully. + bool Connect(IOBluetoothDevice* device); + + private: + friend BluetoothProfile; + + BluetoothProfileMac(const std::string& uuid, const std::string& name); + virtual ~BluetoothProfileMac(); + + const std::string uuid_; + const std::string name_; + SocketCallback socket_callback_; +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_MAC_H_ diff --git a/device/bluetooth/bluetooth_profile_mac.mm b/device/bluetooth/bluetooth_profile_mac.mm new file mode 100644 index 0000000..ca50f06 --- /dev/null +++ b/device/bluetooth/bluetooth_profile_mac.mm @@ -0,0 +1,80 @@ +// Copyright 2013 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_profile_mac.h" + +#import <IOBluetooth/objc/IOBluetoothDevice.h> +#import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h> +#import <IOBluetooth/objc/IOBluetoothSDPUUID.h> + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/string_number_conversions.h" +#include "device/bluetooth/bluetooth_device_mac.h" +#include "device/bluetooth/bluetooth_socket_mac.h" + +namespace { + +// Converts |uuid| to a IOBluetoothSDPUUID instance. +// +// |uuid| must be in the format of XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. +IOBluetoothSDPUUID* GetIOBluetoothSDPUUID(const std::string& uuid) { + DCHECK(uuid.size() == 36); + DCHECK(uuid[8] == '-'); + DCHECK(uuid[13] == '-'); + DCHECK(uuid[18] == '-'); + DCHECK(uuid[23] == '-'); + std::string numbers_only = uuid; + numbers_only.erase(23, 1); + numbers_only.erase(18, 1); + numbers_only.erase(13, 1); + numbers_only.erase(8, 1); + std::vector<uint8> uuid_bytes_vector; + base::HexStringToBytes(numbers_only, &uuid_bytes_vector); + DCHECK(uuid_bytes_vector.size() == 16); + + return [IOBluetoothSDPUUID uuidWithBytes:&uuid_bytes_vector[0] + length:uuid_bytes_vector.size()]; +} + +} // namespace + +namespace device { + +BluetoothProfileMac::BluetoothProfileMac(const std::string& uuid, + const std::string& name) + : BluetoothProfile(), uuid_(uuid), name_(name) { +} + +BluetoothProfileMac::~BluetoothProfileMac() { +} + +void BluetoothProfileMac::Unregister() { + delete this; +} + +void BluetoothProfileMac::SetConnectionCallback( + const SocketCallback& callback) { + socket_callback_ = callback; +} + +bool BluetoothProfileMac::Connect(IOBluetoothDevice* device) { + IOBluetoothSDPServiceRecord* record = + [device getServiceRecordForUUID:GetIOBluetoothSDPUUID(uuid_)]; + if (record != nil) { + scoped_refptr<BluetoothSocket> socket( + BluetoothSocketMac::CreateBluetoothSocket(record)); + if (socket.get() != NULL) { + socket_callback_.Run(socket); + return true; + } + } + return false; +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_socket_mac.h b/device/bluetooth/bluetooth_socket_mac.h index 5689a42..4d7bfb7 100644 --- a/device/bluetooth/bluetooth_socket_mac.h +++ b/device/bluetooth/bluetooth_socket_mac.h @@ -13,9 +13,11 @@ #ifdef __OBJC__ @class BluetoothRFCOMMChannelDelegate; @class IOBluetoothRFCOMMChannel; +@class IOBluetoothSDPServiceRecord; #else class BluetoothRFCOMMChannelDelegate; class IOBluetoothRFCOMMChannel; +class IOBluetoothSDPServiceRecord; #endif namespace net { @@ -32,9 +34,14 @@ class BluetoothServiceRecord; // This class is an implementation of BluetoothSocket class for OSX platform. class BluetoothSocketMac : public BluetoothSocket { public: + // TODO(youngki): This method is deprecated; remove this method when + // BluetoothServiceRecord is removed. static scoped_refptr<BluetoothSocket> CreateBluetoothSocket( const BluetoothServiceRecord& service_record); + static scoped_refptr<BluetoothSocket> CreateBluetoothSocket( + IOBluetoothSDPServiceRecord* record); + // BluetoothSocket override virtual bool Receive(net::GrowableIOBuffer* buffer) OVERRIDE; virtual bool Send(net::DrainableIOBuffer* buffer) OVERRIDE; diff --git a/device/bluetooth/bluetooth_socket_mac.mm b/device/bluetooth/bluetooth_socket_mac.mm index 31a797c..036f6f1 100644 --- a/device/bluetooth/bluetooth_socket_mac.mm +++ b/device/bluetooth/bluetooth_socket_mac.mm @@ -6,16 +6,29 @@ #import <IOBluetooth/objc/IOBluetoothDevice.h> #import <IOBluetooth/objc/IOBluetoothRFCOMMChannel.h> +#import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h> #include <limits> #include <string> +#include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/stringprintf.h" +#include "base/strings/sys_string_conversions.h" #include "device/bluetooth/bluetooth_service_record.h" #include "device/bluetooth/bluetooth_service_record_mac.h" #include "net/base/io_buffer.h" +// Replicate specific 10.7 SDK declarations for building with prior SDKs. +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface IOBluetoothDevice (LionSDKDeclarations) +- (NSString*)addressString; +@end + +#endif // MAC_OS_X_VERSION_10_7 + @interface BluetoothRFCOMMChannelDelegate : NSObject <IOBluetoothRFCOMMChannelDelegate> { @private @@ -84,6 +97,32 @@ scoped_refptr<BluetoothSocket> BluetoothSocketMac::CreateBluetoothSocket( return scoped_refptr<BluetoothSocketMac>(bluetooth_socket); } +// static +scoped_refptr<BluetoothSocket> BluetoothSocketMac::CreateBluetoothSocket( + IOBluetoothSDPServiceRecord* record) { + BluetoothSocketMac* bluetooth_socket = NULL; + uint8 rfcomm_channel_id; + if ([record getRFCOMMChannelID:&rfcomm_channel_id] == kIOReturnSuccess) { + IOBluetoothDevice* device = [record device]; + IOBluetoothRFCOMMChannel* rfcomm_channel; + IOReturn status = + [device openRFCOMMChannelAsync:&rfcomm_channel + withChannelID:rfcomm_channel_id + delegate:nil]; + if (status == kIOReturnSuccess) { + bluetooth_socket = new BluetoothSocketMac(rfcomm_channel); + } else { + LOG(ERROR) << "Failed to connect bluetooth socket (" + << base::SysNSStringToUTF8([device addressString]) << "): (" << status + << ")"; + } + } + + // TODO(youngki): Add support for L2CAP sockets as well. + + return scoped_refptr<BluetoothSocketMac>(bluetooth_socket); +} + bool BluetoothSocketMac::Receive(net::GrowableIOBuffer* buffer) { CHECK(buffer->offset() == 0); int length = incoming_data_buffer_->offset(); diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h index c742d8e..b2b93d5 100644 --- a/device/bluetooth/test/mock_bluetooth_device.h +++ b/device/bluetooth/test/mock_bluetooth_device.h @@ -63,8 +63,9 @@ class MockBluetoothDevice : public BluetoothDevice { MOCK_METHOD2(ConnectToService, void(const std::string&, const BluetoothDevice::SocketCallback&)); - MOCK_METHOD2(ConnectToProfile, + MOCK_METHOD3(ConnectToProfile, void(BluetoothProfile*, + const base::Closure&, const BluetoothDevice::ErrorCallback&)); MOCK_METHOD3(SetOutOfBandPairingData, diff --git a/device/device.gyp b/device/device.gyp index 3a8c87a..3f3d010 100644 --- a/device/device.gyp +++ b/device/device.gyp @@ -46,6 +46,8 @@ 'bluetooth/bluetooth_out_of_band_pairing_data.h', 'bluetooth/bluetooth_profile.cc', 'bluetooth/bluetooth_profile.h', + 'bluetooth/bluetooth_profile_mac.h', + 'bluetooth/bluetooth_profile_mac.mm', 'bluetooth/bluetooth_service_record.cc', 'bluetooth/bluetooth_service_record.h', 'bluetooth/bluetooth_service_record_chromeos.cc', |