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 |