OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/bluetooth/bluetooth_api.h" | 5 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h" |
6 | 6 |
7 #if defined(OS_CHROMEOS) | 7 #if defined(OS_CHROMEOS) |
8 #include <errno.h> | 8 #include <errno.h> |
9 #endif | 9 #endif |
10 | 10 |
11 #include <string> | 11 #include <string> |
12 | 12 |
| 13 #include "base/memory/ref_counted.h" |
13 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" | 14 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" |
| 15 #include "chrome/browser/extensions/bluetooth_event_router.h" |
14 #include "chrome/browser/extensions/event_names.h" | 16 #include "chrome/browser/extensions/event_names.h" |
15 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
16 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
17 #include "chrome/common/extensions/api/experimental_bluetooth.h" | 19 #include "chrome/common/extensions/api/experimental_bluetooth.h" |
18 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "device/bluetooth/bluetooth_adapter.h" |
| 22 #include "device/bluetooth/bluetooth_device.h" |
| 23 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" |
| 24 #include "device/bluetooth/bluetooth_service_record.h" |
| 25 #include "device/bluetooth/bluetooth_socket.h" |
| 26 #include "device/bluetooth/bluetooth_utils.h" |
19 | 27 |
20 #if defined(OS_CHROMEOS) | 28 #if defined(OS_CHROMEOS) |
21 #include "base/memory/ref_counted.h" | |
22 #include "base/safe_strerror_posix.h" | 29 #include "base/safe_strerror_posix.h" |
23 #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" | 30 #endif |
24 #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" | 31 |
25 #include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" | 32 using bluetooth::BluetoothAdapter; |
26 #include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" | 33 using bluetooth::BluetoothDevice; |
27 #include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" | 34 using bluetooth::BluetoothSocket; |
28 #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" | |
29 #include "chromeos/dbus/bluetooth_out_of_band_client.h" | |
30 #include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" | |
31 | 35 |
32 namespace { | 36 namespace { |
33 | 37 |
34 chromeos::ExtensionBluetoothEventRouter* GetEventRouter(Profile* profile) { | 38 extensions::ExtensionBluetoothEventRouter* GetEventRouter(Profile* profile) { |
35 return profile->GetExtensionService()->bluetooth_event_router(); | 39 return profile->GetExtensionService()->bluetooth_event_router(); |
36 } | 40 } |
37 | 41 |
38 const chromeos::BluetoothAdapter& GetAdapter(Profile* profile) { | 42 const BluetoothAdapter* GetAdapter(Profile* profile) { |
39 return GetEventRouter(profile)->adapter(); | 43 return GetEventRouter(profile)->adapter(); |
40 } | 44 } |
41 | 45 |
42 chromeos::BluetoothAdapter* GetMutableAdapter(Profile* profile) { | 46 BluetoothAdapter* GetMutableAdapter(Profile* profile) { |
43 chromeos::BluetoothAdapter* adapter = | 47 BluetoothAdapter* adapter = GetEventRouter(profile)->GetMutableAdapter(); |
44 GetEventRouter(profile)->GetMutableAdapter(); | |
45 CHECK(adapter); | |
46 return adapter; | 48 return adapter; |
47 } | 49 } |
48 | 50 |
| 51 bool IsBluetoothSupported(Profile* profile) { |
| 52 return GetAdapter(profile) != NULL; |
| 53 } |
| 54 |
49 } // namespace | 55 } // namespace |
50 #endif | |
51 | 56 |
52 namespace { | 57 namespace { |
53 | 58 |
54 const char kCouldNotGetLocalOutOfBandPairingData[] = | 59 const char kCouldNotGetLocalOutOfBandPairingData[] = |
55 "Could not get local Out Of Band Pairing Data"; | 60 "Could not get local Out Of Band Pairing Data"; |
56 const char kCouldNotSetOutOfBandPairingData[] = | 61 const char kCouldNotSetOutOfBandPairingData[] = |
57 "Could not set Out Of Band Pairing Data"; | 62 "Could not set Out Of Band Pairing Data"; |
58 const char kFailedToConnect[] = "Connection failed"; | 63 const char kFailedToConnect[] = "Connection failed"; |
59 const char kInvalidDevice[] = "Invalid device"; | 64 const char kInvalidDevice[] = "Invalid device"; |
60 const char kInvalidUuid[] = "Invalid UUID"; | 65 const char kInvalidUuid[] = "Invalid UUID"; |
| 66 const char kPlatformNotSupported[] = |
| 67 "This operation is not supported on your platform"; |
61 const char kServiceDiscoveryFailed[] = "Service discovery failed"; | 68 const char kServiceDiscoveryFailed[] = "Service discovery failed"; |
62 const char kSocketNotFoundError[] = "Socket not found: invalid socket id"; | 69 const char kSocketNotFoundError[] = "Socket not found: invalid socket id"; |
63 const char kStartDiscoveryFailed[] = "Starting discovery failed"; | 70 const char kStartDiscoveryFailed[] = "Starting discovery failed"; |
64 const char kStopDiscoveryFailed[] = "Failed to stop discovery"; | 71 const char kStopDiscoveryFailed[] = "Failed to stop discovery"; |
65 | 72 |
66 } // namespace | 73 } // namespace |
67 | 74 |
68 namespace Connect = extensions::api::experimental_bluetooth::Connect; | 75 namespace Connect = extensions::api::experimental_bluetooth::Connect; |
69 namespace Disconnect = extensions::api::experimental_bluetooth::Disconnect; | 76 namespace Disconnect = extensions::api::experimental_bluetooth::Disconnect; |
70 namespace GetDevices = extensions::api::experimental_bluetooth::GetDevices; | 77 namespace GetDevices = extensions::api::experimental_bluetooth::GetDevices; |
71 namespace GetServices = extensions::api::experimental_bluetooth::GetServices; | 78 namespace GetServices = extensions::api::experimental_bluetooth::GetServices; |
72 namespace Read = extensions::api::experimental_bluetooth::Read; | 79 namespace Read = extensions::api::experimental_bluetooth::Read; |
73 namespace SetOutOfBandPairingData = | 80 namespace SetOutOfBandPairingData = |
74 extensions::api::experimental_bluetooth::SetOutOfBandPairingData; | 81 extensions::api::experimental_bluetooth::SetOutOfBandPairingData; |
75 namespace Write = extensions::api::experimental_bluetooth::Write; | 82 namespace Write = extensions::api::experimental_bluetooth::Write; |
76 | 83 |
77 namespace extensions { | 84 namespace extensions { |
78 namespace api { | 85 namespace api { |
79 | 86 |
80 #if defined(OS_CHROMEOS) | 87 bool BluetoothIsAvailableFunction::RunImpl() { |
| 88 if (!IsBluetoothSupported(profile())) { |
| 89 SetError(kPlatformNotSupported); |
| 90 return false; |
| 91 } |
81 | 92 |
82 bool BluetoothIsAvailableFunction::RunImpl() { | 93 SetResult(Value::CreateBooleanValue(GetAdapter(profile())->IsPresent())); |
83 SetResult(Value::CreateBooleanValue(GetAdapter(profile()).IsPresent())); | |
84 return true; | 94 return true; |
85 } | 95 } |
86 | 96 |
87 bool BluetoothIsPoweredFunction::RunImpl() { | 97 bool BluetoothIsPoweredFunction::RunImpl() { |
88 SetResult(Value::CreateBooleanValue(GetAdapter(profile()).IsPowered())); | 98 if (!IsBluetoothSupported(profile())) { |
| 99 SetError(kPlatformNotSupported); |
| 100 return false; |
| 101 } |
| 102 |
| 103 SetResult(Value::CreateBooleanValue(GetAdapter(profile())->IsPowered())); |
89 return true; | 104 return true; |
90 } | 105 } |
91 | 106 |
92 bool BluetoothGetAddressFunction::RunImpl() { | 107 bool BluetoothGetAddressFunction::RunImpl() { |
93 SetResult(Value::CreateStringValue(GetAdapter(profile()).address())); | 108 if (!IsBluetoothSupported(profile())) { |
| 109 SetError(kPlatformNotSupported); |
| 110 return false; |
| 111 } |
| 112 |
| 113 SetResult(Value::CreateStringValue(GetAdapter(profile())->address())); |
94 return true; | 114 return true; |
95 } | 115 } |
96 | 116 |
97 bool BluetoothGetNameFunction::RunImpl() { | 117 bool BluetoothGetNameFunction::RunImpl() { |
98 SetResult(Value::CreateStringValue(GetAdapter(profile()).name())); | 118 if (!IsBluetoothSupported(profile())) { |
| 119 SetError(kPlatformNotSupported); |
| 120 return false; |
| 121 } |
| 122 |
| 123 SetResult(Value::CreateStringValue(GetAdapter(profile())->name())); |
99 return true; | 124 return true; |
100 } | 125 } |
101 | 126 |
102 BluetoothGetDevicesFunction::BluetoothGetDevicesFunction() | 127 BluetoothGetDevicesFunction::BluetoothGetDevicesFunction() |
103 : callbacks_pending_(0) {} | 128 : callbacks_pending_(0) {} |
104 | 129 |
105 void BluetoothGetDevicesFunction::DispatchDeviceSearchResult( | 130 void BluetoothGetDevicesFunction::DispatchDeviceSearchResult( |
106 const chromeos::BluetoothDevice& device) { | 131 const BluetoothDevice& device) { |
107 experimental_bluetooth::Device extension_device; | 132 experimental_bluetooth::Device extension_device; |
108 experimental_bluetooth::BluetoothDeviceToApiDevice(device, &extension_device); | 133 experimental_bluetooth::BluetoothDeviceToApiDevice(device, &extension_device); |
109 GetEventRouter(profile())->DispatchDeviceEvent( | 134 GetEventRouter(profile())->DispatchDeviceEvent( |
110 extensions::event_names::kBluetoothOnDeviceSearchResult, | 135 extensions::event_names::kBluetoothOnDeviceSearchResult, |
111 extension_device); | 136 extension_device); |
112 } | 137 } |
113 | 138 |
114 void BluetoothGetDevicesFunction::ProvidesServiceCallback( | 139 void BluetoothGetDevicesFunction::ProvidesServiceCallback( |
115 const chromeos::BluetoothDevice* device, | 140 const BluetoothDevice* device, bool providesService) { |
116 bool providesService) { | |
117 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 141 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
118 | 142 |
119 CHECK(device); | 143 CHECK(device); |
120 if (providesService) | 144 if (providesService) |
121 DispatchDeviceSearchResult(*device); | 145 DispatchDeviceSearchResult(*device); |
122 | 146 |
123 callbacks_pending_--; | 147 callbacks_pending_--; |
124 if (callbacks_pending_ == -1) | 148 if (callbacks_pending_ == -1) |
125 SendResponse(true); | 149 SendResponse(true); |
126 } | 150 } |
127 | 151 |
128 bool BluetoothGetDevicesFunction::RunImpl() { | 152 bool BluetoothGetDevicesFunction::RunImpl() { |
| 153 if (!IsBluetoothSupported(profile())) { |
| 154 SetError(kPlatformNotSupported); |
| 155 return false; |
| 156 } |
| 157 |
129 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 158 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
130 | 159 |
131 scoped_ptr<GetDevices::Params> params(GetDevices::Params::Create(*args_)); | 160 scoped_ptr<GetDevices::Params> params(GetDevices::Params::Create(*args_)); |
132 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 161 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
133 const experimental_bluetooth::GetDevicesOptions& options = params->options; | 162 const experimental_bluetooth::GetDevicesOptions& options = params->options; |
134 | 163 |
135 std::string uuid; | 164 std::string uuid; |
136 if (options.uuid.get() != NULL) { | 165 if (options.uuid.get() != NULL) { |
137 uuid = chromeos::bluetooth_utils::CanonicalUuid(*options.uuid.get()); | 166 uuid = bluetooth::utils::CanonicalUuid(*options.uuid.get()); |
138 if (uuid.empty()) { | 167 if (uuid.empty()) { |
139 SetError(kInvalidUuid); | 168 SetError(kInvalidUuid); |
140 return false; | 169 return false; |
141 } | 170 } |
142 } | 171 } |
143 | 172 |
144 CHECK_EQ(0, callbacks_pending_); | 173 CHECK_EQ(0, callbacks_pending_); |
145 | 174 |
146 chromeos::BluetoothAdapter::DeviceList devices = | 175 BluetoothAdapter::DeviceList devices = |
147 GetMutableAdapter(profile())->GetDevices(); | 176 GetMutableAdapter(profile())->GetDevices(); |
148 for (chromeos::BluetoothAdapter::DeviceList::iterator i = devices.begin(); | 177 for (BluetoothAdapter::DeviceList::iterator i = devices.begin(); |
149 i != devices.end(); ++i) { | 178 i != devices.end(); ++i) { |
150 chromeos::BluetoothDevice* device = *i; | 179 BluetoothDevice* device = *i; |
151 CHECK(device); | 180 CHECK(device); |
152 | 181 |
153 if (!uuid.empty() && !(device->ProvidesServiceWithUUID(uuid))) | 182 if (!uuid.empty() && !(device->ProvidesServiceWithUUID(uuid))) |
154 continue; | 183 continue; |
155 | 184 |
156 if (options.name.get() == NULL) { | 185 if (options.name.get() == NULL) { |
157 DispatchDeviceSearchResult(*device); | 186 DispatchDeviceSearchResult(*device); |
158 continue; | 187 continue; |
159 } | 188 } |
160 | 189 |
(...skipping 10 matching lines...) Expand all Loading... |
171 // for-loop, which ensures that all requests have been made before | 200 // for-loop, which ensures that all requests have been made before |
172 // SendResponse happens. | 201 // SendResponse happens. |
173 if (callbacks_pending_ == -1) | 202 if (callbacks_pending_ == -1) |
174 SendResponse(true); | 203 SendResponse(true); |
175 | 204 |
176 return true; | 205 return true; |
177 } | 206 } |
178 | 207 |
179 void BluetoothGetServicesFunction::GetServiceRecordsCallback( | 208 void BluetoothGetServicesFunction::GetServiceRecordsCallback( |
180 base::ListValue* services, | 209 base::ListValue* services, |
181 const chromeos::BluetoothDevice::ServiceRecordList& records) { | 210 const BluetoothDevice::ServiceRecordList& records) { |
182 for (chromeos::BluetoothDevice::ServiceRecordList::const_iterator i = | 211 for (BluetoothDevice::ServiceRecordList::const_iterator i = records.begin(); |
183 records.begin(); i != records.end(); ++i) { | 212 i != records.end(); ++i) { |
184 const chromeos::BluetoothServiceRecord& record = **i; | 213 const bluetooth::BluetoothServiceRecord& record = **i; |
185 experimental_bluetooth::ServiceRecord api_record; | 214 experimental_bluetooth::ServiceRecord api_record; |
186 api_record.name = record.name(); | 215 api_record.name = record.name(); |
187 if (!record.uuid().empty()) | 216 if (!record.uuid().empty()) |
188 api_record.uuid.reset(new std::string(record.uuid())); | 217 api_record.uuid.reset(new std::string(record.uuid())); |
189 services->Append(api_record.ToValue().release()); | 218 services->Append(api_record.ToValue().release()); |
190 } | 219 } |
191 | 220 |
192 SendResponse(true); | 221 SendResponse(true); |
193 } | 222 } |
194 | 223 |
195 void BluetoothGetServicesFunction::OnErrorCallback() { | 224 void BluetoothGetServicesFunction::OnErrorCallback() { |
196 SetError(kServiceDiscoveryFailed); | 225 SetError(kServiceDiscoveryFailed); |
197 SendResponse(false); | 226 SendResponse(false); |
198 } | 227 } |
199 | 228 |
200 bool BluetoothGetServicesFunction::RunImpl() { | 229 bool BluetoothGetServicesFunction::RunImpl() { |
| 230 if (!IsBluetoothSupported(profile())) { |
| 231 SetError(kPlatformNotSupported); |
| 232 return false; |
| 233 } |
| 234 |
201 scoped_ptr<GetServices::Params> params(GetServices::Params::Create(*args_)); | 235 scoped_ptr<GetServices::Params> params(GetServices::Params::Create(*args_)); |
202 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 236 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
203 const experimental_bluetooth::GetServicesOptions& options = params->options; | 237 const experimental_bluetooth::GetServicesOptions& options = params->options; |
204 | 238 |
205 chromeos::BluetoothDevice* device = | 239 BluetoothDevice* device = |
206 GetMutableAdapter(profile())->GetDevice(options.device_address); | 240 GetMutableAdapter(profile())->GetDevice(options.device_address); |
207 if (!device) { | 241 if (!device) { |
208 SetError(kInvalidDevice); | 242 SetError(kInvalidDevice); |
209 return false; | 243 return false; |
210 } | 244 } |
211 | 245 |
212 ListValue* services = new ListValue; | 246 ListValue* services = new ListValue; |
213 SetResult(services); | 247 SetResult(services); |
214 | 248 |
215 device->GetServiceRecords( | 249 device->GetServiceRecords( |
216 base::Bind(&BluetoothGetServicesFunction::GetServiceRecordsCallback, | 250 base::Bind(&BluetoothGetServicesFunction::GetServiceRecordsCallback, |
217 this, | 251 this, |
218 services), | 252 services), |
219 base::Bind(&BluetoothGetServicesFunction::OnErrorCallback, | 253 base::Bind(&BluetoothGetServicesFunction::OnErrorCallback, |
220 this)); | 254 this)); |
221 | 255 |
222 return true; | 256 return true; |
223 } | 257 } |
224 | 258 |
225 void BluetoothConnectFunction::ConnectToServiceCallback( | 259 void BluetoothConnectFunction::ConnectToServiceCallback( |
226 const chromeos::BluetoothDevice* device, | 260 const BluetoothDevice* device, |
227 const std::string& service_uuid, | 261 const std::string& service_uuid, |
228 scoped_refptr<chromeos::BluetoothSocket> socket) { | 262 scoped_refptr<BluetoothSocket> socket) { |
229 if (socket.get()) { | 263 if (socket.get()) { |
230 int socket_id = GetEventRouter(profile())->RegisterSocket(socket); | 264 int socket_id = GetEventRouter(profile())->RegisterSocket(socket); |
231 | 265 |
232 experimental_bluetooth::Socket result_socket; | 266 experimental_bluetooth::Socket result_socket; |
233 experimental_bluetooth::BluetoothDeviceToApiDevice( | 267 experimental_bluetooth::BluetoothDeviceToApiDevice( |
234 *device, &result_socket.device); | 268 *device, &result_socket.device); |
235 result_socket.service_uuid = service_uuid; | 269 result_socket.service_uuid = service_uuid; |
236 result_socket.id = socket_id; | 270 result_socket.id = socket_id; |
237 SetResult(result_socket.ToValue().release()); | 271 SetResult(result_socket.ToValue().release()); |
238 SendResponse(true); | 272 SendResponse(true); |
239 } else { | 273 } else { |
240 SetError(kFailedToConnect); | 274 SetError(kFailedToConnect); |
241 SendResponse(false); | 275 SendResponse(false); |
242 } | 276 } |
243 } | 277 } |
244 | 278 |
245 bool BluetoothConnectFunction::RunImpl() { | 279 bool BluetoothConnectFunction::RunImpl() { |
| 280 if (!IsBluetoothSupported(profile())) { |
| 281 SetError(kPlatformNotSupported); |
| 282 return false; |
| 283 } |
| 284 |
246 scoped_ptr<Connect::Params> params(Connect::Params::Create(*args_)); | 285 scoped_ptr<Connect::Params> params(Connect::Params::Create(*args_)); |
247 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 286 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
248 const experimental_bluetooth::ConnectOptions& options = params->options; | 287 const experimental_bluetooth::ConnectOptions& options = params->options; |
249 | 288 |
250 std::string uuid = chromeos::bluetooth_utils::CanonicalUuid( | 289 std::string uuid = bluetooth::utils::CanonicalUuid( |
251 options.service_uuid); | 290 options.service_uuid); |
252 if (uuid.empty()) { | 291 if (uuid.empty()) { |
253 SetError(kInvalidUuid); | 292 SetError(kInvalidUuid); |
254 return false; | 293 return false; |
255 } | 294 } |
256 | 295 |
257 chromeos::BluetoothDevice* device = | 296 BluetoothDevice* device = |
258 GetMutableAdapter(profile())->GetDevice(options.device_address); | 297 GetMutableAdapter(profile())->GetDevice(options.device_address); |
259 if (!device) { | 298 if (!device) { |
260 SetError(kInvalidDevice); | 299 SetError(kInvalidDevice); |
261 return false; | 300 return false; |
262 } | 301 } |
263 | 302 |
264 device->ConnectToService(uuid, | 303 device->ConnectToService(uuid, |
265 base::Bind(&BluetoothConnectFunction::ConnectToServiceCallback, | 304 base::Bind(&BluetoothConnectFunction::ConnectToServiceCallback, |
266 this, | 305 this, |
267 device, | 306 device, |
268 uuid)); | 307 uuid)); |
269 return true; | 308 return true; |
270 } | 309 } |
271 | 310 |
272 bool BluetoothDisconnectFunction::RunImpl() { | 311 bool BluetoothDisconnectFunction::RunImpl() { |
273 scoped_ptr<Disconnect::Params> params(Disconnect::Params::Create(*args_)); | 312 scoped_ptr<Disconnect::Params> params(Disconnect::Params::Create(*args_)); |
274 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 313 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
275 const experimental_bluetooth::DisconnectOptions& options = params->options; | 314 const experimental_bluetooth::DisconnectOptions& options = params->options; |
276 return GetEventRouter(profile())->ReleaseSocket(options.socket_id); | 315 return GetEventRouter(profile())->ReleaseSocket(options.socket_id); |
277 } | 316 } |
278 | 317 |
| 318 BluetoothReadFunction::BluetoothReadFunction() {} |
| 319 BluetoothReadFunction::~BluetoothReadFunction() {} |
| 320 |
279 bool BluetoothReadFunction::Prepare() { | 321 bool BluetoothReadFunction::Prepare() { |
280 scoped_ptr<Read::Params> params(Read::Params::Create(*args_)); | 322 scoped_ptr<Read::Params> params(Read::Params::Create(*args_)); |
281 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 323 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
282 const experimental_bluetooth::ReadOptions& options = params->options; | 324 const experimental_bluetooth::ReadOptions& options = params->options; |
283 | 325 |
284 socket_ = GetEventRouter(profile())->GetSocket(options.socket_id); | 326 socket_ = GetEventRouter(profile())->GetSocket(options.socket_id); |
285 if (socket_.get() == NULL) { | 327 if (socket_.get() == NULL) { |
286 SetError(kSocketNotFoundError); | 328 SetError(kSocketNotFoundError); |
287 return false; | 329 return false; |
288 } | 330 } |
289 | 331 |
290 success_ = false; | 332 success_ = false; |
291 return true; | 333 return true; |
292 } | 334 } |
293 | 335 |
294 void BluetoothReadFunction::Work() { | 336 void BluetoothReadFunction::Work() { |
| 337 if (!socket_.get()) |
| 338 return; |
| 339 |
295 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 340 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
296 CHECK(socket_.get() != NULL); | |
297 | 341 |
298 char* all_bytes = NULL; | 342 char* all_bytes = NULL; |
299 ssize_t buffer_size = 0; | 343 ssize_t buffer_size = 0; |
300 ssize_t total_bytes_read = 0; | 344 ssize_t total_bytes_read = 0; |
301 int errsv; | 345 int errsv; |
302 while (true) { | 346 while (true) { |
303 buffer_size += 1024; | 347 buffer_size += 1024; |
304 all_bytes = static_cast<char*>(realloc(all_bytes, buffer_size)); | 348 all_bytes = static_cast<char*>(realloc(all_bytes, buffer_size)); |
305 CHECK(all_bytes) << "Failed to grow Bluetooth socket buffer"; | 349 CHECK(all_bytes) << "Failed to grow Bluetooth socket buffer"; |
306 | 350 |
307 // bluetooth sockets are non-blocking, so read until we hit an error | 351 // bluetooth sockets are non-blocking, so read until we hit an error |
308 ssize_t bytes_read = read(socket_->fd(), all_bytes + total_bytes_read, | 352 ssize_t bytes_read = read(socket_->fd(), all_bytes + total_bytes_read, |
309 buffer_size - total_bytes_read); | 353 buffer_size - total_bytes_read); |
310 errsv = errno; | 354 errsv = errno; |
311 if (bytes_read <= 0) | 355 if (bytes_read <= 0) |
312 break; | 356 break; |
313 | 357 |
314 total_bytes_read += bytes_read; | 358 total_bytes_read += bytes_read; |
315 } | 359 } |
316 | 360 |
317 if (total_bytes_read > 0) { | 361 if (total_bytes_read > 0) { |
318 success_ = true; | 362 success_ = true; |
319 SetResult(base::BinaryValue::Create(all_bytes, total_bytes_read)); | 363 SetResult(base::BinaryValue::Create(all_bytes, total_bytes_read)); |
320 } else { | 364 } else { |
321 success_ = (errsv == EAGAIN || errsv == EWOULDBLOCK); | 365 success_ = (errsv == EAGAIN || errsv == EWOULDBLOCK); |
322 free(all_bytes); | 366 free(all_bytes); |
323 } | 367 } |
324 | 368 |
| 369 #if defined(OS_CHROMEOS) |
325 if (!success_) | 370 if (!success_) |
326 SetError(safe_strerror(errsv)); | 371 SetError(safe_strerror(errsv)); |
| 372 #endif |
327 } | 373 } |
328 | 374 |
329 bool BluetoothReadFunction::Respond() { | 375 bool BluetoothReadFunction::Respond() { |
330 return success_; | 376 return success_; |
331 } | 377 } |
332 | 378 |
| 379 BluetoothWriteFunction::BluetoothWriteFunction() {} |
| 380 BluetoothWriteFunction::~BluetoothWriteFunction() {} |
| 381 |
333 bool BluetoothWriteFunction::Prepare() { | 382 bool BluetoothWriteFunction::Prepare() { |
334 // TODO(bryeung): update to new-style parameter passing when ArrayBuffer | 383 // TODO(bryeung): update to new-style parameter passing when ArrayBuffer |
335 // support is added | 384 // support is added |
336 DictionaryValue* options; | 385 DictionaryValue* options; |
337 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options)); | 386 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options)); |
338 int socket_id; | 387 int socket_id; |
339 EXTENSION_FUNCTION_VALIDATE(options->GetInteger("socketId", &socket_id)); | 388 EXTENSION_FUNCTION_VALIDATE(options->GetInteger("socketId", &socket_id)); |
340 | 389 |
341 socket_ = GetEventRouter(profile())->GetSocket(socket_id); | 390 socket_ = GetEventRouter(profile())->GetSocket(socket_id); |
342 if (socket_.get() == NULL) { | 391 if (socket_.get() == NULL) { |
(...skipping 20 matching lines...) Expand all Loading... |
363 int errsv = errno; | 412 int errsv = errno; |
364 | 413 |
365 if (bytes_written > 0) { | 414 if (bytes_written > 0) { |
366 SetResult(Value::CreateIntegerValue(bytes_written)); | 415 SetResult(Value::CreateIntegerValue(bytes_written)); |
367 success_ = true; | 416 success_ = true; |
368 } else { | 417 } else { |
369 results_.reset(); | 418 results_.reset(); |
370 success_ = (errsv == EAGAIN || errsv == EWOULDBLOCK); | 419 success_ = (errsv == EAGAIN || errsv == EWOULDBLOCK); |
371 } | 420 } |
372 | 421 |
| 422 #if defined(OS_CHROMEOS) |
373 if (!success_) | 423 if (!success_) |
374 SetError(safe_strerror(errsv)); | 424 SetError(safe_strerror(errsv)); |
| 425 #endif |
375 } | 426 } |
376 | 427 |
377 bool BluetoothWriteFunction::Respond() { | 428 bool BluetoothWriteFunction::Respond() { |
378 return success_; | 429 return success_; |
379 } | 430 } |
380 | 431 |
381 void BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback() { | 432 void BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback() { |
382 SendResponse(true); | 433 SendResponse(true); |
383 } | 434 } |
384 | 435 |
385 void BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback() { | 436 void BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback() { |
386 SetError(kCouldNotSetOutOfBandPairingData); | 437 SetError(kCouldNotSetOutOfBandPairingData); |
387 SendResponse(false); | 438 SendResponse(false); |
388 } | 439 } |
389 | 440 |
390 bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { | 441 bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { |
| 442 if (!IsBluetoothSupported(profile())) { |
| 443 SetError(kPlatformNotSupported); |
| 444 return false; |
| 445 } |
| 446 |
391 // TODO(bryeung): update to new-style parameter passing when ArrayBuffer | 447 // TODO(bryeung): update to new-style parameter passing when ArrayBuffer |
392 // support is added | 448 // support is added |
393 DictionaryValue* options; | 449 DictionaryValue* options; |
394 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options)); | 450 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options)); |
395 std::string address; | 451 std::string address; |
396 EXTENSION_FUNCTION_VALIDATE(options->GetString("deviceAddress", &address)); | 452 EXTENSION_FUNCTION_VALIDATE(options->GetString("deviceAddress", &address)); |
397 | 453 |
398 chromeos::BluetoothDevice* device = | 454 BluetoothDevice* device = GetMutableAdapter(profile())->GetDevice(address); |
399 GetMutableAdapter(profile())->GetDevice(address); | |
400 if (!device) { | 455 if (!device) { |
401 SetError(kInvalidDevice); | 456 SetError(kInvalidDevice); |
402 return false; | 457 return false; |
403 } | 458 } |
404 | 459 |
405 if (options->HasKey("data")) { | 460 if (options->HasKey("data")) { |
406 DictionaryValue* data_in; | 461 DictionaryValue* data_in; |
407 EXTENSION_FUNCTION_VALIDATE(options->GetDictionary("data", &data_in)); | 462 EXTENSION_FUNCTION_VALIDATE(options->GetDictionary("data", &data_in)); |
408 | 463 |
409 chromeos::BluetoothOutOfBandPairingData data_out; | 464 bluetooth::BluetoothOutOfBandPairingData data_out; |
410 | 465 |
411 base::BinaryValue* tmp_data; | 466 base::BinaryValue* tmp_data; |
412 EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("hash", &tmp_data)); | 467 EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("hash", &tmp_data)); |
413 EXTENSION_FUNCTION_VALIDATE( | 468 EXTENSION_FUNCTION_VALIDATE( |
414 tmp_data->GetSize() == chromeos::kBluetoothOutOfBandPairingDataSize); | 469 tmp_data->GetSize() == bluetooth::kBluetoothOutOfBandPairingDataSize); |
415 memcpy(data_out.hash, | 470 memcpy(data_out.hash, |
416 reinterpret_cast<uint8_t*>(tmp_data->GetBuffer()), | 471 reinterpret_cast<uint8_t*>(tmp_data->GetBuffer()), |
417 chromeos::kBluetoothOutOfBandPairingDataSize); | 472 bluetooth::kBluetoothOutOfBandPairingDataSize); |
418 | 473 |
419 EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("randomizer", &tmp_data)); | 474 EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("randomizer", &tmp_data)); |
420 EXTENSION_FUNCTION_VALIDATE( | 475 EXTENSION_FUNCTION_VALIDATE( |
421 tmp_data->GetSize() == chromeos::kBluetoothOutOfBandPairingDataSize); | 476 tmp_data->GetSize() == bluetooth::kBluetoothOutOfBandPairingDataSize); |
422 memcpy(data_out.randomizer, | 477 memcpy(data_out.randomizer, |
423 reinterpret_cast<uint8_t*>(tmp_data->GetBuffer()), | 478 reinterpret_cast<uint8_t*>(tmp_data->GetBuffer()), |
424 chromeos::kBluetoothOutOfBandPairingDataSize); | 479 bluetooth::kBluetoothOutOfBandPairingDataSize); |
425 | 480 |
426 device->SetOutOfBandPairingData( | 481 device->SetOutOfBandPairingData( |
427 data_out, | 482 data_out, |
428 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback, | 483 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback, |
429 this), | 484 this), |
430 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback, | 485 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback, |
431 this)); | 486 this)); |
432 } else { | 487 } else { |
433 device->ClearOutOfBandPairingData( | 488 device->ClearOutOfBandPairingData( |
434 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback, | 489 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback, |
435 this), | 490 this), |
436 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback, | 491 base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback, |
437 this)); | 492 this)); |
438 } | 493 } |
439 | 494 |
440 return true; | 495 return true; |
441 } | 496 } |
442 | 497 |
443 void BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback( | 498 void BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback( |
444 const chromeos::BluetoothOutOfBandPairingData& data) { | 499 const bluetooth::BluetoothOutOfBandPairingData& data) { |
445 base::BinaryValue* hash = base::BinaryValue::CreateWithCopiedBuffer( | 500 base::BinaryValue* hash = base::BinaryValue::CreateWithCopiedBuffer( |
446 reinterpret_cast<const char*>(data.hash), | 501 reinterpret_cast<const char*>(data.hash), |
447 chromeos::kBluetoothOutOfBandPairingDataSize); | 502 bluetooth::kBluetoothOutOfBandPairingDataSize); |
448 base::BinaryValue* randomizer = base::BinaryValue::CreateWithCopiedBuffer( | 503 base::BinaryValue* randomizer = base::BinaryValue::CreateWithCopiedBuffer( |
449 reinterpret_cast<const char*>(data.randomizer), | 504 reinterpret_cast<const char*>(data.randomizer), |
450 chromeos::kBluetoothOutOfBandPairingDataSize); | 505 bluetooth::kBluetoothOutOfBandPairingDataSize); |
451 | 506 |
452 // TODO(bryeung): convert to experimental_bluetooth::OutOfBandPairingData | 507 // TODO(bryeung): convert to experimental_bluetooth::OutOfBandPairingData |
453 // when ArrayBuffer support within objects is completed. | 508 // when ArrayBuffer support within objects is completed. |
454 DictionaryValue* result = new DictionaryValue(); | 509 DictionaryValue* result = new DictionaryValue(); |
455 result->Set("hash", hash); | 510 result->Set("hash", hash); |
456 result->Set("randomizer", randomizer); | 511 result->Set("randomizer", randomizer); |
457 | 512 |
458 SetResult(result); | 513 SetResult(result); |
459 | 514 |
460 SendResponse(true); | 515 SendResponse(true); |
461 } | 516 } |
462 | 517 |
463 void BluetoothGetLocalOutOfBandPairingDataFunction::ErrorCallback() { | 518 void BluetoothGetLocalOutOfBandPairingDataFunction::ErrorCallback() { |
464 SetError(kCouldNotGetLocalOutOfBandPairingData); | 519 SetError(kCouldNotGetLocalOutOfBandPairingData); |
465 SendResponse(false); | 520 SendResponse(false); |
466 } | 521 } |
467 | 522 |
468 bool BluetoothGetLocalOutOfBandPairingDataFunction::RunImpl() { | 523 bool BluetoothGetLocalOutOfBandPairingDataFunction::RunImpl() { |
| 524 if (!IsBluetoothSupported(profile())) { |
| 525 SetError(kPlatformNotSupported); |
| 526 return false; |
| 527 } |
| 528 |
469 GetMutableAdapter(profile())->ReadLocalOutOfBandPairingData( | 529 GetMutableAdapter(profile())->ReadLocalOutOfBandPairingData( |
470 base::Bind(&BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback, | 530 base::Bind(&BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback, |
471 this), | 531 this), |
472 base::Bind(&BluetoothGetLocalOutOfBandPairingDataFunction::ErrorCallback, | 532 base::Bind(&BluetoothGetLocalOutOfBandPairingDataFunction::ErrorCallback, |
473 this)); | 533 this)); |
474 return true; | 534 return true; |
475 } | 535 } |
476 | 536 |
477 void BluetoothStartDiscoveryFunction::OnSuccessCallback() { | 537 void BluetoothStartDiscoveryFunction::OnSuccessCallback() { |
478 GetEventRouter(profile())->SetResponsibleForDiscovery(true); | 538 GetEventRouter(profile())->SetResponsibleForDiscovery(true); |
479 SendResponse(true); | 539 SendResponse(true); |
480 } | 540 } |
481 | 541 |
482 void BluetoothStartDiscoveryFunction::OnErrorCallback() { | 542 void BluetoothStartDiscoveryFunction::OnErrorCallback() { |
483 SetError(kStartDiscoveryFailed); | 543 SetError(kStartDiscoveryFailed); |
484 SendResponse(false); | 544 SendResponse(false); |
485 } | 545 } |
486 | 546 |
487 bool BluetoothStartDiscoveryFunction::RunImpl() { | 547 bool BluetoothStartDiscoveryFunction::RunImpl() { |
| 548 if (!IsBluetoothSupported(profile())) { |
| 549 SetError(kPlatformNotSupported); |
| 550 return false; |
| 551 } |
| 552 |
488 GetEventRouter(profile())->SetSendDiscoveryEvents(true); | 553 GetEventRouter(profile())->SetSendDiscoveryEvents(true); |
489 | 554 |
490 // If the adapter is already discovering, there is nothing else to do. | 555 // If the adapter is already discovering, there is nothing else to do. |
491 if (GetMutableAdapter(profile())->IsDiscovering()) { | 556 if (GetMutableAdapter(profile())->IsDiscovering()) { |
492 SendResponse(true); | 557 SendResponse(true); |
493 return true; | 558 return true; |
494 } | 559 } |
495 | 560 |
496 GetMutableAdapter(profile())->SetDiscovering(true, | 561 GetMutableAdapter(profile())->SetDiscovering(true, |
497 base::Bind(&BluetoothStartDiscoveryFunction::OnSuccessCallback, this), | 562 base::Bind(&BluetoothStartDiscoveryFunction::OnSuccessCallback, this), |
498 base::Bind(&BluetoothStartDiscoveryFunction::OnErrorCallback, this)); | 563 base::Bind(&BluetoothStartDiscoveryFunction::OnErrorCallback, this)); |
499 return true; | 564 return true; |
500 } | 565 } |
501 | 566 |
502 void BluetoothStopDiscoveryFunction::OnSuccessCallback() { | 567 void BluetoothStopDiscoveryFunction::OnSuccessCallback() { |
503 SendResponse(true); | 568 SendResponse(true); |
504 } | 569 } |
505 | 570 |
506 void BluetoothStopDiscoveryFunction::OnErrorCallback() { | 571 void BluetoothStopDiscoveryFunction::OnErrorCallback() { |
507 SetError(kStopDiscoveryFailed); | 572 SetError(kStopDiscoveryFailed); |
508 SendResponse(false); | 573 SendResponse(false); |
509 } | 574 } |
510 | 575 |
511 bool BluetoothStopDiscoveryFunction::RunImpl() { | 576 bool BluetoothStopDiscoveryFunction::RunImpl() { |
| 577 if (!IsBluetoothSupported(profile())) { |
| 578 SetError(kPlatformNotSupported); |
| 579 return false; |
| 580 } |
| 581 |
512 GetEventRouter(profile())->SetSendDiscoveryEvents(false); | 582 GetEventRouter(profile())->SetSendDiscoveryEvents(false); |
513 if (GetEventRouter(profile())->IsResponsibleForDiscovery()) { | 583 if (GetEventRouter(profile())->IsResponsibleForDiscovery()) { |
514 GetMutableAdapter(profile())->SetDiscovering(false, | 584 GetMutableAdapter(profile())->SetDiscovering(false, |
515 base::Bind(&BluetoothStopDiscoveryFunction::OnSuccessCallback, this), | 585 base::Bind(&BluetoothStopDiscoveryFunction::OnSuccessCallback, this), |
516 base::Bind(&BluetoothStopDiscoveryFunction::OnErrorCallback, this)); | 586 base::Bind(&BluetoothStopDiscoveryFunction::OnErrorCallback, this)); |
517 } | 587 } |
518 return true; | 588 return true; |
519 } | 589 } |
520 | 590 |
521 #else | |
522 | |
523 // ----------------------------------------------------------------------------- | |
524 // NIY stubs | |
525 // ----------------------------------------------------------------------------- | |
526 bool BluetoothIsAvailableFunction::RunImpl() { | |
527 NOTREACHED() << "Not implemented yet"; | |
528 return false; | |
529 } | |
530 | |
531 bool BluetoothIsPoweredFunction::RunImpl() { | |
532 NOTREACHED() << "Not implemented yet"; | |
533 return false; | |
534 } | |
535 | |
536 bool BluetoothGetAddressFunction::RunImpl() { | |
537 NOTREACHED() << "Not implemented yet"; | |
538 return false; | |
539 } | |
540 | |
541 bool BluetoothGetNameFunction::RunImpl() { | |
542 NOTREACHED() << "Not implemented yet"; | |
543 return false; | |
544 } | |
545 | |
546 bool BluetoothGetDevicesFunction::RunImpl() { | |
547 NOTREACHED() << "Not implemented yet"; | |
548 return false; | |
549 } | |
550 | |
551 bool BluetoothGetServicesFunction::RunImpl() { | |
552 NOTREACHED() << "Not implemented yet"; | |
553 return false; | |
554 } | |
555 | |
556 bool BluetoothConnectFunction::RunImpl() { | |
557 NOTREACHED() << "Not implemented yet"; | |
558 return false; | |
559 } | |
560 | |
561 bool BluetoothDisconnectFunction::RunImpl() { | |
562 NOTREACHED() << "Not implemented yet"; | |
563 return false; | |
564 } | |
565 | |
566 bool BluetoothReadFunction::Prepare() { | |
567 return true; | |
568 } | |
569 | |
570 void BluetoothReadFunction::Work() { | |
571 } | |
572 | |
573 bool BluetoothReadFunction::Respond() { | |
574 NOTREACHED() << "Not implemented yet"; | |
575 return false; | |
576 } | |
577 | |
578 bool BluetoothWriteFunction::Prepare() { | |
579 return true; | |
580 } | |
581 | |
582 void BluetoothWriteFunction::Work() { | |
583 } | |
584 | |
585 bool BluetoothWriteFunction::Respond() { | |
586 NOTREACHED() << "Not implemented yet"; | |
587 return false; | |
588 } | |
589 | |
590 bool BluetoothStartDiscoveryFunction::RunImpl() { | |
591 NOTREACHED() << "Not implemented yet"; | |
592 return false; | |
593 } | |
594 | |
595 bool BluetoothStopDiscoveryFunction::RunImpl() { | |
596 NOTREACHED() << "Not implemented yet"; | |
597 return false; | |
598 } | |
599 | |
600 bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { | |
601 NOTREACHED() << "Not implemented yet"; | |
602 return false; | |
603 } | |
604 | |
605 bool BluetoothGetLocalOutOfBandPairingDataFunction::RunImpl() { | |
606 NOTREACHED() << "Not implemented yet"; | |
607 return false; | |
608 } | |
609 | |
610 #endif | |
611 | |
612 BluetoothReadFunction::BluetoothReadFunction() {} | |
613 BluetoothReadFunction::~BluetoothReadFunction() {} | |
614 | |
615 BluetoothWriteFunction::BluetoothWriteFunction() {} | |
616 BluetoothWriteFunction::~BluetoothWriteFunction() {} | |
617 | |
618 } // namespace api | 591 } // namespace api |
619 } // namespace extensions | 592 } // namespace extensions |
OLD | NEW |