OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h" | |
6 | |
7 #include <stdint.h> | |
8 | |
9 #include "chrome/browser/extensions/api/bluetooth_socket/bluetooth_api_socket.h" | |
10 #include "chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_
dispatcher.h" | |
11 #include "chrome/common/extensions/api/bluetooth/bluetooth_manifest_data.h" | |
12 #include "content/public/browser/browser_context.h" | |
13 #include "content/public/browser/browser_thread.h" | |
14 #include "device/bluetooth/bluetooth_adapter.h" | |
15 #include "device/bluetooth/bluetooth_adapter_factory.h" | |
16 #include "device/bluetooth/bluetooth_device.h" | |
17 #include "device/bluetooth/bluetooth_socket.h" | |
18 #include "extensions/common/permissions/permissions_data.h" | |
19 #include "net/base/io_buffer.h" | |
20 | |
21 using content::BrowserThread; | |
22 using extensions::BluetoothApiSocket; | |
23 using extensions::api::bluetooth_socket::ListenOptions; | |
24 using extensions::api::bluetooth_socket::SocketInfo; | |
25 using extensions::api::bluetooth_socket::SocketProperties; | |
26 | |
27 namespace { | |
28 | |
29 const char kDeviceNotFoundError[] = "Device not found"; | |
30 const char kInvalidPsmError[] = "Invalid PSM"; | |
31 const char kInvalidUuidError[] = "Invalid UUID"; | |
32 const char kPermissionDeniedError[] = "Permission denied"; | |
33 const char kSocketNotFoundError[] = "Socket not found"; | |
34 | |
35 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id, | |
36 BluetoothApiSocket* socket) { | |
37 DCHECK(BrowserThread::CurrentlyOn(BluetoothApiSocket::kThreadId)); | |
38 linked_ptr<SocketInfo> socket_info(new SocketInfo()); | |
39 // This represents what we know about the socket, and does not call through | |
40 // to the system. | |
41 socket_info->socket_id = socket_id; | |
42 if (socket->name()) { | |
43 socket_info->name.reset(new std::string(*socket->name())); | |
44 } | |
45 socket_info->persistent = socket->persistent(); | |
46 if (socket->buffer_size() > 0) { | |
47 socket_info->buffer_size.reset(new int(socket->buffer_size())); | |
48 } | |
49 socket_info->paused = socket->paused(); | |
50 socket_info->connected = socket->IsConnected(); | |
51 | |
52 if (socket->IsConnected()) | |
53 socket_info->address.reset(new std::string(socket->device_address())); | |
54 socket_info->uuid.reset(new std::string(socket->uuid().canonical_value())); | |
55 | |
56 return socket_info; | |
57 } | |
58 | |
59 void SetSocketProperties(BluetoothApiSocket* socket, | |
60 SocketProperties* properties) { | |
61 if (properties->name.get()) { | |
62 socket->set_name(*properties->name.get()); | |
63 } | |
64 if (properties->persistent.get()) { | |
65 socket->set_persistent(*properties->persistent.get()); | |
66 } | |
67 if (properties->buffer_size.get()) { | |
68 // buffer size is validated when issuing the actual Recv operation | |
69 // on the socket. | |
70 socket->set_buffer_size(*properties->buffer_size.get()); | |
71 } | |
72 } | |
73 | |
74 extensions::api::BluetoothSocketEventDispatcher* GetSocketEventDispatcher( | |
75 content::BrowserContext* browser_context) { | |
76 extensions::api::BluetoothSocketEventDispatcher* socket_event_dispatcher = | |
77 extensions::api::BluetoothSocketEventDispatcher::Get(browser_context); | |
78 DCHECK(socket_event_dispatcher) | |
79 << "There is no socket event dispatcher. " | |
80 "If this assertion is failing during a test, then it is likely that " | |
81 "TestExtensionSystem is failing to provide an instance of " | |
82 "BluetoothSocketEventDispatcher."; | |
83 return socket_event_dispatcher; | |
84 } | |
85 | |
86 // Returns |true| if |psm| is a valid PSM. | |
87 // Per the Bluetooth specification, the PSM field must be at least two octets in | |
88 // length, with least significant bit of the least significant octet equal to | |
89 // '1' and the least significant bit of the most significant octet equal to '0'. | |
90 bool IsValidPsm(int psm) { | |
91 if (psm <= 0) | |
92 return false; | |
93 | |
94 std::vector<int16_t> octets; | |
95 while (psm > 0) { | |
96 octets.push_back(psm & 0xFF); | |
97 psm = psm >> 8; | |
98 } | |
99 | |
100 if (octets.size() < 2U) | |
101 return false; | |
102 | |
103 // The least significant bit of the least significant octet must be '1'. | |
104 if ((octets.front() & 0x01) != 1) | |
105 return false; | |
106 | |
107 // The least significant bit of the most significant octet must be '0'. | |
108 if ((octets.back() & 0x01) != 0) | |
109 return false; | |
110 | |
111 return true; | |
112 } | |
113 | |
114 } // namespace | |
115 | |
116 namespace extensions { | |
117 namespace api { | |
118 | |
119 BluetoothSocketAsyncApiFunction::BluetoothSocketAsyncApiFunction() {} | |
120 | |
121 BluetoothSocketAsyncApiFunction::~BluetoothSocketAsyncApiFunction() {} | |
122 | |
123 bool BluetoothSocketAsyncApiFunction::RunAsync() { | |
124 if (!PrePrepare() || !Prepare()) { | |
125 return false; | |
126 } | |
127 AsyncWorkStart(); | |
128 return true; | |
129 } | |
130 | |
131 bool BluetoothSocketAsyncApiFunction::PrePrepare() { | |
132 if (!BluetoothManifestData::CheckSocketPermitted(extension())) { | |
133 error_ = kPermissionDeniedError; | |
134 return false; | |
135 } | |
136 | |
137 manager_ = ApiResourceManager<BluetoothApiSocket>::Get(browser_context()); | |
138 DCHECK(manager_) | |
139 << "There is no socket manager. " | |
140 "If this assertion is failing during a test, then it is likely that " | |
141 "TestExtensionSystem is failing to provide an instance of " | |
142 "ApiResourceManager<BluetoothApiSocket>."; | |
143 return manager_ != NULL; | |
144 } | |
145 | |
146 bool BluetoothSocketAsyncApiFunction::Respond() { return error_.empty(); } | |
147 | |
148 void BluetoothSocketAsyncApiFunction::AsyncWorkCompleted() { | |
149 SendResponse(Respond()); | |
150 } | |
151 | |
152 void BluetoothSocketAsyncApiFunction::Work() {} | |
153 | |
154 void BluetoothSocketAsyncApiFunction::AsyncWorkStart() { | |
155 Work(); | |
156 AsyncWorkCompleted(); | |
157 } | |
158 | |
159 int BluetoothSocketAsyncApiFunction::AddSocket(BluetoothApiSocket* socket) { | |
160 return manager_->Add(socket); | |
161 } | |
162 | |
163 content::BrowserThread::ID | |
164 BluetoothSocketAsyncApiFunction::work_thread_id() const { | |
165 return BluetoothApiSocket::kThreadId; | |
166 } | |
167 | |
168 BluetoothApiSocket* BluetoothSocketAsyncApiFunction::GetSocket( | |
169 int api_resource_id) { | |
170 return manager_->Get(extension_id(), api_resource_id); | |
171 } | |
172 | |
173 void BluetoothSocketAsyncApiFunction::RemoveSocket(int api_resource_id) { | |
174 manager_->Remove(extension_id(), api_resource_id); | |
175 } | |
176 | |
177 base::hash_set<int>* BluetoothSocketAsyncApiFunction::GetSocketIds() { | |
178 return manager_->GetResourceIds(extension_id()); | |
179 } | |
180 | |
181 BluetoothSocketCreateFunction::BluetoothSocketCreateFunction() {} | |
182 | |
183 BluetoothSocketCreateFunction::~BluetoothSocketCreateFunction() {} | |
184 | |
185 bool BluetoothSocketCreateFunction::Prepare() { | |
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
187 | |
188 params_ = bluetooth_socket::Create::Params::Create(*args_); | |
189 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
190 return true; | |
191 } | |
192 | |
193 void BluetoothSocketCreateFunction::Work() { | |
194 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
195 | |
196 BluetoothApiSocket* socket = new BluetoothApiSocket(extension_id()); | |
197 | |
198 bluetooth_socket::SocketProperties* properties = | |
199 params_.get()->properties.get(); | |
200 if (properties) { | |
201 SetSocketProperties(socket, properties); | |
202 } | |
203 | |
204 bluetooth_socket::CreateInfo create_info; | |
205 create_info.socket_id = AddSocket(socket); | |
206 results_ = bluetooth_socket::Create::Results::Create(create_info); | |
207 AsyncWorkCompleted(); | |
208 } | |
209 | |
210 BluetoothSocketUpdateFunction::BluetoothSocketUpdateFunction() {} | |
211 | |
212 BluetoothSocketUpdateFunction::~BluetoothSocketUpdateFunction() {} | |
213 | |
214 bool BluetoothSocketUpdateFunction::Prepare() { | |
215 params_ = bluetooth_socket::Update::Params::Create(*args_); | |
216 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
217 return true; | |
218 } | |
219 | |
220 void BluetoothSocketUpdateFunction::Work() { | |
221 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
222 if (!socket) { | |
223 error_ = kSocketNotFoundError; | |
224 return; | |
225 } | |
226 | |
227 SetSocketProperties(socket, ¶ms_.get()->properties); | |
228 results_ = bluetooth_socket::Update::Results::Create(); | |
229 } | |
230 | |
231 BluetoothSocketSetPausedFunction::BluetoothSocketSetPausedFunction() | |
232 : socket_event_dispatcher_(NULL) {} | |
233 | |
234 BluetoothSocketSetPausedFunction::~BluetoothSocketSetPausedFunction() {} | |
235 | |
236 bool BluetoothSocketSetPausedFunction::Prepare() { | |
237 params_ = bluetooth_socket::SetPaused::Params::Create(*args_); | |
238 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
239 | |
240 socket_event_dispatcher_ = GetSocketEventDispatcher(browser_context()); | |
241 return socket_event_dispatcher_ != NULL; | |
242 } | |
243 | |
244 void BluetoothSocketSetPausedFunction::Work() { | |
245 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
246 if (!socket) { | |
247 error_ = kSocketNotFoundError; | |
248 return; | |
249 } | |
250 | |
251 if (socket->paused() != params_->paused) { | |
252 socket->set_paused(params_->paused); | |
253 if (!params_->paused) { | |
254 socket_event_dispatcher_->OnSocketResume(extension_id(), | |
255 params_->socket_id); | |
256 } | |
257 } | |
258 | |
259 results_ = bluetooth_socket::SetPaused::Results::Create(); | |
260 } | |
261 | |
262 BluetoothSocketListenFunction::BluetoothSocketListenFunction() {} | |
263 | |
264 BluetoothSocketListenFunction::~BluetoothSocketListenFunction() {} | |
265 | |
266 bool BluetoothSocketListenFunction::Prepare() { | |
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
268 if (!CreateParams()) | |
269 return false; | |
270 socket_event_dispatcher_ = GetSocketEventDispatcher(browser_context()); | |
271 return socket_event_dispatcher_ != NULL; | |
272 } | |
273 | |
274 void BluetoothSocketListenFunction::AsyncWorkStart() { | |
275 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
276 device::BluetoothAdapterFactory::GetAdapter( | |
277 base::Bind(&BluetoothSocketListenFunction::OnGetAdapter, this)); | |
278 } | |
279 | |
280 void BluetoothSocketListenFunction::OnGetAdapter( | |
281 scoped_refptr<device::BluetoothAdapter> adapter) { | |
282 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
283 BluetoothApiSocket* socket = GetSocket(socket_id()); | |
284 if (!socket) { | |
285 error_ = kSocketNotFoundError; | |
286 AsyncWorkCompleted(); | |
287 return; | |
288 } | |
289 | |
290 device::BluetoothUUID bluetooth_uuid(uuid()); | |
291 if (!bluetooth_uuid.IsValid()) { | |
292 error_ = kInvalidUuidError; | |
293 AsyncWorkCompleted(); | |
294 return; | |
295 } | |
296 | |
297 BluetoothPermissionRequest param(uuid()); | |
298 if (!BluetoothManifestData::CheckRequest(extension(), param)) { | |
299 error_ = kPermissionDeniedError; | |
300 AsyncWorkCompleted(); | |
301 return; | |
302 } | |
303 | |
304 scoped_ptr<std::string> name; | |
305 if (socket->name()) | |
306 name.reset(new std::string(*socket->name())); | |
307 | |
308 CreateService( | |
309 adapter, | |
310 bluetooth_uuid, | |
311 name.Pass(), | |
312 base::Bind(&BluetoothSocketListenFunction::OnCreateService, this), | |
313 base::Bind(&BluetoothSocketListenFunction::OnCreateServiceError, this)); | |
314 } | |
315 | |
316 | |
317 void BluetoothSocketListenFunction::OnCreateService( | |
318 scoped_refptr<device::BluetoothSocket> socket) { | |
319 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
320 | |
321 // Fetch the socket again since this is not a reference-counted object, and | |
322 // it may have gone away in the meantime (we check earlier to avoid making | |
323 // a connection in the case of an obvious programming error). | |
324 BluetoothApiSocket* api_socket = GetSocket(socket_id()); | |
325 if (!api_socket) { | |
326 error_ = kSocketNotFoundError; | |
327 AsyncWorkCompleted(); | |
328 return; | |
329 } | |
330 | |
331 api_socket->AdoptListeningSocket(socket, | |
332 device::BluetoothUUID(uuid())); | |
333 socket_event_dispatcher_->OnSocketListen(extension_id(), socket_id()); | |
334 | |
335 CreateResults(); | |
336 AsyncWorkCompleted(); | |
337 } | |
338 | |
339 void BluetoothSocketListenFunction::OnCreateServiceError( | |
340 const std::string& message) { | |
341 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
342 error_ = message; | |
343 AsyncWorkCompleted(); | |
344 } | |
345 | |
346 BluetoothSocketListenUsingRfcommFunction:: | |
347 BluetoothSocketListenUsingRfcommFunction() {} | |
348 | |
349 BluetoothSocketListenUsingRfcommFunction:: | |
350 ~BluetoothSocketListenUsingRfcommFunction() {} | |
351 | |
352 int BluetoothSocketListenUsingRfcommFunction::socket_id() const { | |
353 return params_->socket_id; | |
354 } | |
355 | |
356 const std::string& BluetoothSocketListenUsingRfcommFunction::uuid() const { | |
357 return params_->uuid; | |
358 } | |
359 | |
360 bool BluetoothSocketListenUsingRfcommFunction::CreateParams() { | |
361 params_ = bluetooth_socket::ListenUsingRfcomm::Params::Create(*args_); | |
362 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
363 return true; | |
364 } | |
365 | |
366 void BluetoothSocketListenUsingRfcommFunction::CreateService( | |
367 scoped_refptr<device::BluetoothAdapter> adapter, | |
368 const device::BluetoothUUID& uuid, | |
369 scoped_ptr<std::string> name, | |
370 const device::BluetoothAdapter::CreateServiceCallback& callback, | |
371 const device::BluetoothAdapter::CreateServiceErrorCallback& | |
372 error_callback) { | |
373 device::BluetoothAdapter::ServiceOptions service_options; | |
374 service_options.name = name.Pass(); | |
375 | |
376 ListenOptions* options = params_->options.get(); | |
377 if (options) { | |
378 if (options->channel.get()) | |
379 service_options.channel.reset(new int(*(options->channel))); | |
380 } | |
381 | |
382 adapter->CreateRfcommService(uuid, service_options, callback, error_callback); | |
383 } | |
384 | |
385 void BluetoothSocketListenUsingRfcommFunction::CreateResults() { | |
386 results_ = bluetooth_socket::ListenUsingRfcomm::Results::Create(); | |
387 } | |
388 | |
389 BluetoothSocketListenUsingL2capFunction:: | |
390 BluetoothSocketListenUsingL2capFunction() {} | |
391 | |
392 BluetoothSocketListenUsingL2capFunction:: | |
393 ~BluetoothSocketListenUsingL2capFunction() {} | |
394 | |
395 int BluetoothSocketListenUsingL2capFunction::socket_id() const { | |
396 return params_->socket_id; | |
397 } | |
398 | |
399 const std::string& BluetoothSocketListenUsingL2capFunction::uuid() const { | |
400 return params_->uuid; | |
401 } | |
402 | |
403 bool BluetoothSocketListenUsingL2capFunction::CreateParams() { | |
404 params_ = bluetooth_socket::ListenUsingL2cap::Params::Create(*args_); | |
405 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
406 return true; | |
407 } | |
408 | |
409 void BluetoothSocketListenUsingL2capFunction::CreateService( | |
410 scoped_refptr<device::BluetoothAdapter> adapter, | |
411 const device::BluetoothUUID& uuid, | |
412 scoped_ptr<std::string> name, | |
413 const device::BluetoothAdapter::CreateServiceCallback& callback, | |
414 const device::BluetoothAdapter::CreateServiceErrorCallback& | |
415 error_callback) { | |
416 device::BluetoothAdapter::ServiceOptions service_options; | |
417 service_options.name = name.Pass(); | |
418 | |
419 ListenOptions* options = params_->options.get(); | |
420 if (options) { | |
421 if (options->psm) { | |
422 int psm = *options->psm; | |
423 if (!IsValidPsm(psm)) { | |
424 error_callback.Run(kInvalidPsmError); | |
425 return; | |
426 } | |
427 | |
428 service_options.psm.reset(new int(psm)); | |
429 } | |
430 } | |
431 | |
432 adapter->CreateL2capService(uuid, service_options, callback, error_callback); | |
433 } | |
434 | |
435 void BluetoothSocketListenUsingL2capFunction::CreateResults() { | |
436 results_ = bluetooth_socket::ListenUsingL2cap::Results::Create(); | |
437 } | |
438 | |
439 BluetoothSocketAbstractConnectFunction:: | |
440 BluetoothSocketAbstractConnectFunction() {} | |
441 | |
442 BluetoothSocketAbstractConnectFunction:: | |
443 ~BluetoothSocketAbstractConnectFunction() {} | |
444 | |
445 bool BluetoothSocketAbstractConnectFunction::Prepare() { | |
446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
447 params_ = bluetooth_socket::Connect::Params::Create(*args_); | |
448 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
449 | |
450 socket_event_dispatcher_ = GetSocketEventDispatcher(browser_context()); | |
451 return socket_event_dispatcher_ != NULL; | |
452 } | |
453 | |
454 void BluetoothSocketAbstractConnectFunction::AsyncWorkStart() { | |
455 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
456 device::BluetoothAdapterFactory::GetAdapter( | |
457 base::Bind(&BluetoothSocketAbstractConnectFunction::OnGetAdapter, this)); | |
458 } | |
459 | |
460 void BluetoothSocketAbstractConnectFunction::OnGetAdapter( | |
461 scoped_refptr<device::BluetoothAdapter> adapter) { | |
462 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
463 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
464 if (!socket) { | |
465 error_ = kSocketNotFoundError; | |
466 AsyncWorkCompleted(); | |
467 return; | |
468 } | |
469 | |
470 device::BluetoothDevice* device = adapter->GetDevice(params_->address); | |
471 if (!device) { | |
472 error_ = kDeviceNotFoundError; | |
473 AsyncWorkCompleted(); | |
474 return; | |
475 } | |
476 | |
477 device::BluetoothUUID uuid(params_->uuid); | |
478 if (!uuid.IsValid()) { | |
479 error_ = kInvalidUuidError; | |
480 AsyncWorkCompleted(); | |
481 return; | |
482 } | |
483 | |
484 BluetoothPermissionRequest param(params_->uuid); | |
485 if (!BluetoothManifestData::CheckRequest(extension(), param)) { | |
486 error_ = kPermissionDeniedError; | |
487 AsyncWorkCompleted(); | |
488 return; | |
489 } | |
490 | |
491 ConnectToService(device, uuid); | |
492 } | |
493 | |
494 void BluetoothSocketAbstractConnectFunction::OnConnect( | |
495 scoped_refptr<device::BluetoothSocket> socket) { | |
496 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
497 | |
498 // Fetch the socket again since this is not a reference-counted object, and | |
499 // it may have gone away in the meantime (we check earlier to avoid making | |
500 // a connection in the case of an obvious programming error). | |
501 BluetoothApiSocket* api_socket = GetSocket(params_->socket_id); | |
502 if (!api_socket) { | |
503 error_ = kSocketNotFoundError; | |
504 AsyncWorkCompleted(); | |
505 return; | |
506 } | |
507 | |
508 api_socket->AdoptConnectedSocket(socket, | |
509 params_->address, | |
510 device::BluetoothUUID(params_->uuid)); | |
511 socket_event_dispatcher_->OnSocketConnect(extension_id(), | |
512 params_->socket_id); | |
513 | |
514 results_ = bluetooth_socket::Connect::Results::Create(); | |
515 AsyncWorkCompleted(); | |
516 } | |
517 | |
518 void BluetoothSocketAbstractConnectFunction::OnConnectError( | |
519 const std::string& message) { | |
520 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
521 error_ = message; | |
522 AsyncWorkCompleted(); | |
523 } | |
524 | |
525 BluetoothSocketConnectFunction::BluetoothSocketConnectFunction() {} | |
526 | |
527 BluetoothSocketConnectFunction::~BluetoothSocketConnectFunction() {} | |
528 | |
529 void BluetoothSocketConnectFunction::ConnectToService( | |
530 device::BluetoothDevice* device, | |
531 const device::BluetoothUUID& uuid) { | |
532 device->ConnectToService( | |
533 uuid, | |
534 base::Bind(&BluetoothSocketConnectFunction::OnConnect, this), | |
535 base::Bind(&BluetoothSocketConnectFunction::OnConnectError, this)); | |
536 } | |
537 | |
538 BluetoothSocketDisconnectFunction::BluetoothSocketDisconnectFunction() {} | |
539 | |
540 BluetoothSocketDisconnectFunction::~BluetoothSocketDisconnectFunction() {} | |
541 | |
542 bool BluetoothSocketDisconnectFunction::Prepare() { | |
543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
544 params_ = bluetooth_socket::Disconnect::Params::Create(*args_); | |
545 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
546 return true; | |
547 } | |
548 | |
549 void BluetoothSocketDisconnectFunction::AsyncWorkStart() { | |
550 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
551 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
552 if (!socket) { | |
553 error_ = kSocketNotFoundError; | |
554 AsyncWorkCompleted(); | |
555 return; | |
556 } | |
557 | |
558 socket->Disconnect(base::Bind(&BluetoothSocketDisconnectFunction::OnSuccess, | |
559 this)); | |
560 } | |
561 | |
562 void BluetoothSocketDisconnectFunction::OnSuccess() { | |
563 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
564 results_ = bluetooth_socket::Disconnect::Results::Create(); | |
565 AsyncWorkCompleted(); | |
566 } | |
567 | |
568 BluetoothSocketCloseFunction::BluetoothSocketCloseFunction() {} | |
569 | |
570 BluetoothSocketCloseFunction::~BluetoothSocketCloseFunction() {} | |
571 | |
572 bool BluetoothSocketCloseFunction::Prepare() { | |
573 params_ = bluetooth_socket::Close::Params::Create(*args_); | |
574 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
575 return true; | |
576 } | |
577 | |
578 void BluetoothSocketCloseFunction::Work() { | |
579 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
580 if (!socket) { | |
581 error_ = kSocketNotFoundError; | |
582 return; | |
583 } | |
584 | |
585 RemoveSocket(params_->socket_id); | |
586 results_ = bluetooth_socket::Close::Results::Create(); | |
587 } | |
588 | |
589 BluetoothSocketSendFunction::BluetoothSocketSendFunction() | |
590 : io_buffer_size_(0) {} | |
591 | |
592 BluetoothSocketSendFunction::~BluetoothSocketSendFunction() {} | |
593 | |
594 bool BluetoothSocketSendFunction::Prepare() { | |
595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
596 params_ = bluetooth_socket::Send::Params::Create(*args_); | |
597 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
598 | |
599 io_buffer_size_ = params_->data.size(); | |
600 io_buffer_ = new net::WrappedIOBuffer(params_->data.data()); | |
601 return true; | |
602 } | |
603 | |
604 void BluetoothSocketSendFunction::AsyncWorkStart() { | |
605 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
606 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
607 if (!socket) { | |
608 error_ = kSocketNotFoundError; | |
609 return; | |
610 } | |
611 | |
612 socket->Send(io_buffer_, | |
613 io_buffer_size_, | |
614 base::Bind(&BluetoothSocketSendFunction::OnSuccess, this), | |
615 base::Bind(&BluetoothSocketSendFunction::OnError, this)); | |
616 } | |
617 | |
618 void BluetoothSocketSendFunction::OnSuccess(int bytes_sent) { | |
619 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
620 results_ = bluetooth_socket::Send::Results::Create(bytes_sent); | |
621 AsyncWorkCompleted(); | |
622 } | |
623 | |
624 void BluetoothSocketSendFunction::OnError( | |
625 BluetoothApiSocket::ErrorReason reason, | |
626 const std::string& message) { | |
627 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
628 error_ = message; | |
629 AsyncWorkCompleted(); | |
630 } | |
631 | |
632 BluetoothSocketGetInfoFunction::BluetoothSocketGetInfoFunction() {} | |
633 | |
634 BluetoothSocketGetInfoFunction::~BluetoothSocketGetInfoFunction() {} | |
635 | |
636 bool BluetoothSocketGetInfoFunction::Prepare() { | |
637 params_ = bluetooth_socket::GetInfo::Params::Create(*args_); | |
638 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
639 return true; | |
640 } | |
641 | |
642 void BluetoothSocketGetInfoFunction::Work() { | |
643 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
644 if (!socket) { | |
645 error_ = kSocketNotFoundError; | |
646 return; | |
647 } | |
648 | |
649 linked_ptr<bluetooth_socket::SocketInfo> socket_info = | |
650 CreateSocketInfo(params_->socket_id, socket); | |
651 results_ = bluetooth_socket::GetInfo::Results::Create(*socket_info); | |
652 } | |
653 | |
654 BluetoothSocketGetSocketsFunction::BluetoothSocketGetSocketsFunction() {} | |
655 | |
656 BluetoothSocketGetSocketsFunction::~BluetoothSocketGetSocketsFunction() {} | |
657 | |
658 bool BluetoothSocketGetSocketsFunction::Prepare() { return true; } | |
659 | |
660 void BluetoothSocketGetSocketsFunction::Work() { | |
661 std::vector<linked_ptr<bluetooth_socket::SocketInfo> > socket_infos; | |
662 base::hash_set<int>* resource_ids = GetSocketIds(); | |
663 if (resource_ids != NULL) { | |
664 for (base::hash_set<int>::iterator it = resource_ids->begin(); | |
665 it != resource_ids->end(); | |
666 ++it) { | |
667 int socket_id = *it; | |
668 BluetoothApiSocket* socket = GetSocket(socket_id); | |
669 if (socket) { | |
670 socket_infos.push_back(CreateSocketInfo(socket_id, socket)); | |
671 } | |
672 } | |
673 } | |
674 results_ = bluetooth_socket::GetSockets::Results::Create(socket_infos); | |
675 } | |
676 | |
677 } // namespace api | |
678 } // namespace extensions | |
OLD | NEW |