| 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_profile_mac.h" | 5 #include "device/bluetooth/bluetooth_profile_mac.h" |
| 6 | 6 |
| 7 #import <IOBluetooth/objc/IOBluetoothDevice.h> | 7 #import <IOBluetooth/objc/IOBluetoothDevice.h> |
| 8 #import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h> | 8 #import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h> |
| 9 #import <IOBluetooth/objc/IOBluetoothSDPUUID.h> | 9 #import <IOBluetooth/objc/IOBluetoothSDPUUID.h> |
| 10 | 10 |
| 11 #include <string> | 11 #include <string> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 15 #include "base/bind.h" |
| 16 #include "base/location.h" |
| 15 #include "base/logging.h" | 17 #include "base/logging.h" |
| 16 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
| 17 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/sys_string_conversions.h" |
| 21 #include "base/thread_task_runner_handle.h" |
| 22 #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 18 #include "device/bluetooth/bluetooth_device_mac.h" | 23 #include "device/bluetooth/bluetooth_device_mac.h" |
| 19 #include "device/bluetooth/bluetooth_socket_mac.h" | 24 #include "device/bluetooth/bluetooth_socket_mac.h" |
| 20 | 25 |
| 26 // Replicate specific 10.7 SDK declarations for building with prior SDKs. |
| 27 #if !defined(MAC_OS_X_VERSION_10_7) || \ |
| 28 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 |
| 29 |
| 30 @interface IOBluetoothDevice (LionSDKDeclarations) |
| 31 - (NSString*)addressString; |
| 32 @end |
| 33 |
| 34 #endif // MAC_OS_X_VERSION_10_7 |
| 35 |
| 21 namespace { | 36 namespace { |
| 22 | 37 |
| 38 const char kNoConnectionCallback[] = "Connection callback not set"; |
| 39 const char kProfileNotFound[] = "Profile not found"; |
| 40 |
| 23 // Converts |uuid| to a IOBluetoothSDPUUID instance. | 41 // Converts |uuid| to a IOBluetoothSDPUUID instance. |
| 24 // | 42 // |
| 25 // |uuid| must be in the format of XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. | 43 // |uuid| must be in the format of XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. |
| 26 IOBluetoothSDPUUID* GetIOBluetoothSDPUUID(const std::string& uuid) { | 44 IOBluetoothSDPUUID* GetIOBluetoothSDPUUID(const std::string& uuid) { |
| 27 DCHECK(uuid.size() == 36); | 45 DCHECK(uuid.size() == 36); |
| 28 DCHECK(uuid[8] == '-'); | 46 DCHECK(uuid[8] == '-'); |
| 29 DCHECK(uuid[13] == '-'); | 47 DCHECK(uuid[13] == '-'); |
| 30 DCHECK(uuid[18] == '-'); | 48 DCHECK(uuid[18] == '-'); |
| 31 DCHECK(uuid[23] == '-'); | 49 DCHECK(uuid[23] == '-'); |
| 32 std::string numbers_only = uuid; | 50 std::string numbers_only = uuid; |
| 33 numbers_only.erase(23, 1); | 51 numbers_only.erase(23, 1); |
| 34 numbers_only.erase(18, 1); | 52 numbers_only.erase(18, 1); |
| 35 numbers_only.erase(13, 1); | 53 numbers_only.erase(13, 1); |
| 36 numbers_only.erase(8, 1); | 54 numbers_only.erase(8, 1); |
| 37 std::vector<uint8> uuid_bytes_vector; | 55 std::vector<uint8> uuid_bytes_vector; |
| 38 base::HexStringToBytes(numbers_only, &uuid_bytes_vector); | 56 base::HexStringToBytes(numbers_only, &uuid_bytes_vector); |
| 39 DCHECK(uuid_bytes_vector.size() == 16); | 57 DCHECK(uuid_bytes_vector.size() == 16); |
| 40 | 58 |
| 41 return [IOBluetoothSDPUUID uuidWithBytes:&uuid_bytes_vector[0] | 59 return [IOBluetoothSDPUUID uuidWithBytes:&uuid_bytes_vector[0] |
| 42 length:uuid_bytes_vector.size()]; | 60 length:uuid_bytes_vector.size()]; |
| 43 } | 61 } |
| 44 | 62 |
| 63 void OnSocketConnectUI( |
| 64 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
| 65 scoped_refptr<device::BluetoothSocketMac> socket, |
| 66 const base::Closure& success_callback, |
| 67 const device::BluetoothProfileMac::ErrorCallback& error_callback) { |
| 68 DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); |
| 69 socket->Connect(success_callback, error_callback); |
| 70 } |
| 71 |
| 72 void OnConnectSuccessUIWithAdapter( |
| 73 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
| 74 const base::Closure& callback, |
| 75 const device::BluetoothProfileMac::ConnectionCallback& connection_callback, |
| 76 const std::string& device_address, |
| 77 scoped_refptr<device::BluetoothSocketMac> socket, |
| 78 scoped_refptr<device::BluetoothAdapter> adapter) { |
| 79 DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); |
| 80 const device::BluetoothDevice* device = adapter->GetDevice(device_address); |
| 81 if (device) { |
| 82 connection_callback.Run(device, socket); |
| 83 callback.Run(); |
| 84 } |
| 85 } |
| 86 |
| 87 void OnConnectSuccessUI( |
| 88 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
| 89 const base::Closure& callback, |
| 90 const device::BluetoothProfileMac::ConnectionCallback& connection_callback, |
| 91 const std::string& device_address, |
| 92 scoped_refptr<device::BluetoothSocketMac> socket) { |
| 93 DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); |
| 94 device::BluetoothAdapterFactory::GetAdapter( |
| 95 base::Bind(&OnConnectSuccessUIWithAdapter, |
| 96 ui_task_runner, |
| 97 callback, |
| 98 connection_callback, |
| 99 device_address, |
| 100 socket)); |
| 101 } |
| 102 |
| 103 void OnConnectErrorUI( |
| 104 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, |
| 105 const device::BluetoothProfileMac::ErrorCallback& error_callback, |
| 106 const std::string& error) { |
| 107 DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); |
| 108 error_callback.Run(error); |
| 109 } |
| 110 |
| 45 } // namespace | 111 } // namespace |
| 46 | 112 |
| 47 namespace device { | 113 namespace device { |
| 48 | 114 |
| 49 BluetoothProfileMac::BluetoothProfileMac(const BluetoothUUID& uuid, | 115 BluetoothProfileMac::BluetoothProfileMac(const BluetoothUUID& uuid, |
| 50 const std::string& name) | 116 const std::string& name) |
| 51 : BluetoothProfile(), uuid_(uuid), name_(name) { | 117 : BluetoothProfile(), uuid_(uuid), name_(name) { |
| 52 } | 118 } |
| 53 | 119 |
| 54 BluetoothProfileMac::~BluetoothProfileMac() { | 120 BluetoothProfileMac::~BluetoothProfileMac() { |
| 55 } | 121 } |
| 56 | 122 |
| 57 void BluetoothProfileMac::Unregister() { | 123 void BluetoothProfileMac::Unregister() { |
| 58 delete this; | 124 delete this; |
| 59 } | 125 } |
| 60 | 126 |
| 61 void BluetoothProfileMac::SetConnectionCallback( | 127 void BluetoothProfileMac::SetConnectionCallback( |
| 62 const ConnectionCallback& callback) { | 128 const ConnectionCallback& callback) { |
| 63 connection_callback_ = callback; | 129 connection_callback_ = callback; |
| 64 } | 130 } |
| 65 | 131 |
| 66 bool BluetoothProfileMac::Connect(IOBluetoothDevice* device) { | 132 void BluetoothProfileMac::Connect( |
| 67 if (connection_callback_.is_null()) | 133 const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner, |
| 68 return false; | 134 IOBluetoothDevice* device, |
| 135 const base::Closure& success_callback, |
| 136 const ErrorCallback& error_callback) { |
| 137 DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); |
| 138 if (connection_callback_.is_null()) { |
| 139 error_callback.Run(kNoConnectionCallback); |
| 140 return; |
| 141 } |
| 69 | 142 |
| 70 IOBluetoothSDPServiceRecord* record = | 143 IOBluetoothSDPServiceRecord* record = [device |
| 71 [device getServiceRecordForUUID:GetIOBluetoothSDPUUID( | 144 getServiceRecordForUUID:GetIOBluetoothSDPUUID(uuid_.canonical_value())]; |
| 72 uuid_.canonical_value())]; | 145 if (record == nil) { |
| 73 if (record != nil) { | 146 error_callback.Run(kProfileNotFound); |
| 74 scoped_refptr<BluetoothSocket> socket( | 147 return; |
| 75 BluetoothSocketMac::CreateBluetoothSocket(record)); | |
| 76 if (socket.get() != NULL) { | |
| 77 BluetoothDeviceMac device_mac(device); | |
| 78 connection_callback_.Run(&device_mac, socket); | |
| 79 return true; | |
| 80 } | |
| 81 } | 148 } |
| 82 return false; | 149 |
| 150 std::string device_address = base::SysNSStringToUTF8([device addressString]); |
| 151 scoped_refptr<BluetoothSocketMac> socket( |
| 152 BluetoothSocketMac::CreateBluetoothSocket(ui_task_runner, record)); |
| 153 OnSocketConnectUI( |
| 154 ui_task_runner, |
| 155 socket, |
| 156 base::Bind(OnConnectSuccessUI, |
| 157 ui_task_runner, |
| 158 success_callback, |
| 159 connection_callback_, |
| 160 device_address, |
| 161 socket), |
| 162 base::Bind(OnConnectErrorUI, ui_task_runner, error_callback)); |
| 83 } | 163 } |
| 84 | 164 |
| 85 } // namespace device | 165 } // namespace device |
| OLD | NEW |