Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / extensions / browser / api / bluetooth_low_energy / bluetooth_low_energy_api.cc
blob71529ad7c579caaf562637bb2c63763b418ae330
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.
5 #include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h"
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "base/strings/stringprintf.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "extensions/browser/api/bluetooth_low_energy/utils.h"
12 #include "extensions/browser/event_router.h"
13 #include "extensions/common/api/bluetooth/bluetooth_manifest_data.h"
14 #include "extensions/common/api/bluetooth_low_energy.h"
15 #include "extensions/common/permissions/permissions_data.h"
17 using content::BrowserContext;
18 using content::BrowserThread;
20 namespace apibtle = extensions::core_api::bluetooth_low_energy;
22 namespace extensions {
24 namespace {
26 const char kErrorAdapterNotInitialized[] =
27 "Could not initialize Bluetooth adapter";
28 const char kErrorAlreadyConnected[] = "Already connected";
29 const char kErrorAlreadyNotifying[] = "Already notifying";
30 const char kErrorAuthenticationFailed[] = "Authentication failed";
31 const char kErrorCanceled[] = "Request canceled";
32 const char kErrorGattNotSupported[] = "Operation not supported by this service";
33 const char kErrorHigherSecurity[] = "Higher security needed";
34 const char kErrorInProgress[] = "In progress";
35 const char kErrorInsufficientAuthorization[] = "Insufficient authorization";
36 const char kErrorInvalidLength[] = "Invalid attribute value length";
37 const char kErrorNotConnected[] = "Not connected";
38 const char kErrorNotFound[] = "Instance not found";
39 const char kErrorNotNotifying[] = "Not notifying";
40 const char kErrorOperationFailed[] = "Operation failed";
41 const char kErrorPermissionDenied[] = "Permission denied";
42 const char kErrorPlatformNotSupported[] =
43 "This operation is not supported on the current platform";
44 const char kErrorTimeout[] = "Operation timed out";
45 const char kErrorUnsupportedDevice[] =
46 "This device is not supported on the current platform";
48 // Returns the correct error string based on error status |status|. This is used
49 // to set the value of |chrome.runtime.lastError.message| and should not be
50 // passed |BluetoothLowEnergyEventRouter::kStatusSuccess|.
51 std::string StatusToString(BluetoothLowEnergyEventRouter::Status status) {
52 switch (status) {
53 case BluetoothLowEnergyEventRouter::kStatusErrorPermissionDenied:
54 return kErrorPermissionDenied;
55 case BluetoothLowEnergyEventRouter::kStatusErrorNotFound:
56 return kErrorNotFound;
57 case BluetoothLowEnergyEventRouter::kStatusErrorAlreadyConnected:
58 return kErrorAlreadyConnected;
59 case BluetoothLowEnergyEventRouter::kStatusErrorAlreadyNotifying:
60 return kErrorAlreadyNotifying;
61 case BluetoothLowEnergyEventRouter::kStatusErrorNotConnected:
62 return kErrorNotConnected;
63 case BluetoothLowEnergyEventRouter::kStatusErrorInsufficientAuthorization:
64 return kErrorInsufficientAuthorization;
65 case BluetoothLowEnergyEventRouter::kStatusErrorNotNotifying:
66 return kErrorNotNotifying;
67 case BluetoothLowEnergyEventRouter::kStatusErrorInProgress:
68 return kErrorInProgress;
69 case BluetoothLowEnergyEventRouter::kStatusErrorAuthenticationFailed:
70 return kErrorAuthenticationFailed;
71 case BluetoothLowEnergyEventRouter::kStatusErrorHigherSecurity:
72 return kErrorHigherSecurity;
73 case BluetoothLowEnergyEventRouter::kStatusErrorCanceled:
74 return kErrorCanceled;
75 case BluetoothLowEnergyEventRouter::kStatusErrorTimeout:
76 return kErrorTimeout;
77 case BluetoothLowEnergyEventRouter::kStatusErrorUnsupportedDevice:
78 return kErrorUnsupportedDevice;
79 case BluetoothLowEnergyEventRouter::kStatusErrorInvalidLength:
80 return kErrorInvalidLength;
81 case BluetoothLowEnergyEventRouter::kStatusErrorGattNotSupported:
82 return kErrorGattNotSupported;
83 case BluetoothLowEnergyEventRouter::kStatusSuccess:
84 NOTREACHED();
85 break;
86 default:
87 return kErrorOperationFailed;
89 return "";
92 extensions::BluetoothLowEnergyEventRouter* GetEventRouter(
93 BrowserContext* context) {
94 DCHECK_CURRENTLY_ON(BrowserThread::UI);
95 return extensions::BluetoothLowEnergyAPI::Get(context)->event_router();
98 void DoWorkCallback(const base::Callback<bool()>& callback) {
99 DCHECK(!callback.is_null());
100 callback.Run();
103 } // namespace
106 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI> >
107 g_factory = LAZY_INSTANCE_INITIALIZER;
109 // static
110 BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI>*
111 BluetoothLowEnergyAPI::GetFactoryInstance() {
112 return g_factory.Pointer();
115 // static
116 BluetoothLowEnergyAPI* BluetoothLowEnergyAPI::Get(BrowserContext* context) {
117 DCHECK_CURRENTLY_ON(BrowserThread::UI);
118 return GetFactoryInstance()->Get(context);
121 BluetoothLowEnergyAPI::BluetoothLowEnergyAPI(BrowserContext* context)
122 : event_router_(new BluetoothLowEnergyEventRouter(context)) {
123 DCHECK_CURRENTLY_ON(BrowserThread::UI);
126 BluetoothLowEnergyAPI::~BluetoothLowEnergyAPI() {
129 void BluetoothLowEnergyAPI::Shutdown() {
130 DCHECK_CURRENTLY_ON(BrowserThread::UI);
133 namespace core_api {
135 BluetoothLowEnergyExtensionFunction::BluetoothLowEnergyExtensionFunction() {
138 BluetoothLowEnergyExtensionFunction::~BluetoothLowEnergyExtensionFunction() {
141 bool BluetoothLowEnergyExtensionFunction::RunAsync() {
142 DCHECK_CURRENTLY_ON(BrowserThread::UI);
144 if (!BluetoothManifestData::CheckLowEnergyPermitted(extension())) {
145 error_ = kErrorPermissionDenied;
146 return false;
149 BluetoothLowEnergyEventRouter* event_router =
150 GetEventRouter(browser_context());
151 if (!event_router->IsBluetoothSupported()) {
152 SetError(kErrorPlatformNotSupported);
153 return false;
156 // It is safe to pass |this| here as ExtensionFunction is refcounted.
157 if (!event_router->InitializeAdapterAndInvokeCallback(base::Bind(
158 &DoWorkCallback,
159 base::Bind(&BluetoothLowEnergyExtensionFunction::DoWork, this)))) {
160 SetError(kErrorAdapterNotInitialized);
161 return false;
164 return true;
167 bool BluetoothLowEnergyConnectFunction::DoWork() {
168 DCHECK_CURRENTLY_ON(BrowserThread::UI);
170 BluetoothLowEnergyEventRouter* event_router =
171 GetEventRouter(browser_context());
173 // The adapter must be initialized at this point, but return an error instead
174 // of asserting.
175 if (!event_router->HasAdapter()) {
176 SetError(kErrorAdapterNotInitialized);
177 SendResponse(false);
178 return false;
181 scoped_ptr<apibtle::Connect::Params> params(
182 apibtle::Connect::Params::Create(*args_));
183 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
185 bool persistent = false; // Not persistent by default.
186 apibtle::ConnectProperties* properties = params.get()->properties.get();
187 if (properties)
188 persistent = properties->persistent;
190 event_router->Connect(
191 persistent,
192 extension(),
193 params->device_address,
194 base::Bind(&BluetoothLowEnergyConnectFunction::SuccessCallback, this),
195 base::Bind(&BluetoothLowEnergyConnectFunction::ErrorCallback, this));
197 return true;
200 void BluetoothLowEnergyConnectFunction::SuccessCallback() {
201 SendResponse(true);
204 void BluetoothLowEnergyConnectFunction::ErrorCallback(
205 BluetoothLowEnergyEventRouter::Status status) {
206 SetError(StatusToString(status));
207 SendResponse(false);
210 bool BluetoothLowEnergyDisconnectFunction::DoWork() {
211 DCHECK_CURRENTLY_ON(BrowserThread::UI);
213 BluetoothLowEnergyEventRouter* event_router =
214 GetEventRouter(browser_context());
216 // The adapter must be initialized at this point, but return an error instead
217 // of asserting.
218 if (!event_router->HasAdapter()) {
219 SetError(kErrorAdapterNotInitialized);
220 SendResponse(false);
221 return false;
224 scoped_ptr<apibtle::Disconnect::Params> params(
225 apibtle::Disconnect::Params::Create(*args_));
226 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
228 event_router->Disconnect(
229 extension(),
230 params->device_address,
231 base::Bind(&BluetoothLowEnergyDisconnectFunction::SuccessCallback, this),
232 base::Bind(&BluetoothLowEnergyDisconnectFunction::ErrorCallback, this));
234 return true;
237 void BluetoothLowEnergyDisconnectFunction::SuccessCallback() {
238 SendResponse(true);
241 void BluetoothLowEnergyDisconnectFunction::ErrorCallback(
242 BluetoothLowEnergyEventRouter::Status status) {
243 SetError(StatusToString(status));
244 SendResponse(false);
247 bool BluetoothLowEnergyGetServiceFunction::DoWork() {
248 DCHECK_CURRENTLY_ON(BrowserThread::UI);
250 BluetoothLowEnergyEventRouter* event_router =
251 GetEventRouter(browser_context());
253 // The adapter must be initialized at this point, but return an error instead
254 // of asserting.
255 if (!event_router->HasAdapter()) {
256 SetError(kErrorAdapterNotInitialized);
257 SendResponse(false);
258 return false;
261 scoped_ptr<apibtle::GetService::Params> params(
262 apibtle::GetService::Params::Create(*args_));
263 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
265 apibtle::Service service;
266 BluetoothLowEnergyEventRouter::Status status =
267 event_router->GetService(params->service_id, &service);
268 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
269 SetError(StatusToString(status));
270 SendResponse(false);
271 return false;
274 results_ = apibtle::GetService::Results::Create(service);
275 SendResponse(true);
277 return true;
280 bool BluetoothLowEnergyGetServicesFunction::DoWork() {
281 DCHECK_CURRENTLY_ON(BrowserThread::UI);
283 BluetoothLowEnergyEventRouter* event_router =
284 GetEventRouter(browser_context());
286 // The adapter must be initialized at this point, but return an error instead
287 // of asserting.
288 if (!event_router->HasAdapter()) {
289 SetError(kErrorAdapterNotInitialized);
290 SendResponse(false);
291 return false;
294 scoped_ptr<apibtle::GetServices::Params> params(
295 apibtle::GetServices::Params::Create(*args_));
296 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
298 BluetoothLowEnergyEventRouter::ServiceList service_list;
299 if (!event_router->GetServices(params->device_address, &service_list)) {
300 SetError(kErrorNotFound);
301 SendResponse(false);
302 return false;
305 results_ = apibtle::GetServices::Results::Create(service_list);
306 SendResponse(true);
308 return true;
311 bool BluetoothLowEnergyGetCharacteristicFunction::DoWork() {
312 DCHECK_CURRENTLY_ON(BrowserThread::UI);
314 BluetoothLowEnergyEventRouter* event_router =
315 GetEventRouter(browser_context());
317 // The adapter must be initialized at this point, but return an error instead
318 // of asserting.
319 if (!event_router->HasAdapter()) {
320 SetError(kErrorAdapterNotInitialized);
321 SendResponse(false);
322 return false;
325 scoped_ptr<apibtle::GetCharacteristic::Params> params(
326 apibtle::GetCharacteristic::Params::Create(*args_));
327 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
329 apibtle::Characteristic characteristic;
330 BluetoothLowEnergyEventRouter::Status status =
331 event_router->GetCharacteristic(
332 extension(), params->characteristic_id, &characteristic);
333 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
334 SetError(StatusToString(status));
335 SendResponse(false);
336 return false;
339 // Manually construct the result instead of using
340 // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
341 // enums correctly.
342 SetResult(apibtle::CharacteristicToValue(&characteristic).release());
343 SendResponse(true);
345 return true;
348 bool BluetoothLowEnergyGetCharacteristicsFunction::DoWork() {
349 DCHECK_CURRENTLY_ON(BrowserThread::UI);
351 BluetoothLowEnergyEventRouter* event_router =
352 GetEventRouter(browser_context());
354 // The adapter must be initialized at this point, but return an error instead
355 // of asserting.
356 if (!event_router->HasAdapter()) {
357 SetError(kErrorAdapterNotInitialized);
358 SendResponse(false);
359 return false;
362 scoped_ptr<apibtle::GetCharacteristics::Params> params(
363 apibtle::GetCharacteristics::Params::Create(*args_));
364 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
366 BluetoothLowEnergyEventRouter::CharacteristicList characteristic_list;
367 BluetoothLowEnergyEventRouter::Status status =
368 event_router->GetCharacteristics(
369 extension(), params->service_id, &characteristic_list);
370 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
371 SetError(StatusToString(status));
372 SendResponse(false);
373 return false;
376 // Manually construct the result instead of using
377 // apibtle::GetCharacteristics::Result::Create as it doesn't convert lists of
378 // enums correctly.
379 scoped_ptr<base::ListValue> result(new base::ListValue());
380 for (BluetoothLowEnergyEventRouter::CharacteristicList::iterator iter =
381 characteristic_list.begin();
382 iter != characteristic_list.end();
383 ++iter)
384 result->Append(apibtle::CharacteristicToValue(iter->get()).release());
386 SetResult(result.release());
387 SendResponse(true);
389 return true;
392 bool BluetoothLowEnergyGetIncludedServicesFunction::DoWork() {
393 DCHECK_CURRENTLY_ON(BrowserThread::UI);
395 BluetoothLowEnergyEventRouter* event_router =
396 GetEventRouter(browser_context());
398 // The adapter must be initialized at this point, but return an error instead
399 // of asserting.
400 if (!event_router->HasAdapter()) {
401 SetError(kErrorAdapterNotInitialized);
402 SendResponse(false);
403 return false;
406 scoped_ptr<apibtle::GetIncludedServices::Params> params(
407 apibtle::GetIncludedServices::Params::Create(*args_));
408 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
410 BluetoothLowEnergyEventRouter::ServiceList service_list;
411 BluetoothLowEnergyEventRouter::Status status =
412 event_router->GetIncludedServices(params->service_id, &service_list);
413 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
414 SetError(StatusToString(status));
415 SendResponse(false);
416 return false;
419 results_ = apibtle::GetIncludedServices::Results::Create(service_list);
420 SendResponse(true);
422 return true;
425 bool BluetoothLowEnergyGetDescriptorFunction::DoWork() {
426 DCHECK_CURRENTLY_ON(BrowserThread::UI);
428 BluetoothLowEnergyEventRouter* event_router =
429 GetEventRouter(browser_context());
431 // The adapter must be initialized at this point, but return an error instead
432 // of asserting.
433 if (!event_router->HasAdapter()) {
434 SetError(kErrorAdapterNotInitialized);
435 SendResponse(false);
436 return false;
439 scoped_ptr<apibtle::GetDescriptor::Params> params(
440 apibtle::GetDescriptor::Params::Create(*args_));
441 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
443 apibtle::Descriptor descriptor;
444 BluetoothLowEnergyEventRouter::Status status = event_router->GetDescriptor(
445 extension(), params->descriptor_id, &descriptor);
446 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
447 SetError(StatusToString(status));
448 SendResponse(false);
449 return false;
452 // Manually construct the result instead of using
453 // apibtle::GetDescriptor::Result::Create as it doesn't convert lists of enums
454 // correctly.
455 SetResult(apibtle::DescriptorToValue(&descriptor).release());
456 SendResponse(true);
458 return true;
461 bool BluetoothLowEnergyGetDescriptorsFunction::DoWork() {
462 DCHECK_CURRENTLY_ON(BrowserThread::UI);
464 BluetoothLowEnergyEventRouter* event_router =
465 GetEventRouter(browser_context());
467 // The adapter must be initialized at this point, but return an error instead
468 // of asserting.
469 if (!event_router->HasAdapter()) {
470 SetError(kErrorAdapterNotInitialized);
471 SendResponse(false);
472 return false;
475 scoped_ptr<apibtle::GetDescriptors::Params> params(
476 apibtle::GetDescriptors::Params::Create(*args_));
477 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
479 BluetoothLowEnergyEventRouter::DescriptorList descriptor_list;
480 BluetoothLowEnergyEventRouter::Status status = event_router->GetDescriptors(
481 extension(), params->characteristic_id, &descriptor_list);
482 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
483 SetError(StatusToString(status));
484 SendResponse(false);
485 return false;
488 // Manually construct the result instead of using
489 // apibtle::GetDescriptors::Result::Create as it doesn't convert lists of
490 // enums correctly.
491 scoped_ptr<base::ListValue> result(new base::ListValue());
492 for (BluetoothLowEnergyEventRouter::DescriptorList::iterator iter =
493 descriptor_list.begin();
494 iter != descriptor_list.end();
495 ++iter)
496 result->Append(apibtle::DescriptorToValue(iter->get()).release());
498 SetResult(result.release());
499 SendResponse(true);
501 return true;
504 bool BluetoothLowEnergyReadCharacteristicValueFunction::DoWork() {
505 DCHECK_CURRENTLY_ON(BrowserThread::UI);
507 BluetoothLowEnergyEventRouter* event_router =
508 GetEventRouter(browser_context());
510 // The adapter must be initialized at this point, but return an error instead
511 // of asserting.
512 if (!event_router->HasAdapter()) {
513 SetError(kErrorAdapterNotInitialized);
514 SendResponse(false);
515 return false;
518 scoped_ptr<apibtle::ReadCharacteristicValue::Params> params(
519 apibtle::ReadCharacteristicValue::Params::Create(*args_));
520 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
522 instance_id_ = params->characteristic_id;
523 event_router->ReadCharacteristicValue(
524 extension(),
525 instance_id_,
526 base::Bind(
527 &BluetoothLowEnergyReadCharacteristicValueFunction::SuccessCallback,
528 this),
529 base::Bind(
530 &BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback,
531 this));
533 return true;
536 void BluetoothLowEnergyReadCharacteristicValueFunction::SuccessCallback() {
537 // Obtain info on the characteristic and see whether or not the characteristic
538 // is still around.
539 apibtle::Characteristic characteristic;
540 BluetoothLowEnergyEventRouter::Status status =
541 GetEventRouter(browser_context())
542 ->GetCharacteristic(extension(), instance_id_, &characteristic);
543 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
544 SetError(StatusToString(status));
545 SendResponse(false);
546 return;
549 // Manually construct the result instead of using
550 // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
551 // enums correctly.
552 SetResult(apibtle::CharacteristicToValue(&characteristic).release());
553 SendResponse(true);
556 void BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback(
557 BluetoothLowEnergyEventRouter::Status status) {
558 SetError(StatusToString(status));
559 SendResponse(false);
562 bool BluetoothLowEnergyWriteCharacteristicValueFunction::DoWork() {
563 DCHECK_CURRENTLY_ON(BrowserThread::UI);
565 BluetoothLowEnergyEventRouter* event_router =
566 GetEventRouter(browser_context());
568 // The adapter must be initialized at this point, but return an error instead
569 // of asserting.
570 if (!event_router->HasAdapter()) {
571 SetError(kErrorAdapterNotInitialized);
572 SendResponse(false);
573 return false;
576 scoped_ptr<apibtle::WriteCharacteristicValue::Params> params(
577 apibtle::WriteCharacteristicValue::Params::Create(*args_));
578 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
580 std::vector<uint8> value(params->value.begin(), params->value.end());
581 event_router->WriteCharacteristicValue(
582 extension(),
583 params->characteristic_id,
584 value,
585 base::Bind(
586 &BluetoothLowEnergyWriteCharacteristicValueFunction::SuccessCallback,
587 this),
588 base::Bind(
589 &BluetoothLowEnergyWriteCharacteristicValueFunction::ErrorCallback,
590 this));
592 return true;
595 void BluetoothLowEnergyWriteCharacteristicValueFunction::SuccessCallback() {
596 results_ = apibtle::WriteCharacteristicValue::Results::Create();
597 SendResponse(true);
600 void BluetoothLowEnergyWriteCharacteristicValueFunction::ErrorCallback(
601 BluetoothLowEnergyEventRouter::Status status) {
602 SetError(StatusToString(status));
603 SendResponse(false);
606 bool BluetoothLowEnergyStartCharacteristicNotificationsFunction::DoWork() {
607 DCHECK_CURRENTLY_ON(BrowserThread::UI);
609 BluetoothLowEnergyEventRouter* event_router =
610 GetEventRouter(browser_context());
612 // The adapter must be initialized at this point, but return an error instead
613 // of asserting.
614 if (!event_router->HasAdapter()) {
615 SetError(kErrorAdapterNotInitialized);
616 SendResponse(false);
617 return false;
620 scoped_ptr<apibtle::StartCharacteristicNotifications::Params> params(
621 apibtle::StartCharacteristicNotifications::Params::Create(*args_));
622 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
624 bool persistent = false; // Not persistent by default.
625 apibtle::NotificationProperties* properties = params.get()->properties.get();
626 if (properties)
627 persistent = properties->persistent;
629 event_router->StartCharacteristicNotifications(
630 persistent,
631 extension(),
632 params->characteristic_id,
633 base::Bind(&BluetoothLowEnergyStartCharacteristicNotificationsFunction::
634 SuccessCallback,
635 this),
636 base::Bind(&BluetoothLowEnergyStartCharacteristicNotificationsFunction::
637 ErrorCallback,
638 this));
640 return true;
643 void
644 BluetoothLowEnergyStartCharacteristicNotificationsFunction::SuccessCallback() {
645 SendResponse(true);
648 void BluetoothLowEnergyStartCharacteristicNotificationsFunction::ErrorCallback(
649 BluetoothLowEnergyEventRouter::Status status) {
650 SetError(StatusToString(status));
651 SendResponse(false);
654 bool BluetoothLowEnergyStopCharacteristicNotificationsFunction::DoWork() {
655 DCHECK_CURRENTLY_ON(BrowserThread::UI);
657 BluetoothLowEnergyEventRouter* event_router =
658 GetEventRouter(browser_context());
660 // The adapter must be initialized at this point, but return an error instead
661 // of asserting.
662 if (!event_router->HasAdapter()) {
663 SetError(kErrorAdapterNotInitialized);
664 SendResponse(false);
665 return false;
668 scoped_ptr<apibtle::StopCharacteristicNotifications::Params> params(
669 apibtle::StopCharacteristicNotifications::Params::Create(*args_));
670 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
672 event_router->StopCharacteristicNotifications(
673 extension(),
674 params->characteristic_id,
675 base::Bind(&BluetoothLowEnergyStopCharacteristicNotificationsFunction::
676 SuccessCallback,
677 this),
678 base::Bind(&BluetoothLowEnergyStopCharacteristicNotificationsFunction::
679 ErrorCallback,
680 this));
682 return true;
685 void
686 BluetoothLowEnergyStopCharacteristicNotificationsFunction::SuccessCallback() {
687 SendResponse(true);
690 void BluetoothLowEnergyStopCharacteristicNotificationsFunction::ErrorCallback(
691 BluetoothLowEnergyEventRouter::Status status) {
692 SetError(StatusToString(status));
693 SendResponse(false);
696 bool BluetoothLowEnergyReadDescriptorValueFunction::DoWork() {
697 DCHECK_CURRENTLY_ON(BrowserThread::UI);
699 BluetoothLowEnergyEventRouter* event_router =
700 GetEventRouter(browser_context());
702 // The adapter must be initialized at this point, but return an error instead
703 // of asserting.
704 if (!event_router->HasAdapter()) {
705 SetError(kErrorAdapterNotInitialized);
706 SendResponse(false);
707 return false;
710 scoped_ptr<apibtle::ReadDescriptorValue::Params> params(
711 apibtle::ReadDescriptorValue::Params::Create(*args_));
712 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
714 instance_id_ = params->descriptor_id;
715 event_router->ReadDescriptorValue(
716 extension(),
717 instance_id_,
718 base::Bind(
719 &BluetoothLowEnergyReadDescriptorValueFunction::SuccessCallback,
720 this),
721 base::Bind(&BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback,
722 this));
724 return true;
727 void BluetoothLowEnergyReadDescriptorValueFunction::SuccessCallback() {
728 // Obtain info on the descriptor and see whether or not the descriptor is
729 // still around.
730 apibtle::Descriptor descriptor;
731 BluetoothLowEnergyEventRouter::Status status =
732 GetEventRouter(browser_context())
733 ->GetDescriptor(extension(), instance_id_, &descriptor);
734 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
735 SetError(StatusToString(status));
736 SendResponse(false);
737 return;
740 // Manually construct the result instead of using
741 // apibtle::GetDescriptor::Results::Create as it doesn't convert lists of
742 // enums correctly.
743 SetResult(apibtle::DescriptorToValue(&descriptor).release());
744 SendResponse(true);
747 void BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback(
748 BluetoothLowEnergyEventRouter::Status status) {
749 SetError(StatusToString(status));
750 SendResponse(false);
753 bool BluetoothLowEnergyWriteDescriptorValueFunction::DoWork() {
754 DCHECK_CURRENTLY_ON(BrowserThread::UI);
756 BluetoothLowEnergyEventRouter* event_router =
757 GetEventRouter(browser_context());
759 // The adapter must be initialized at this point, but return an error instead
760 // of asserting.
761 if (!event_router->HasAdapter()) {
762 SetError(kErrorAdapterNotInitialized);
763 SendResponse(false);
764 return false;
767 scoped_ptr<apibtle::WriteDescriptorValue::Params> params(
768 apibtle::WriteDescriptorValue::Params::Create(*args_));
769 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
771 std::vector<uint8> value(params->value.begin(), params->value.end());
772 event_router->WriteDescriptorValue(
773 extension(),
774 params->descriptor_id,
775 value,
776 base::Bind(
777 &BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback,
778 this),
779 base::Bind(&BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback,
780 this));
782 return true;
785 void BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback() {
786 results_ = apibtle::WriteDescriptorValue::Results::Create();
787 SendResponse(true);
790 void BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback(
791 BluetoothLowEnergyEventRouter::Status status) {
792 SetError(StatusToString(status));
793 SendResponse(false);
796 } // namespace core_api
797 } // namespace extensions