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 BluetoothSocketConnectFunction::BluetoothSocketConnectFunction() {} | |
440 | |
441 BluetoothSocketConnectFunction::~BluetoothSocketConnectFunction() {} | |
442 | |
443 bool BluetoothSocketConnectFunction::Prepare() { | |
444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
445 params_ = bluetooth_socket::Connect::Params::Create(*args_); | |
446 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
447 | |
448 socket_event_dispatcher_ = GetSocketEventDispatcher(browser_context()); | |
449 return socket_event_dispatcher_ != NULL; | |
450 } | |
451 | |
452 void BluetoothSocketConnectFunction::AsyncWorkStart() { | |
453 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
454 device::BluetoothAdapterFactory::GetAdapter( | |
455 base::Bind(&BluetoothSocketConnectFunction::OnGetAdapter, this)); | |
456 } | |
457 | |
458 void BluetoothSocketConnectFunction::OnGetAdapter( | |
459 scoped_refptr<device::BluetoothAdapter> adapter) { | |
460 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
461 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
462 if (!socket) { | |
463 error_ = kSocketNotFoundError; | |
464 AsyncWorkCompleted(); | |
465 return; | |
466 } | |
467 | |
468 device::BluetoothDevice* device = adapter->GetDevice(params_->address); | |
469 if (!device) { | |
470 error_ = kDeviceNotFoundError; | |
471 AsyncWorkCompleted(); | |
472 return; | |
473 } | |
474 | |
475 device::BluetoothUUID uuid(params_->uuid); | |
476 if (!uuid.IsValid()) { | |
477 error_ = kInvalidUuidError; | |
478 AsyncWorkCompleted(); | |
479 return; | |
480 } | |
481 | |
482 BluetoothPermissionRequest param(params_->uuid); | |
483 if (!BluetoothManifestData::CheckRequest(extension(), param)) { | |
484 error_ = kPermissionDeniedError; | |
485 AsyncWorkCompleted(); | |
486 return; | |
487 } | |
488 | |
489 device->ConnectToService( | |
490 uuid, | |
491 base::Bind(&BluetoothSocketConnectFunction::OnConnect, this), | |
492 base::Bind(&BluetoothSocketConnectFunction::OnConnectError, this)); | |
493 } | |
494 | |
495 void BluetoothSocketConnectFunction::OnConnect( | |
496 scoped_refptr<device::BluetoothSocket> socket) { | |
497 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
498 | |
499 // Fetch the socket again since this is not a reference-counted object, and | |
500 // it may have gone away in the meantime (we check earlier to avoid making | |
501 // a connection in the case of an obvious programming error). | |
502 BluetoothApiSocket* api_socket = GetSocket(params_->socket_id); | |
503 if (!api_socket) { | |
504 error_ = kSocketNotFoundError; | |
505 AsyncWorkCompleted(); | |
506 return; | |
507 } | |
508 | |
509 api_socket->AdoptConnectedSocket(socket, | |
510 params_->address, | |
511 device::BluetoothUUID(params_->uuid)); | |
512 socket_event_dispatcher_->OnSocketConnect(extension_id(), | |
513 params_->socket_id); | |
514 | |
515 results_ = bluetooth_socket::Connect::Results::Create(); | |
516 AsyncWorkCompleted(); | |
517 } | |
518 | |
519 void BluetoothSocketConnectFunction::OnConnectError( | |
520 const std::string& message) { | |
521 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
522 error_ = message; | |
523 AsyncWorkCompleted(); | |
524 } | |
525 | |
526 BluetoothSocketDisconnectFunction::BluetoothSocketDisconnectFunction() {} | |
527 | |
528 BluetoothSocketDisconnectFunction::~BluetoothSocketDisconnectFunction() {} | |
529 | |
530 bool BluetoothSocketDisconnectFunction::Prepare() { | |
531 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
532 params_ = bluetooth_socket::Disconnect::Params::Create(*args_); | |
533 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
534 return true; | |
535 } | |
536 | |
537 void BluetoothSocketDisconnectFunction::AsyncWorkStart() { | |
538 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
539 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
540 if (!socket) { | |
541 error_ = kSocketNotFoundError; | |
542 AsyncWorkCompleted(); | |
543 return; | |
544 } | |
545 | |
546 socket->Disconnect(base::Bind(&BluetoothSocketDisconnectFunction::OnSuccess, | |
547 this)); | |
548 } | |
549 | |
550 void BluetoothSocketDisconnectFunction::OnSuccess() { | |
551 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
552 results_ = bluetooth_socket::Disconnect::Results::Create(); | |
553 AsyncWorkCompleted(); | |
554 } | |
555 | |
556 BluetoothSocketCloseFunction::BluetoothSocketCloseFunction() {} | |
557 | |
558 BluetoothSocketCloseFunction::~BluetoothSocketCloseFunction() {} | |
559 | |
560 bool BluetoothSocketCloseFunction::Prepare() { | |
561 params_ = bluetooth_socket::Close::Params::Create(*args_); | |
562 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
563 return true; | |
564 } | |
565 | |
566 void BluetoothSocketCloseFunction::Work() { | |
567 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
568 if (!socket) { | |
569 error_ = kSocketNotFoundError; | |
570 return; | |
571 } | |
572 | |
573 RemoveSocket(params_->socket_id); | |
574 results_ = bluetooth_socket::Close::Results::Create(); | |
575 } | |
576 | |
577 BluetoothSocketSendFunction::BluetoothSocketSendFunction() | |
578 : io_buffer_size_(0) {} | |
579 | |
580 BluetoothSocketSendFunction::~BluetoothSocketSendFunction() {} | |
581 | |
582 bool BluetoothSocketSendFunction::Prepare() { | |
583 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
584 params_ = bluetooth_socket::Send::Params::Create(*args_); | |
585 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
586 | |
587 io_buffer_size_ = params_->data.size(); | |
588 io_buffer_ = new net::WrappedIOBuffer(params_->data.data()); | |
589 return true; | |
590 } | |
591 | |
592 void BluetoothSocketSendFunction::AsyncWorkStart() { | |
593 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
594 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
595 if (!socket) { | |
596 error_ = kSocketNotFoundError; | |
597 return; | |
598 } | |
599 | |
600 socket->Send(io_buffer_, | |
601 io_buffer_size_, | |
602 base::Bind(&BluetoothSocketSendFunction::OnSuccess, this), | |
603 base::Bind(&BluetoothSocketSendFunction::OnError, this)); | |
604 } | |
605 | |
606 void BluetoothSocketSendFunction::OnSuccess(int bytes_sent) { | |
607 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
608 results_ = bluetooth_socket::Send::Results::Create(bytes_sent); | |
609 AsyncWorkCompleted(); | |
610 } | |
611 | |
612 void BluetoothSocketSendFunction::OnError( | |
613 BluetoothApiSocket::ErrorReason reason, | |
614 const std::string& message) { | |
615 DCHECK(BrowserThread::CurrentlyOn(work_thread_id())); | |
616 error_ = message; | |
617 AsyncWorkCompleted(); | |
618 } | |
619 | |
620 BluetoothSocketGetInfoFunction::BluetoothSocketGetInfoFunction() {} | |
621 | |
622 BluetoothSocketGetInfoFunction::~BluetoothSocketGetInfoFunction() {} | |
623 | |
624 bool BluetoothSocketGetInfoFunction::Prepare() { | |
625 params_ = bluetooth_socket::GetInfo::Params::Create(*args_); | |
626 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
627 return true; | |
628 } | |
629 | |
630 void BluetoothSocketGetInfoFunction::Work() { | |
631 BluetoothApiSocket* socket = GetSocket(params_->socket_id); | |
632 if (!socket) { | |
633 error_ = kSocketNotFoundError; | |
634 return; | |
635 } | |
636 | |
637 linked_ptr<bluetooth_socket::SocketInfo> socket_info = | |
638 CreateSocketInfo(params_->socket_id, socket); | |
639 results_ = bluetooth_socket::GetInfo::Results::Create(*socket_info); | |
640 } | |
641 | |
642 BluetoothSocketGetSocketsFunction::BluetoothSocketGetSocketsFunction() {} | |
643 | |
644 BluetoothSocketGetSocketsFunction::~BluetoothSocketGetSocketsFunction() {} | |
645 | |
646 bool BluetoothSocketGetSocketsFunction::Prepare() { return true; } | |
647 | |
648 void BluetoothSocketGetSocketsFunction::Work() { | |
649 std::vector<linked_ptr<bluetooth_socket::SocketInfo> > socket_infos; | |
650 base::hash_set<int>* resource_ids = GetSocketIds(); | |
651 if (resource_ids != NULL) { | |
652 for (base::hash_set<int>::iterator it = resource_ids->begin(); | |
653 it != resource_ids->end(); | |
654 ++it) { | |
655 int socket_id = *it; | |
656 BluetoothApiSocket* socket = GetSocket(socket_id); | |
657 if (socket) { | |
658 socket_infos.push_back(CreateSocketInfo(socket_id, socket)); | |
659 } | |
660 } | |
661 } | |
662 results_ = bluetooth_socket::GetSockets::Results::Create(socket_infos); | |
663 } | |
664 | |
665 } // namespace api | |
666 } // namespace extensions | |
OLD | NEW |