Add testing/scripts/OWNERS
[chromium-blink-merge.git] / extensions / browser / api / bluetooth_low_energy / bluetooth_low_energy_api.cc
blob17b47d290e5edc8a98114acfd6f58b3c9a854555
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 kErrorInProgress[] = "In progress";
31 const char kErrorNotConnected[] = "Not connected";
32 const char kErrorNotNotifying[] = "Not notifying";
33 const char kErrorNotFound[] = "Instance not found";
34 const char kErrorOperationFailed[] = "Operation failed";
35 const char kErrorPermissionDenied[] = "Permission denied";
36 const char kErrorAuthenticationFailed[] = "Authentication failed";
37 const char kErrorCanceled[] = "Request canceled";
38 const char kErrorTimeout[] = "Operation timed out";
39 const char kErrorInvalidLength[] = "Invalid data length";
40 const char kErrorGattNotSupported[] = "Operation not supported by this service";
41 const char kErrorUnsupportedDevice[] =
42 "This device is not supported on the current platform";
43 const char kErrorPlatformNotSupported[] =
44 "This operation is not supported on the current platform";
46 // Returns the correct error string based on error status |status|. This is used
47 // to set the value of |chrome.runtime.lastError.message| and should not be
48 // passed |BluetoothLowEnergyEventRouter::kStatusSuccess|.
49 std::string StatusToString(BluetoothLowEnergyEventRouter::Status status) {
50 switch (status) {
51 case BluetoothLowEnergyEventRouter::kStatusErrorPermissionDenied:
52 return kErrorPermissionDenied;
53 case BluetoothLowEnergyEventRouter::kStatusErrorNotFound:
54 return kErrorNotFound;
55 case BluetoothLowEnergyEventRouter::kStatusErrorAlreadyConnected:
56 return kErrorAlreadyConnected;
57 case BluetoothLowEnergyEventRouter::kStatusErrorAlreadyNotifying:
58 return kErrorAlreadyNotifying;
59 case BluetoothLowEnergyEventRouter::kStatusErrorNotConnected:
60 return kErrorNotConnected;
61 case BluetoothLowEnergyEventRouter::kStatusErrorNotNotifying:
62 return kErrorNotNotifying;
63 case BluetoothLowEnergyEventRouter::kStatusErrorInProgress:
64 return kErrorInProgress;
65 case BluetoothLowEnergyEventRouter::kStatusErrorAuthenticationFailed:
66 return kErrorAuthenticationFailed;
67 case BluetoothLowEnergyEventRouter::kStatusErrorCanceled:
68 return kErrorCanceled;
69 case BluetoothLowEnergyEventRouter::kStatusErrorTimeout:
70 return kErrorTimeout;
71 case BluetoothLowEnergyEventRouter::kStatusErrorUnsupportedDevice:
72 return kErrorUnsupportedDevice;
73 case BluetoothLowEnergyEventRouter::kStatusErrorInvalidLength:
74 return kErrorInvalidLength;
75 case BluetoothLowEnergyEventRouter::kStatusErrorGattNotSupported:
76 return kErrorGattNotSupported;
77 case BluetoothLowEnergyEventRouter::kStatusSuccess:
78 NOTREACHED();
79 break;
80 default:
81 return kErrorOperationFailed;
83 return "";
86 extensions::BluetoothLowEnergyEventRouter* GetEventRouter(
87 BrowserContext* context) {
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89 return extensions::BluetoothLowEnergyAPI::Get(context)->event_router();
92 void DoWorkCallback(const base::Callback<bool()>& callback) {
93 DCHECK(!callback.is_null());
94 callback.Run();
97 } // namespace
100 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI> >
101 g_factory = LAZY_INSTANCE_INITIALIZER;
103 // static
104 BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI>*
105 BluetoothLowEnergyAPI::GetFactoryInstance() {
106 return g_factory.Pointer();
109 // static
110 BluetoothLowEnergyAPI* BluetoothLowEnergyAPI::Get(BrowserContext* context) {
111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 return GetFactoryInstance()->Get(context);
115 BluetoothLowEnergyAPI::BluetoothLowEnergyAPI(BrowserContext* context)
116 : event_router_(new BluetoothLowEnergyEventRouter(context)),
117 browser_context_(context) {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
121 BluetoothLowEnergyAPI::~BluetoothLowEnergyAPI() {
124 void BluetoothLowEnergyAPI::Shutdown() {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
128 namespace core_api {
130 BluetoothLowEnergyExtensionFunction::BluetoothLowEnergyExtensionFunction() {
133 BluetoothLowEnergyExtensionFunction::~BluetoothLowEnergyExtensionFunction() {
136 bool BluetoothLowEnergyExtensionFunction::RunAsync() {
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
139 if (!BluetoothManifestData::CheckLowEnergyPermitted(extension())) {
140 error_ = kErrorPermissionDenied;
141 return false;
144 BluetoothLowEnergyEventRouter* event_router =
145 GetEventRouter(browser_context());
146 if (!event_router->IsBluetoothSupported()) {
147 SetError(kErrorPlatformNotSupported);
148 return false;
151 // It is safe to pass |this| here as ExtensionFunction is refcounted.
152 if (!event_router->InitializeAdapterAndInvokeCallback(base::Bind(
153 &DoWorkCallback,
154 base::Bind(&BluetoothLowEnergyExtensionFunction::DoWork, this)))) {
155 SetError(kErrorAdapterNotInitialized);
156 return false;
159 return true;
162 bool BluetoothLowEnergyConnectFunction::DoWork() {
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
165 BluetoothLowEnergyEventRouter* event_router =
166 GetEventRouter(browser_context());
168 // The adapter must be initialized at this point, but return an error instead
169 // of asserting.
170 if (!event_router->HasAdapter()) {
171 SetError(kErrorAdapterNotInitialized);
172 SendResponse(false);
173 return false;
176 scoped_ptr<apibtle::Connect::Params> params(
177 apibtle::Connect::Params::Create(*args_));
178 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
180 bool persistent = false; // Not persistent by default.
181 apibtle::ConnectProperties* properties = params.get()->properties.get();
182 if (properties)
183 persistent = properties->persistent;
185 event_router->Connect(
186 persistent,
187 extension(),
188 params->device_address,
189 base::Bind(&BluetoothLowEnergyConnectFunction::SuccessCallback, this),
190 base::Bind(&BluetoothLowEnergyConnectFunction::ErrorCallback, this));
192 return true;
195 void BluetoothLowEnergyConnectFunction::SuccessCallback() {
196 SendResponse(true);
199 void BluetoothLowEnergyConnectFunction::ErrorCallback(
200 BluetoothLowEnergyEventRouter::Status status) {
201 SetError(StatusToString(status));
202 SendResponse(false);
205 bool BluetoothLowEnergyDisconnectFunction::DoWork() {
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
208 BluetoothLowEnergyEventRouter* event_router =
209 GetEventRouter(browser_context());
211 // The adapter must be initialized at this point, but return an error instead
212 // of asserting.
213 if (!event_router->HasAdapter()) {
214 SetError(kErrorAdapterNotInitialized);
215 SendResponse(false);
216 return false;
219 scoped_ptr<apibtle::Disconnect::Params> params(
220 apibtle::Disconnect::Params::Create(*args_));
221 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
223 event_router->Disconnect(
224 extension(),
225 params->device_address,
226 base::Bind(&BluetoothLowEnergyDisconnectFunction::SuccessCallback, this),
227 base::Bind(&BluetoothLowEnergyDisconnectFunction::ErrorCallback, this));
229 return true;
232 void BluetoothLowEnergyDisconnectFunction::SuccessCallback() {
233 SendResponse(true);
236 void BluetoothLowEnergyDisconnectFunction::ErrorCallback(
237 BluetoothLowEnergyEventRouter::Status status) {
238 SetError(StatusToString(status));
239 SendResponse(false);
242 bool BluetoothLowEnergyGetServiceFunction::DoWork() {
243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
245 BluetoothLowEnergyEventRouter* event_router =
246 GetEventRouter(browser_context());
248 // The adapter must be initialized at this point, but return an error instead
249 // of asserting.
250 if (!event_router->HasAdapter()) {
251 SetError(kErrorAdapterNotInitialized);
252 SendResponse(false);
253 return false;
256 scoped_ptr<apibtle::GetService::Params> params(
257 apibtle::GetService::Params::Create(*args_));
258 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
260 apibtle::Service service;
261 BluetoothLowEnergyEventRouter::Status status =
262 event_router->GetService(params->service_id, &service);
263 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
264 SetError(StatusToString(status));
265 SendResponse(false);
266 return false;
269 results_ = apibtle::GetService::Results::Create(service);
270 SendResponse(true);
272 return true;
275 bool BluetoothLowEnergyGetServicesFunction::DoWork() {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
278 BluetoothLowEnergyEventRouter* event_router =
279 GetEventRouter(browser_context());
281 // The adapter must be initialized at this point, but return an error instead
282 // of asserting.
283 if (!event_router->HasAdapter()) {
284 SetError(kErrorAdapterNotInitialized);
285 SendResponse(false);
286 return false;
289 scoped_ptr<apibtle::GetServices::Params> params(
290 apibtle::GetServices::Params::Create(*args_));
291 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
293 BluetoothLowEnergyEventRouter::ServiceList service_list;
294 if (!event_router->GetServices(params->device_address, &service_list)) {
295 SetError(kErrorNotFound);
296 SendResponse(false);
297 return false;
300 results_ = apibtle::GetServices::Results::Create(service_list);
301 SendResponse(true);
303 return true;
306 bool BluetoothLowEnergyGetCharacteristicFunction::DoWork() {
307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309 BluetoothLowEnergyEventRouter* event_router =
310 GetEventRouter(browser_context());
312 // The adapter must be initialized at this point, but return an error instead
313 // of asserting.
314 if (!event_router->HasAdapter()) {
315 SetError(kErrorAdapterNotInitialized);
316 SendResponse(false);
317 return false;
320 scoped_ptr<apibtle::GetCharacteristic::Params> params(
321 apibtle::GetCharacteristic::Params::Create(*args_));
322 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
324 apibtle::Characteristic characteristic;
325 BluetoothLowEnergyEventRouter::Status status =
326 event_router->GetCharacteristic(
327 extension(), params->characteristic_id, &characteristic);
328 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
329 SetError(StatusToString(status));
330 SendResponse(false);
331 return false;
334 // Manually construct the result instead of using
335 // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
336 // enums correctly.
337 SetResult(apibtle::CharacteristicToValue(&characteristic).release());
338 SendResponse(true);
340 return true;
343 bool BluetoothLowEnergyGetCharacteristicsFunction::DoWork() {
344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
346 BluetoothLowEnergyEventRouter* event_router =
347 GetEventRouter(browser_context());
349 // The adapter must be initialized at this point, but return an error instead
350 // of asserting.
351 if (!event_router->HasAdapter()) {
352 SetError(kErrorAdapterNotInitialized);
353 SendResponse(false);
354 return false;
357 scoped_ptr<apibtle::GetCharacteristics::Params> params(
358 apibtle::GetCharacteristics::Params::Create(*args_));
359 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
361 BluetoothLowEnergyEventRouter::CharacteristicList characteristic_list;
362 BluetoothLowEnergyEventRouter::Status status =
363 event_router->GetCharacteristics(
364 extension(), params->service_id, &characteristic_list);
365 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
366 SetError(StatusToString(status));
367 SendResponse(false);
368 return false;
371 // Manually construct the result instead of using
372 // apibtle::GetCharacteristics::Result::Create as it doesn't convert lists of
373 // enums correctly.
374 scoped_ptr<base::ListValue> result(new base::ListValue());
375 for (BluetoothLowEnergyEventRouter::CharacteristicList::iterator iter =
376 characteristic_list.begin();
377 iter != characteristic_list.end();
378 ++iter)
379 result->Append(apibtle::CharacteristicToValue(iter->get()).release());
381 SetResult(result.release());
382 SendResponse(true);
384 return true;
387 bool BluetoothLowEnergyGetIncludedServicesFunction::DoWork() {
388 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
390 BluetoothLowEnergyEventRouter* event_router =
391 GetEventRouter(browser_context());
393 // The adapter must be initialized at this point, but return an error instead
394 // of asserting.
395 if (!event_router->HasAdapter()) {
396 SetError(kErrorAdapterNotInitialized);
397 SendResponse(false);
398 return false;
401 scoped_ptr<apibtle::GetIncludedServices::Params> params(
402 apibtle::GetIncludedServices::Params::Create(*args_));
403 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
405 BluetoothLowEnergyEventRouter::ServiceList service_list;
406 BluetoothLowEnergyEventRouter::Status status =
407 event_router->GetIncludedServices(params->service_id, &service_list);
408 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
409 SetError(StatusToString(status));
410 SendResponse(false);
411 return false;
414 results_ = apibtle::GetIncludedServices::Results::Create(service_list);
415 SendResponse(true);
417 return true;
420 bool BluetoothLowEnergyGetDescriptorFunction::DoWork() {
421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
423 BluetoothLowEnergyEventRouter* event_router =
424 GetEventRouter(browser_context());
426 // The adapter must be initialized at this point, but return an error instead
427 // of asserting.
428 if (!event_router->HasAdapter()) {
429 SetError(kErrorAdapterNotInitialized);
430 SendResponse(false);
431 return false;
434 scoped_ptr<apibtle::GetDescriptor::Params> params(
435 apibtle::GetDescriptor::Params::Create(*args_));
436 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
438 apibtle::Descriptor descriptor;
439 BluetoothLowEnergyEventRouter::Status status = event_router->GetDescriptor(
440 extension(), params->descriptor_id, &descriptor);
441 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
442 SetError(StatusToString(status));
443 SendResponse(false);
444 return false;
447 // Manually construct the result instead of using
448 // apibtle::GetDescriptor::Result::Create as it doesn't convert lists of enums
449 // correctly.
450 SetResult(apibtle::DescriptorToValue(&descriptor).release());
451 SendResponse(true);
453 return true;
456 bool BluetoothLowEnergyGetDescriptorsFunction::DoWork() {
457 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
459 BluetoothLowEnergyEventRouter* event_router =
460 GetEventRouter(browser_context());
462 // The adapter must be initialized at this point, but return an error instead
463 // of asserting.
464 if (!event_router->HasAdapter()) {
465 SetError(kErrorAdapterNotInitialized);
466 SendResponse(false);
467 return false;
470 scoped_ptr<apibtle::GetDescriptors::Params> params(
471 apibtle::GetDescriptors::Params::Create(*args_));
472 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
474 BluetoothLowEnergyEventRouter::DescriptorList descriptor_list;
475 BluetoothLowEnergyEventRouter::Status status = event_router->GetDescriptors(
476 extension(), params->characteristic_id, &descriptor_list);
477 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
478 SetError(StatusToString(status));
479 SendResponse(false);
480 return false;
483 // Manually construct the result instead of using
484 // apibtle::GetDescriptors::Result::Create as it doesn't convert lists of
485 // enums correctly.
486 scoped_ptr<base::ListValue> result(new base::ListValue());
487 for (BluetoothLowEnergyEventRouter::DescriptorList::iterator iter =
488 descriptor_list.begin();
489 iter != descriptor_list.end();
490 ++iter)
491 result->Append(apibtle::DescriptorToValue(iter->get()).release());
493 SetResult(result.release());
494 SendResponse(true);
496 return true;
499 bool BluetoothLowEnergyReadCharacteristicValueFunction::DoWork() {
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
502 BluetoothLowEnergyEventRouter* event_router =
503 GetEventRouter(browser_context());
505 // The adapter must be initialized at this point, but return an error instead
506 // of asserting.
507 if (!event_router->HasAdapter()) {
508 SetError(kErrorAdapterNotInitialized);
509 SendResponse(false);
510 return false;
513 scoped_ptr<apibtle::ReadCharacteristicValue::Params> params(
514 apibtle::ReadCharacteristicValue::Params::Create(*args_));
515 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
517 instance_id_ = params->characteristic_id;
518 event_router->ReadCharacteristicValue(
519 extension(),
520 instance_id_,
521 base::Bind(
522 &BluetoothLowEnergyReadCharacteristicValueFunction::SuccessCallback,
523 this),
524 base::Bind(
525 &BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback,
526 this));
528 return true;
531 void BluetoothLowEnergyReadCharacteristicValueFunction::SuccessCallback() {
532 // Obtain info on the characteristic and see whether or not the characteristic
533 // is still around.
534 apibtle::Characteristic characteristic;
535 BluetoothLowEnergyEventRouter::Status status =
536 GetEventRouter(browser_context())
537 ->GetCharacteristic(extension(), instance_id_, &characteristic);
538 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
539 SetError(StatusToString(status));
540 SendResponse(false);
541 return;
544 // Manually construct the result instead of using
545 // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
546 // enums correctly.
547 SetResult(apibtle::CharacteristicToValue(&characteristic).release());
548 SendResponse(true);
551 void BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback(
552 BluetoothLowEnergyEventRouter::Status status) {
553 SetError(StatusToString(status));
554 SendResponse(false);
557 bool BluetoothLowEnergyWriteCharacteristicValueFunction::DoWork() {
558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
560 BluetoothLowEnergyEventRouter* event_router =
561 GetEventRouter(browser_context());
563 // The adapter must be initialized at this point, but return an error instead
564 // of asserting.
565 if (!event_router->HasAdapter()) {
566 SetError(kErrorAdapterNotInitialized);
567 SendResponse(false);
568 return false;
571 scoped_ptr<apibtle::WriteCharacteristicValue::Params> params(
572 apibtle::WriteCharacteristicValue::Params::Create(*args_));
573 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
575 std::vector<uint8> value(params->value.begin(), params->value.end());
576 event_router->WriteCharacteristicValue(
577 extension(),
578 params->characteristic_id,
579 value,
580 base::Bind(
581 &BluetoothLowEnergyWriteCharacteristicValueFunction::SuccessCallback,
582 this),
583 base::Bind(
584 &BluetoothLowEnergyWriteCharacteristicValueFunction::ErrorCallback,
585 this));
587 return true;
590 void BluetoothLowEnergyWriteCharacteristicValueFunction::SuccessCallback() {
591 results_ = apibtle::WriteCharacteristicValue::Results::Create();
592 SendResponse(true);
595 void BluetoothLowEnergyWriteCharacteristicValueFunction::ErrorCallback(
596 BluetoothLowEnergyEventRouter::Status status) {
597 SetError(StatusToString(status));
598 SendResponse(false);
601 bool BluetoothLowEnergyStartCharacteristicNotificationsFunction::DoWork() {
602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
604 BluetoothLowEnergyEventRouter* event_router =
605 GetEventRouter(browser_context());
607 // The adapter must be initialized at this point, but return an error instead
608 // of asserting.
609 if (!event_router->HasAdapter()) {
610 SetError(kErrorAdapterNotInitialized);
611 SendResponse(false);
612 return false;
615 scoped_ptr<apibtle::StartCharacteristicNotifications::Params> params(
616 apibtle::StartCharacteristicNotifications::Params::Create(*args_));
617 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
619 bool persistent = false; // Not persistent by default.
620 apibtle::NotificationProperties* properties = params.get()->properties.get();
621 if (properties)
622 persistent = properties->persistent;
624 event_router->StartCharacteristicNotifications(
625 persistent,
626 extension(),
627 params->characteristic_id,
628 base::Bind(&BluetoothLowEnergyStartCharacteristicNotificationsFunction::
629 SuccessCallback,
630 this),
631 base::Bind(&BluetoothLowEnergyStartCharacteristicNotificationsFunction::
632 ErrorCallback,
633 this));
635 return true;
638 void
639 BluetoothLowEnergyStartCharacteristicNotificationsFunction::SuccessCallback() {
640 SendResponse(true);
643 void BluetoothLowEnergyStartCharacteristicNotificationsFunction::ErrorCallback(
644 BluetoothLowEnergyEventRouter::Status status) {
645 SetError(StatusToString(status));
646 SendResponse(false);
649 bool BluetoothLowEnergyStopCharacteristicNotificationsFunction::DoWork() {
650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
652 BluetoothLowEnergyEventRouter* event_router =
653 GetEventRouter(browser_context());
655 // The adapter must be initialized at this point, but return an error instead
656 // of asserting.
657 if (!event_router->HasAdapter()) {
658 SetError(kErrorAdapterNotInitialized);
659 SendResponse(false);
660 return false;
663 scoped_ptr<apibtle::StopCharacteristicNotifications::Params> params(
664 apibtle::StopCharacteristicNotifications::Params::Create(*args_));
665 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
667 event_router->StopCharacteristicNotifications(
668 extension(),
669 params->characteristic_id,
670 base::Bind(&BluetoothLowEnergyStopCharacteristicNotificationsFunction::
671 SuccessCallback,
672 this),
673 base::Bind(&BluetoothLowEnergyStopCharacteristicNotificationsFunction::
674 ErrorCallback,
675 this));
677 return true;
680 void
681 BluetoothLowEnergyStopCharacteristicNotificationsFunction::SuccessCallback() {
682 SendResponse(true);
685 void BluetoothLowEnergyStopCharacteristicNotificationsFunction::ErrorCallback(
686 BluetoothLowEnergyEventRouter::Status status) {
687 SetError(StatusToString(status));
688 SendResponse(false);
691 bool BluetoothLowEnergyReadDescriptorValueFunction::DoWork() {
692 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
694 BluetoothLowEnergyEventRouter* event_router =
695 GetEventRouter(browser_context());
697 // The adapter must be initialized at this point, but return an error instead
698 // of asserting.
699 if (!event_router->HasAdapter()) {
700 SetError(kErrorAdapterNotInitialized);
701 SendResponse(false);
702 return false;
705 scoped_ptr<apibtle::ReadDescriptorValue::Params> params(
706 apibtle::ReadDescriptorValue::Params::Create(*args_));
707 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
709 instance_id_ = params->descriptor_id;
710 event_router->ReadDescriptorValue(
711 extension(),
712 instance_id_,
713 base::Bind(
714 &BluetoothLowEnergyReadDescriptorValueFunction::SuccessCallback,
715 this),
716 base::Bind(&BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback,
717 this));
719 return true;
722 void BluetoothLowEnergyReadDescriptorValueFunction::SuccessCallback() {
723 // Obtain info on the descriptor and see whether or not the descriptor is
724 // still around.
725 apibtle::Descriptor descriptor;
726 BluetoothLowEnergyEventRouter::Status status =
727 GetEventRouter(browser_context())
728 ->GetDescriptor(extension(), instance_id_, &descriptor);
729 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
730 SetError(StatusToString(status));
731 SendResponse(false);
732 return;
735 // Manually construct the result instead of using
736 // apibtle::GetDescriptor::Results::Create as it doesn't convert lists of
737 // enums correctly.
738 SetResult(apibtle::DescriptorToValue(&descriptor).release());
739 SendResponse(true);
742 void BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback(
743 BluetoothLowEnergyEventRouter::Status status) {
744 SetError(StatusToString(status));
745 SendResponse(false);
748 bool BluetoothLowEnergyWriteDescriptorValueFunction::DoWork() {
749 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
751 BluetoothLowEnergyEventRouter* event_router =
752 GetEventRouter(browser_context());
754 // The adapter must be initialized at this point, but return an error instead
755 // of asserting.
756 if (!event_router->HasAdapter()) {
757 SetError(kErrorAdapterNotInitialized);
758 SendResponse(false);
759 return false;
762 scoped_ptr<apibtle::WriteDescriptorValue::Params> params(
763 apibtle::WriteDescriptorValue::Params::Create(*args_));
764 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
766 std::vector<uint8> value(params->value.begin(), params->value.end());
767 event_router->WriteDescriptorValue(
768 extension(),
769 params->descriptor_id,
770 value,
771 base::Bind(
772 &BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback,
773 this),
774 base::Bind(&BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback,
775 this));
777 return true;
780 void BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback() {
781 results_ = apibtle::WriteDescriptorValue::Results::Create();
782 SendResponse(true);
785 void BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback(
786 BluetoothLowEnergyEventRouter::Status status) {
787 SetError(StatusToString(status));
788 SendResponse(false);
791 } // namespace core_api
792 } // namespace extensions