Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc

Issue 2370373002: Move chrome.bluetoothLowEnergy out of //chrome. (Closed)
Patch Set: build fix Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_low_energy/bluetooth_low_energ y_api.h"
6
7 #include <stdint.h>
8 #include <algorithm>
9 #include <iterator>
10 #include <utility>
11 #include <vector>
12
13 #include "base/bind.h"
14 #include "base/callback.h"
15 #include "base/callback_forward.h"
16 #include "base/command_line.h"
17 #include "base/lazy_instance.h"
18 #include "base/logging.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/values.h"
21 #include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h"
22 #include "chrome/common/extensions/api/bluetooth_low_energy.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "device/bluetooth/bluetooth_adapter.h"
25 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
26 #include "device/bluetooth/bluetooth_local_gatt_characteristic.h"
27 #include "device/bluetooth/bluetooth_local_gatt_descriptor.h"
28 #include "device/bluetooth/bluetooth_local_gatt_service.h"
29 #include "device/bluetooth/bluetooth_uuid.h"
30 #include "extensions/common/api/bluetooth/bluetooth_manifest_data.h"
31 #include "extensions/common/extension.h"
32 #include "extensions/common/switches.h"
33
34 #if defined(OS_CHROMEOS)
35 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
36 #endif
37
38 using content::BrowserContext;
39 using content::BrowserThread;
40
41 namespace apibtle = extensions::api::bluetooth_low_energy;
42
43 namespace extensions {
44
45 namespace {
46
47 const char kErrorAdapterNotInitialized[] =
48 "Could not initialize Bluetooth adapter";
49 const char kErrorAlreadyConnected[] = "Already connected";
50 const char kErrorAlreadyNotifying[] = "Already notifying";
51 const char kErrorAttributeLengthInvalid[] = "Attribute length invalid";
52 const char kErrorAuthenticationFailed[] = "Authentication failed";
53 const char kErrorCanceled[] = "Request canceled";
54 const char kErrorConnectionCongested[] = "Connection congested";
55 const char kErrorGattNotSupported[] = "Operation not supported by this service";
56 const char kErrorHigherSecurity[] = "Higher security needed";
57 const char kErrorInProgress[] = "In progress";
58 const char kErrorInsufficientAuthorization[] = "Insufficient authorization";
59 const char kErrorInsufficientEncryption[] = "Insufficient encryption";
60 const char kErrorInvalidAdvertisementLength[] = "Invalid advertisement length";
61 const char kErrorInvalidLength[] = "Invalid attribute value length";
62 const char kErrorNotConnected[] = "Not connected";
63 const char kErrorNotFound[] = "Instance not found";
64 const char kErrorNotNotifying[] = "Not notifying";
65 const char kErrorOffsetInvalid[] = "Offset invalid";
66 const char kErrorOperationFailed[] = "Operation failed";
67 const char kErrorPermissionDenied[] = "Permission denied";
68 const char kErrorPlatformNotSupported[] =
69 "This operation is not supported on the current platform";
70 const char kErrorRequestNotSupported[] = "Request not supported";
71 const char kErrorTimeout[] = "Operation timed out";
72 const char kErrorUnsupportedDevice[] =
73 "This device is not supported on the current platform";
74 const char kErrorInvalidServiceId[] = "The service ID doesn't exist.";
75 const char kErrorInvalidCharacteristicId[] =
76 "The characteristic ID doesn't exist.";
77 const char kErrorNotifyPropertyNotSet[] =
78 "The characteristic does not have the notify property set.";
79 const char kErrorIndicatePropertyNotSet[] =
80 "The characteristic does not have the indicate property set.";
81 const char kErrorServiceNotRegistered[] =
82 "The characteristic is not owned by a service that is registered.";
83 const char kErrorUnknownNotificationError[] =
84 "An unknown notification error occured.";
85
86 const char kStatusAdvertisementAlreadyExists[] =
87 "An advertisement is already advertising";
88 const char kStatusAdvertisementDoesNotExist[] =
89 "This advertisement does not exist";
90 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
91 const char kStatusInvalidAdvertisingInterval[] =
92 "Invalid advertising interval specified.";
93 #endif
94
95 // Returns the correct error string based on error status |status|. This is used
96 // to set the value of |chrome.runtime.lastError.message| and should not be
97 // passed |BluetoothLowEnergyEventRouter::kStatusSuccess|.
98 std::string StatusToString(BluetoothLowEnergyEventRouter::Status status) {
99 switch (status) {
100 case BluetoothLowEnergyEventRouter::kStatusErrorAlreadyConnected:
101 return kErrorAlreadyConnected;
102 case BluetoothLowEnergyEventRouter::kStatusErrorAlreadyNotifying:
103 return kErrorAlreadyNotifying;
104 case BluetoothLowEnergyEventRouter::kStatusErrorAttributeLengthInvalid:
105 return kErrorAttributeLengthInvalid;
106 case BluetoothLowEnergyEventRouter::kStatusErrorAuthenticationFailed:
107 return kErrorAuthenticationFailed;
108 case BluetoothLowEnergyEventRouter::kStatusErrorCanceled:
109 return kErrorCanceled;
110 case BluetoothLowEnergyEventRouter::kStatusErrorConnectionCongested:
111 return kErrorConnectionCongested;
112 case BluetoothLowEnergyEventRouter::kStatusErrorGattNotSupported:
113 return kErrorGattNotSupported;
114 case BluetoothLowEnergyEventRouter::kStatusErrorHigherSecurity:
115 return kErrorHigherSecurity;
116 case BluetoothLowEnergyEventRouter::kStatusErrorInProgress:
117 return kErrorInProgress;
118 case BluetoothLowEnergyEventRouter::kStatusErrorInsufficientAuthorization:
119 return kErrorInsufficientAuthorization;
120 case BluetoothLowEnergyEventRouter::kStatusErrorInsufficientEncryption:
121 return kErrorInsufficientEncryption;
122 case BluetoothLowEnergyEventRouter::kStatusErrorInvalidLength:
123 return kErrorInvalidLength;
124 case BluetoothLowEnergyEventRouter::kStatusErrorNotConnected:
125 return kErrorNotConnected;
126 case BluetoothLowEnergyEventRouter::kStatusErrorNotFound:
127 return kErrorNotFound;
128 case BluetoothLowEnergyEventRouter::kStatusErrorNotNotifying:
129 return kErrorNotNotifying;
130 case BluetoothLowEnergyEventRouter::kStatusErrorOffsetInvalid:
131 return kErrorOffsetInvalid;
132 case BluetoothLowEnergyEventRouter::kStatusErrorPermissionDenied:
133 return kErrorPermissionDenied;
134 case BluetoothLowEnergyEventRouter::kStatusErrorRequestNotSupported:
135 return kErrorRequestNotSupported;
136 case BluetoothLowEnergyEventRouter::kStatusErrorTimeout:
137 return kErrorTimeout;
138 case BluetoothLowEnergyEventRouter::kStatusErrorUnsupportedDevice:
139 return kErrorUnsupportedDevice;
140 case BluetoothLowEnergyEventRouter::kStatusErrorInvalidServiceId:
141 return kErrorInvalidServiceId;
142 case BluetoothLowEnergyEventRouter::kStatusSuccess:
143 NOTREACHED();
144 break;
145 default:
146 return kErrorOperationFailed;
147 }
148 return "";
149 }
150
151 extensions::BluetoothLowEnergyEventRouter* GetEventRouter(
152 BrowserContext* context) {
153 DCHECK_CURRENTLY_ON(BrowserThread::UI);
154 return extensions::BluetoothLowEnergyAPI::Get(context)->event_router();
155 }
156
157 template <typename T>
158 void DoWorkCallback(const base::Callback<T()>& callback) {
159 DCHECK(!callback.is_null());
160 callback.Run();
161 }
162
163 std::unique_ptr<device::BluetoothAdvertisement::ManufacturerData>
164 CreateManufacturerData(
165 std::vector<apibtle::ManufacturerData>* manufacturer_data) {
166 std::unique_ptr<device::BluetoothAdvertisement::ManufacturerData>
167 created_data(new device::BluetoothAdvertisement::ManufacturerData());
168 for (const auto& it : *manufacturer_data) {
169 std::vector<uint8_t> data(it.data.size());
170 std::copy(it.data.begin(), it.data.end(), data.begin());
171 (*created_data)[it.id] = data;
172 }
173 return created_data;
174 }
175
176 std::unique_ptr<device::BluetoothAdvertisement::ServiceData> CreateServiceData(
177 std::vector<apibtle::ServiceData>* service_data) {
178 std::unique_ptr<device::BluetoothAdvertisement::ServiceData> created_data(
179 new device::BluetoothAdvertisement::ServiceData());
180 for (const auto& it : *service_data) {
181 std::vector<uint8_t> data(it.data.size());
182 std::copy(it.data.begin(), it.data.end(), data.begin());
183 (*created_data)[it.uuid] = data;
184 }
185 return created_data;
186 }
187
188 bool HasProperty(
189 const std::vector<apibtle::CharacteristicProperty>& api_properties,
190 apibtle::CharacteristicProperty property) {
191 return find(api_properties.begin(), api_properties.end(), property) !=
192 api_properties.end();
193 }
194
195 bool HasPermission(
196 const std::vector<apibtle::DescriptorPermission>& api_permissions,
197 apibtle::DescriptorPermission permission) {
198 return find(api_permissions.begin(), api_permissions.end(), permission) !=
199 api_permissions.end();
200 }
201
202 device::BluetoothGattCharacteristic::Properties GetBluetoothProperties(
203 const std::vector<apibtle::CharacteristicProperty>& api_properties) {
204 device::BluetoothGattCharacteristic::Properties properties =
205 device::BluetoothGattCharacteristic::PROPERTY_NONE;
206
207 static_assert(
208 apibtle::CHARACTERISTIC_PROPERTY_LAST == 14,
209 "Update required if the number of characteristic properties changes.");
210
211 if (HasProperty(api_properties, apibtle::CHARACTERISTIC_PROPERTY_BROADCAST)) {
212 properties |= device::BluetoothGattCharacteristic::PROPERTY_BROADCAST;
213 }
214
215 if (HasProperty(api_properties, apibtle::CHARACTERISTIC_PROPERTY_READ)) {
216 properties |= device::BluetoothGattCharacteristic::PROPERTY_READ;
217 }
218
219 if (HasProperty(api_properties,
220 apibtle::CHARACTERISTIC_PROPERTY_WRITEWITHOUTRESPONSE)) {
221 properties |=
222 device::BluetoothGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE;
223 }
224
225 if (HasProperty(api_properties, apibtle::CHARACTERISTIC_PROPERTY_WRITE)) {
226 properties |= device::BluetoothGattCharacteristic::PROPERTY_WRITE;
227 }
228
229 if (HasProperty(api_properties, apibtle::CHARACTERISTIC_PROPERTY_NOTIFY)) {
230 properties |= device::BluetoothGattCharacteristic::PROPERTY_NOTIFY;
231 }
232
233 if (HasProperty(api_properties, apibtle::CHARACTERISTIC_PROPERTY_INDICATE)) {
234 properties |= device::BluetoothGattCharacteristic::PROPERTY_INDICATE;
235 }
236
237 if (HasProperty(api_properties,
238 apibtle::CHARACTERISTIC_PROPERTY_AUTHENTICATEDSIGNEDWRITES)) {
239 properties |= device::BluetoothGattCharacteristic::
240 PROPERTY_AUTHENTICATED_SIGNED_WRITES;
241 }
242
243 if (HasProperty(api_properties,
244 apibtle::CHARACTERISTIC_PROPERTY_EXTENDEDPROPERTIES)) {
245 properties |=
246 device::BluetoothGattCharacteristic::PROPERTY_EXTENDED_PROPERTIES;
247 }
248
249 if (HasProperty(api_properties,
250 apibtle::CHARACTERISTIC_PROPERTY_RELIABLEWRITE)) {
251 properties |= device::BluetoothGattCharacteristic::PROPERTY_RELIABLE_WRITE;
252 }
253
254 if (HasProperty(api_properties,
255 apibtle::CHARACTERISTIC_PROPERTY_WRITABLEAUXILIARIES)) {
256 properties |=
257 device::BluetoothGattCharacteristic::PROPERTY_WRITABLE_AUXILIARIES;
258 }
259
260 if (HasProperty(api_properties,
261 apibtle::CHARACTERISTIC_PROPERTY_ENCRYPTREAD)) {
262 properties |= device::BluetoothGattCharacteristic::PROPERTY_READ_ENCRYPTED;
263 }
264
265 if (HasProperty(api_properties,
266 apibtle::CHARACTERISTIC_PROPERTY_ENCRYPTWRITE)) {
267 properties |= device::BluetoothGattCharacteristic::PROPERTY_WRITE_ENCRYPTED;
268 }
269
270 if (HasProperty(api_properties,
271 apibtle::CHARACTERISTIC_PROPERTY_ENCRYPTAUTHENTICATEDREAD)) {
272 properties |= device::BluetoothGattCharacteristic::
273 PROPERTY_READ_ENCRYPTED_AUTHENTICATED;
274 }
275
276 if (HasProperty(api_properties,
277 apibtle::CHARACTERISTIC_PROPERTY_ENCRYPTAUTHENTICATEDWRITE)) {
278 properties |= device::BluetoothGattCharacteristic::
279 PROPERTY_WRITE_ENCRYPTED_AUTHENTICATED;
280 }
281
282 return properties;
283 }
284
285 device::BluetoothGattCharacteristic::Permissions GetBluetoothPermissions(
286 const std::vector<apibtle::DescriptorPermission>& api_permissions) {
287 device::BluetoothGattCharacteristic::Permissions permissions =
288 device::BluetoothGattCharacteristic::PERMISSION_NONE;
289
290 static_assert(
291 apibtle::DESCRIPTOR_PERMISSION_LAST == 6,
292 "Update required if the number of descriptor permissions changes.");
293
294 if (HasPermission(api_permissions, apibtle::DESCRIPTOR_PERMISSION_READ)) {
295 permissions |= device::BluetoothGattCharacteristic::PERMISSION_READ;
296 }
297
298 if (HasPermission(api_permissions, apibtle::DESCRIPTOR_PERMISSION_WRITE)) {
299 permissions |= device::BluetoothGattCharacteristic::PERMISSION_WRITE;
300 }
301
302 if (HasPermission(api_permissions,
303 apibtle::DESCRIPTOR_PERMISSION_ENCRYPTEDREAD)) {
304 permissions |=
305 device::BluetoothGattCharacteristic::PERMISSION_READ_ENCRYPTED;
306 }
307
308 if (HasPermission(api_permissions,
309 apibtle::DESCRIPTOR_PERMISSION_ENCRYPTEDWRITE)) {
310 permissions |=
311 device::BluetoothGattCharacteristic::PERMISSION_WRITE_ENCRYPTED;
312 }
313
314 if (HasPermission(
315 api_permissions,
316 apibtle::DESCRIPTOR_PERMISSION_ENCRYPTEDAUTHENTICATEDREAD)) {
317 permissions |= device::BluetoothGattCharacteristic::
318 PERMISSION_READ_ENCRYPTED_AUTHENTICATED;
319 }
320
321 if (HasPermission(
322 api_permissions,
323 apibtle::DESCRIPTOR_PERMISSION_ENCRYPTEDAUTHENTICATEDWRITE)) {
324 permissions |= device::BluetoothGattCharacteristic::
325 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED;
326 }
327
328 return permissions;
329 }
330
331 bool IsAutoLaunchedKioskApp(const ExtensionId& id) {
332 #if defined(OS_CHROMEOS)
333 chromeos::KioskAppManager::App app_info;
334 return chromeos::KioskAppManager::Get()->GetApp(id, &app_info) &&
335 app_info.was_auto_launched_with_zero_delay;
336 #else
337 return false;
338 #endif
339 }
340
341 bool IsPeripheralFlagEnabled() {
342 return base::CommandLine::ForCurrentProcess()->HasSwitch(
343 switches::kEnableBLEAdvertising);
344 }
345
346 } // namespace
347
348
349 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI> >
350 g_factory = LAZY_INSTANCE_INITIALIZER;
351
352 // static
353 BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI>*
354 BluetoothLowEnergyAPI::GetFactoryInstance() {
355 return g_factory.Pointer();
356 }
357
358 // static
359 BluetoothLowEnergyAPI* BluetoothLowEnergyAPI::Get(BrowserContext* context) {
360 DCHECK_CURRENTLY_ON(BrowserThread::UI);
361 return GetFactoryInstance()->Get(context);
362 }
363
364 BluetoothLowEnergyAPI::BluetoothLowEnergyAPI(BrowserContext* context)
365 : event_router_(new BluetoothLowEnergyEventRouter(context)) {
366 DCHECK_CURRENTLY_ON(BrowserThread::UI);
367 }
368
369 BluetoothLowEnergyAPI::~BluetoothLowEnergyAPI() {
370 }
371
372 void BluetoothLowEnergyAPI::Shutdown() {
373 DCHECK_CURRENTLY_ON(BrowserThread::UI);
374 }
375
376 namespace api {
377
378 BluetoothLowEnergyExtensionFunctionDeprecated::
379 BluetoothLowEnergyExtensionFunctionDeprecated() {}
380
381 BluetoothLowEnergyExtensionFunctionDeprecated::
382 ~BluetoothLowEnergyExtensionFunctionDeprecated() {}
383
384 bool BluetoothLowEnergyExtensionFunctionDeprecated::RunAsync() {
385 DCHECK_CURRENTLY_ON(BrowserThread::UI);
386
387 if (!BluetoothManifestData::CheckLowEnergyPermitted(extension())) {
388 error_ = kErrorPermissionDenied;
389 return false;
390 }
391
392 BluetoothLowEnergyEventRouter* event_router =
393 GetEventRouter(browser_context());
394 if (!event_router->IsBluetoothSupported()) {
395 SetError(kErrorPlatformNotSupported);
396 return false;
397 }
398
399 // It is safe to pass |this| here as ExtensionFunction is refcounted.
400 if (!event_router->InitializeAdapterAndInvokeCallback(base::Bind(
401 &DoWorkCallback<bool>,
402 base::Bind(&BluetoothLowEnergyExtensionFunctionDeprecated::DoWork,
403 this)))) {
404 SetError(kErrorAdapterNotInitialized);
405 return false;
406 }
407
408 return true;
409 }
410
411 BluetoothLowEnergyExtensionFunction::BluetoothLowEnergyExtensionFunction()
412 : event_router_(nullptr) {}
413
414 BluetoothLowEnergyExtensionFunction::~BluetoothLowEnergyExtensionFunction() {}
415
416 ExtensionFunction::ResponseAction BluetoothLowEnergyExtensionFunction::Run() {
417 DCHECK_CURRENTLY_ON(BrowserThread::UI);
418
419 if (!BluetoothManifestData::CheckLowEnergyPermitted(extension()))
420 return RespondNow(Error(kErrorPermissionDenied));
421
422 event_router_ = GetEventRouter(browser_context());
423 if (!event_router_->IsBluetoothSupported())
424 return RespondNow(Error(kErrorPlatformNotSupported));
425
426 // It is safe to pass |this| here as ExtensionFunction is refcounted.
427 if (!event_router_->InitializeAdapterAndInvokeCallback(base::Bind(
428 &DoWorkCallback<void>,
429 base::Bind(&BluetoothLowEnergyExtensionFunction::PreDoWork, this)))) {
430 // DoWork will respond when the adapter gets initialized.
431 return RespondNow(Error(kErrorAdapterNotInitialized));
432 }
433
434 return RespondLater();
435 }
436
437 void BluetoothLowEnergyExtensionFunction::PreDoWork() {
438 // The adapter must be initialized at this point, but return an error instead
439 // of asserting.
440 if (!event_router_->HasAdapter()) {
441 Respond(Error(kErrorAdapterNotInitialized));
442 return;
443 }
444 DoWork();
445 }
446
447 template <typename Params>
448 BLEPeripheralExtensionFunction<Params>::BLEPeripheralExtensionFunction() {}
449
450 template <typename Params>
451 BLEPeripheralExtensionFunction<Params>::~BLEPeripheralExtensionFunction() {}
452
453 template <typename Params>
454 ExtensionFunction::ResponseAction
455 BLEPeripheralExtensionFunction<Params>::Run() {
456 DCHECK_CURRENTLY_ON(BrowserThread::UI);
457
458 // Check permissions in manifest.
459 if (!BluetoothManifestData::CheckPeripheralPermitted(extension()))
460 return RespondNow(Error(kErrorPermissionDenied));
461
462 if (!(IsAutoLaunchedKioskApp(extension()->id()) ||
463 IsPeripheralFlagEnabled())) {
464 return RespondNow(Error(kErrorPermissionDenied));
465 }
466
467 // Causes link error on Windows. API will never be on Windows, so #ifdefing.
468 #if !defined(OS_WIN)
469 params_ = Params::Create(*args_);
470 EXTENSION_FUNCTION_VALIDATE(params_.get() != NULL);
471 #endif
472
473 return BluetoothLowEnergyExtensionFunction::Run();
474 }
475
476 bool BluetoothLowEnergyConnectFunction::DoWork() {
477 DCHECK_CURRENTLY_ON(BrowserThread::UI);
478
479 BluetoothLowEnergyEventRouter* event_router =
480 GetEventRouter(browser_context());
481
482 // The adapter must be initialized at this point, but return an error instead
483 // of asserting.
484 if (!event_router->HasAdapter()) {
485 SetError(kErrorAdapterNotInitialized);
486 SendResponse(false);
487 return false;
488 }
489
490 std::unique_ptr<apibtle::Connect::Params> params(
491 apibtle::Connect::Params::Create(*args_));
492 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
493
494 bool persistent = false; // Not persistent by default.
495 apibtle::ConnectProperties* properties = params->properties.get();
496 if (properties)
497 persistent = properties->persistent;
498
499 event_router->Connect(
500 persistent,
501 extension(),
502 params->device_address,
503 base::Bind(&BluetoothLowEnergyConnectFunction::SuccessCallback, this),
504 base::Bind(&BluetoothLowEnergyConnectFunction::ErrorCallback, this));
505
506 return true;
507 }
508
509 void BluetoothLowEnergyConnectFunction::SuccessCallback() {
510 SendResponse(true);
511 }
512
513 void BluetoothLowEnergyConnectFunction::ErrorCallback(
514 BluetoothLowEnergyEventRouter::Status status) {
515 SetError(StatusToString(status));
516 SendResponse(false);
517 }
518
519 bool BluetoothLowEnergyDisconnectFunction::DoWork() {
520 DCHECK_CURRENTLY_ON(BrowserThread::UI);
521
522 BluetoothLowEnergyEventRouter* event_router =
523 GetEventRouter(browser_context());
524
525 // The adapter must be initialized at this point, but return an error instead
526 // of asserting.
527 if (!event_router->HasAdapter()) {
528 SetError(kErrorAdapterNotInitialized);
529 SendResponse(false);
530 return false;
531 }
532
533 std::unique_ptr<apibtle::Disconnect::Params> params(
534 apibtle::Disconnect::Params::Create(*args_));
535 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
536
537 event_router->Disconnect(
538 extension(),
539 params->device_address,
540 base::Bind(&BluetoothLowEnergyDisconnectFunction::SuccessCallback, this),
541 base::Bind(&BluetoothLowEnergyDisconnectFunction::ErrorCallback, this));
542
543 return true;
544 }
545
546 void BluetoothLowEnergyDisconnectFunction::SuccessCallback() {
547 SendResponse(true);
548 }
549
550 void BluetoothLowEnergyDisconnectFunction::ErrorCallback(
551 BluetoothLowEnergyEventRouter::Status status) {
552 SetError(StatusToString(status));
553 SendResponse(false);
554 }
555
556 bool BluetoothLowEnergyGetServiceFunction::DoWork() {
557 DCHECK_CURRENTLY_ON(BrowserThread::UI);
558
559 BluetoothLowEnergyEventRouter* event_router =
560 GetEventRouter(browser_context());
561
562 // The adapter must be initialized at this point, but return an error instead
563 // of asserting.
564 if (!event_router->HasAdapter()) {
565 SetError(kErrorAdapterNotInitialized);
566 SendResponse(false);
567 return false;
568 }
569
570 std::unique_ptr<apibtle::GetService::Params> params(
571 apibtle::GetService::Params::Create(*args_));
572 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
573
574 apibtle::Service service;
575 BluetoothLowEnergyEventRouter::Status status =
576 event_router->GetService(params->service_id, &service);
577 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
578 SetError(StatusToString(status));
579 SendResponse(false);
580 return false;
581 }
582
583 results_ = apibtle::GetService::Results::Create(service);
584 SendResponse(true);
585
586 return true;
587 }
588
589 bool BluetoothLowEnergyGetServicesFunction::DoWork() {
590 DCHECK_CURRENTLY_ON(BrowserThread::UI);
591
592 BluetoothLowEnergyEventRouter* event_router =
593 GetEventRouter(browser_context());
594
595 // The adapter must be initialized at this point, but return an error instead
596 // of asserting.
597 if (!event_router->HasAdapter()) {
598 SetError(kErrorAdapterNotInitialized);
599 SendResponse(false);
600 return false;
601 }
602
603 std::unique_ptr<apibtle::GetServices::Params> params(
604 apibtle::GetServices::Params::Create(*args_));
605 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
606
607 BluetoothLowEnergyEventRouter::ServiceList service_list;
608 if (!event_router->GetServices(params->device_address, &service_list)) {
609 SetError(kErrorNotFound);
610 SendResponse(false);
611 return false;
612 }
613
614 results_ = apibtle::GetServices::Results::Create(service_list);
615 SendResponse(true);
616
617 return true;
618 }
619
620 bool BluetoothLowEnergyGetCharacteristicFunction::DoWork() {
621 DCHECK_CURRENTLY_ON(BrowserThread::UI);
622
623 BluetoothLowEnergyEventRouter* event_router =
624 GetEventRouter(browser_context());
625
626 // The adapter must be initialized at this point, but return an error instead
627 // of asserting.
628 if (!event_router->HasAdapter()) {
629 SetError(kErrorAdapterNotInitialized);
630 SendResponse(false);
631 return false;
632 }
633
634 std::unique_ptr<apibtle::GetCharacteristic::Params> params(
635 apibtle::GetCharacteristic::Params::Create(*args_));
636 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
637
638 apibtle::Characteristic characteristic;
639 BluetoothLowEnergyEventRouter::Status status =
640 event_router->GetCharacteristic(
641 extension(), params->characteristic_id, &characteristic);
642 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
643 SetError(StatusToString(status));
644 SendResponse(false);
645 return false;
646 }
647
648 // Manually construct the result instead of using
649 // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
650 // enums correctly.
651 SetResult(apibtle::CharacteristicToValue(&characteristic));
652 SendResponse(true);
653
654 return true;
655 }
656
657 bool BluetoothLowEnergyGetCharacteristicsFunction::DoWork() {
658 DCHECK_CURRENTLY_ON(BrowserThread::UI);
659
660 BluetoothLowEnergyEventRouter* event_router =
661 GetEventRouter(browser_context());
662
663 // The adapter must be initialized at this point, but return an error instead
664 // of asserting.
665 if (!event_router->HasAdapter()) {
666 SetError(kErrorAdapterNotInitialized);
667 SendResponse(false);
668 return false;
669 }
670
671 std::unique_ptr<apibtle::GetCharacteristics::Params> params(
672 apibtle::GetCharacteristics::Params::Create(*args_));
673 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
674
675 BluetoothLowEnergyEventRouter::CharacteristicList characteristic_list;
676 BluetoothLowEnergyEventRouter::Status status =
677 event_router->GetCharacteristics(
678 extension(), params->service_id, &characteristic_list);
679 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
680 SetError(StatusToString(status));
681 SendResponse(false);
682 return false;
683 }
684
685 // Manually construct the result instead of using
686 // apibtle::GetCharacteristics::Result::Create as it doesn't convert lists of
687 // enums correctly.
688 std::unique_ptr<base::ListValue> result(new base::ListValue());
689 for (apibtle::Characteristic& characteristic : characteristic_list)
690 result->Append(apibtle::CharacteristicToValue(&characteristic));
691
692 SetResult(std::move(result));
693 SendResponse(true);
694
695 return true;
696 }
697
698 bool BluetoothLowEnergyGetIncludedServicesFunction::DoWork() {
699 DCHECK_CURRENTLY_ON(BrowserThread::UI);
700
701 BluetoothLowEnergyEventRouter* event_router =
702 GetEventRouter(browser_context());
703
704 // The adapter must be initialized at this point, but return an error instead
705 // of asserting.
706 if (!event_router->HasAdapter()) {
707 SetError(kErrorAdapterNotInitialized);
708 SendResponse(false);
709 return false;
710 }
711
712 std::unique_ptr<apibtle::GetIncludedServices::Params> params(
713 apibtle::GetIncludedServices::Params::Create(*args_));
714 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
715
716 BluetoothLowEnergyEventRouter::ServiceList service_list;
717 BluetoothLowEnergyEventRouter::Status status =
718 event_router->GetIncludedServices(params->service_id, &service_list);
719 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
720 SetError(StatusToString(status));
721 SendResponse(false);
722 return false;
723 }
724
725 results_ = apibtle::GetIncludedServices::Results::Create(service_list);
726 SendResponse(true);
727
728 return true;
729 }
730
731 bool BluetoothLowEnergyGetDescriptorFunction::DoWork() {
732 DCHECK_CURRENTLY_ON(BrowserThread::UI);
733
734 BluetoothLowEnergyEventRouter* event_router =
735 GetEventRouter(browser_context());
736
737 // The adapter must be initialized at this point, but return an error instead
738 // of asserting.
739 if (!event_router->HasAdapter()) {
740 SetError(kErrorAdapterNotInitialized);
741 SendResponse(false);
742 return false;
743 }
744
745 std::unique_ptr<apibtle::GetDescriptor::Params> params(
746 apibtle::GetDescriptor::Params::Create(*args_));
747 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
748
749 apibtle::Descriptor descriptor;
750 BluetoothLowEnergyEventRouter::Status status = event_router->GetDescriptor(
751 extension(), params->descriptor_id, &descriptor);
752 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
753 SetError(StatusToString(status));
754 SendResponse(false);
755 return false;
756 }
757
758 // Manually construct the result instead of using
759 // apibtle::GetDescriptor::Result::Create as it doesn't convert lists of enums
760 // correctly.
761 SetResult(apibtle::DescriptorToValue(&descriptor));
762 SendResponse(true);
763
764 return true;
765 }
766
767 bool BluetoothLowEnergyGetDescriptorsFunction::DoWork() {
768 DCHECK_CURRENTLY_ON(BrowserThread::UI);
769
770 BluetoothLowEnergyEventRouter* event_router =
771 GetEventRouter(browser_context());
772
773 // The adapter must be initialized at this point, but return an error instead
774 // of asserting.
775 if (!event_router->HasAdapter()) {
776 SetError(kErrorAdapterNotInitialized);
777 SendResponse(false);
778 return false;
779 }
780
781 std::unique_ptr<apibtle::GetDescriptors::Params> params(
782 apibtle::GetDescriptors::Params::Create(*args_));
783 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
784
785 BluetoothLowEnergyEventRouter::DescriptorList descriptor_list;
786 BluetoothLowEnergyEventRouter::Status status = event_router->GetDescriptors(
787 extension(), params->characteristic_id, &descriptor_list);
788 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
789 SetError(StatusToString(status));
790 SendResponse(false);
791 return false;
792 }
793
794 // Manually construct the result instead of using
795 // apibtle::GetDescriptors::Result::Create as it doesn't convert lists of
796 // enums correctly.
797 std::unique_ptr<base::ListValue> result(new base::ListValue());
798 for (apibtle::Descriptor& descriptor : descriptor_list)
799 result->Append(apibtle::DescriptorToValue(&descriptor));
800
801 SetResult(std::move(result));
802 SendResponse(true);
803
804 return true;
805 }
806
807 bool BluetoothLowEnergyReadCharacteristicValueFunction::DoWork() {
808 DCHECK_CURRENTLY_ON(BrowserThread::UI);
809
810 BluetoothLowEnergyEventRouter* event_router =
811 GetEventRouter(browser_context());
812
813 // The adapter must be initialized at this point, but return an error instead
814 // of asserting.
815 if (!event_router->HasAdapter()) {
816 SetError(kErrorAdapterNotInitialized);
817 SendResponse(false);
818 return false;
819 }
820
821 std::unique_ptr<apibtle::ReadCharacteristicValue::Params> params(
822 apibtle::ReadCharacteristicValue::Params::Create(*args_));
823 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
824
825 instance_id_ = params->characteristic_id;
826 event_router->ReadCharacteristicValue(
827 extension(),
828 instance_id_,
829 base::Bind(
830 &BluetoothLowEnergyReadCharacteristicValueFunction::SuccessCallback,
831 this),
832 base::Bind(
833 &BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback,
834 this));
835
836 return true;
837 }
838
839 void BluetoothLowEnergyReadCharacteristicValueFunction::SuccessCallback() {
840 // Obtain info on the characteristic and see whether or not the characteristic
841 // is still around.
842 apibtle::Characteristic characteristic;
843 BluetoothLowEnergyEventRouter::Status status =
844 GetEventRouter(browser_context())
845 ->GetCharacteristic(extension(), instance_id_, &characteristic);
846 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
847 SetError(StatusToString(status));
848 SendResponse(false);
849 return;
850 }
851
852 // Manually construct the result instead of using
853 // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
854 // enums correctly.
855 SetResult(apibtle::CharacteristicToValue(&characteristic));
856 SendResponse(true);
857 }
858
859 void BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback(
860 BluetoothLowEnergyEventRouter::Status status) {
861 SetError(StatusToString(status));
862 SendResponse(false);
863 }
864
865 bool BluetoothLowEnergyWriteCharacteristicValueFunction::DoWork() {
866 DCHECK_CURRENTLY_ON(BrowserThread::UI);
867
868 BluetoothLowEnergyEventRouter* event_router =
869 GetEventRouter(browser_context());
870
871 // The adapter must be initialized at this point, but return an error instead
872 // of asserting.
873 if (!event_router->HasAdapter()) {
874 SetError(kErrorAdapterNotInitialized);
875 SendResponse(false);
876 return false;
877 }
878
879 std::unique_ptr<apibtle::WriteCharacteristicValue::Params> params(
880 apibtle::WriteCharacteristicValue::Params::Create(*args_));
881 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
882
883 std::vector<uint8_t> value(params->value.begin(), params->value.end());
884 event_router->WriteCharacteristicValue(
885 extension(),
886 params->characteristic_id,
887 value,
888 base::Bind(
889 &BluetoothLowEnergyWriteCharacteristicValueFunction::SuccessCallback,
890 this),
891 base::Bind(
892 &BluetoothLowEnergyWriteCharacteristicValueFunction::ErrorCallback,
893 this));
894
895 return true;
896 }
897
898 void BluetoothLowEnergyWriteCharacteristicValueFunction::SuccessCallback() {
899 results_ = apibtle::WriteCharacteristicValue::Results::Create();
900 SendResponse(true);
901 }
902
903 void BluetoothLowEnergyWriteCharacteristicValueFunction::ErrorCallback(
904 BluetoothLowEnergyEventRouter::Status status) {
905 SetError(StatusToString(status));
906 SendResponse(false);
907 }
908
909 bool BluetoothLowEnergyStartCharacteristicNotificationsFunction::DoWork() {
910 DCHECK_CURRENTLY_ON(BrowserThread::UI);
911
912 BluetoothLowEnergyEventRouter* event_router =
913 GetEventRouter(browser_context());
914
915 // The adapter must be initialized at this point, but return an error instead
916 // of asserting.
917 if (!event_router->HasAdapter()) {
918 SetError(kErrorAdapterNotInitialized);
919 SendResponse(false);
920 return false;
921 }
922
923 std::unique_ptr<apibtle::StartCharacteristicNotifications::Params> params(
924 apibtle::StartCharacteristicNotifications::Params::Create(*args_));
925 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
926
927 bool persistent = false; // Not persistent by default.
928 apibtle::NotificationProperties* properties = params->properties.get();
929 if (properties)
930 persistent = properties->persistent;
931
932 event_router->StartCharacteristicNotifications(
933 persistent,
934 extension(),
935 params->characteristic_id,
936 base::Bind(&BluetoothLowEnergyStartCharacteristicNotificationsFunction::
937 SuccessCallback,
938 this),
939 base::Bind(&BluetoothLowEnergyStartCharacteristicNotificationsFunction::
940 ErrorCallback,
941 this));
942
943 return true;
944 }
945
946 void
947 BluetoothLowEnergyStartCharacteristicNotificationsFunction::SuccessCallback() {
948 SendResponse(true);
949 }
950
951 void BluetoothLowEnergyStartCharacteristicNotificationsFunction::ErrorCallback(
952 BluetoothLowEnergyEventRouter::Status status) {
953 SetError(StatusToString(status));
954 SendResponse(false);
955 }
956
957 bool BluetoothLowEnergyStopCharacteristicNotificationsFunction::DoWork() {
958 DCHECK_CURRENTLY_ON(BrowserThread::UI);
959
960 BluetoothLowEnergyEventRouter* event_router =
961 GetEventRouter(browser_context());
962
963 // The adapter must be initialized at this point, but return an error instead
964 // of asserting.
965 if (!event_router->HasAdapter()) {
966 SetError(kErrorAdapterNotInitialized);
967 SendResponse(false);
968 return false;
969 }
970
971 std::unique_ptr<apibtle::StopCharacteristicNotifications::Params> params(
972 apibtle::StopCharacteristicNotifications::Params::Create(*args_));
973 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
974
975 event_router->StopCharacteristicNotifications(
976 extension(),
977 params->characteristic_id,
978 base::Bind(&BluetoothLowEnergyStopCharacteristicNotificationsFunction::
979 SuccessCallback,
980 this),
981 base::Bind(&BluetoothLowEnergyStopCharacteristicNotificationsFunction::
982 ErrorCallback,
983 this));
984
985 return true;
986 }
987
988 void
989 BluetoothLowEnergyStopCharacteristicNotificationsFunction::SuccessCallback() {
990 SendResponse(true);
991 }
992
993 void BluetoothLowEnergyStopCharacteristicNotificationsFunction::ErrorCallback(
994 BluetoothLowEnergyEventRouter::Status status) {
995 SetError(StatusToString(status));
996 SendResponse(false);
997 }
998
999 bool BluetoothLowEnergyReadDescriptorValueFunction::DoWork() {
1000 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1001
1002 BluetoothLowEnergyEventRouter* event_router =
1003 GetEventRouter(browser_context());
1004
1005 // The adapter must be initialized at this point, but return an error instead
1006 // of asserting.
1007 if (!event_router->HasAdapter()) {
1008 SetError(kErrorAdapterNotInitialized);
1009 SendResponse(false);
1010 return false;
1011 }
1012
1013 std::unique_ptr<apibtle::ReadDescriptorValue::Params> params(
1014 apibtle::ReadDescriptorValue::Params::Create(*args_));
1015 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
1016
1017 instance_id_ = params->descriptor_id;
1018 event_router->ReadDescriptorValue(
1019 extension(),
1020 instance_id_,
1021 base::Bind(
1022 &BluetoothLowEnergyReadDescriptorValueFunction::SuccessCallback,
1023 this),
1024 base::Bind(&BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback,
1025 this));
1026
1027 return true;
1028 }
1029
1030 void BluetoothLowEnergyReadDescriptorValueFunction::SuccessCallback() {
1031 // Obtain info on the descriptor and see whether or not the descriptor is
1032 // still around.
1033 apibtle::Descriptor descriptor;
1034 BluetoothLowEnergyEventRouter::Status status =
1035 GetEventRouter(browser_context())
1036 ->GetDescriptor(extension(), instance_id_, &descriptor);
1037 if (status != BluetoothLowEnergyEventRouter::kStatusSuccess) {
1038 SetError(StatusToString(status));
1039 SendResponse(false);
1040 return;
1041 }
1042
1043 // Manually construct the result instead of using
1044 // apibtle::GetDescriptor::Results::Create as it doesn't convert lists of
1045 // enums correctly.
1046 SetResult(apibtle::DescriptorToValue(&descriptor));
1047 SendResponse(true);
1048 }
1049
1050 void BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback(
1051 BluetoothLowEnergyEventRouter::Status status) {
1052 SetError(StatusToString(status));
1053 SendResponse(false);
1054 }
1055
1056 bool BluetoothLowEnergyWriteDescriptorValueFunction::DoWork() {
1057 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1058
1059 BluetoothLowEnergyEventRouter* event_router =
1060 GetEventRouter(browser_context());
1061
1062 // The adapter must be initialized at this point, but return an error instead
1063 // of asserting.
1064 if (!event_router->HasAdapter()) {
1065 SetError(kErrorAdapterNotInitialized);
1066 SendResponse(false);
1067 return false;
1068 }
1069
1070 std::unique_ptr<apibtle::WriteDescriptorValue::Params> params(
1071 apibtle::WriteDescriptorValue::Params::Create(*args_));
1072 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
1073
1074 std::vector<uint8_t> value(params->value.begin(), params->value.end());
1075 event_router->WriteDescriptorValue(
1076 extension(),
1077 params->descriptor_id,
1078 value,
1079 base::Bind(
1080 &BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback,
1081 this),
1082 base::Bind(&BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback,
1083 this));
1084
1085 return true;
1086 }
1087
1088 void BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback() {
1089 results_ = apibtle::WriteDescriptorValue::Results::Create();
1090 SendResponse(true);
1091 }
1092
1093 void BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback(
1094 BluetoothLowEnergyEventRouter::Status status) {
1095 SetError(StatusToString(status));
1096 SendResponse(false);
1097 }
1098
1099 BluetoothLowEnergyAdvertisementFunction::
1100 BluetoothLowEnergyAdvertisementFunction()
1101 : advertisements_manager_(nullptr) {
1102 }
1103
1104 BluetoothLowEnergyAdvertisementFunction::
1105 ~BluetoothLowEnergyAdvertisementFunction() {
1106 }
1107
1108 int BluetoothLowEnergyAdvertisementFunction::AddAdvertisement(
1109 BluetoothApiAdvertisement* advertisement) {
1110 DCHECK(advertisements_manager_);
1111 return advertisements_manager_->Add(advertisement);
1112 }
1113
1114 BluetoothApiAdvertisement*
1115 BluetoothLowEnergyAdvertisementFunction::GetAdvertisement(
1116 int advertisement_id) {
1117 DCHECK(advertisements_manager_);
1118 return advertisements_manager_->Get(extension_id(), advertisement_id);
1119 }
1120
1121 void BluetoothLowEnergyAdvertisementFunction::RemoveAdvertisement(
1122 int advertisement_id) {
1123 DCHECK(advertisements_manager_);
1124 advertisements_manager_->Remove(extension_id(), advertisement_id);
1125 }
1126
1127 bool BluetoothLowEnergyAdvertisementFunction::RunAsync() {
1128 Initialize();
1129 return BluetoothLowEnergyExtensionFunctionDeprecated::RunAsync();
1130 }
1131
1132 void BluetoothLowEnergyAdvertisementFunction::Initialize() {
1133 advertisements_manager_ =
1134 ApiResourceManager<BluetoothApiAdvertisement>::Get(browser_context());
1135 }
1136
1137 // RegisterAdvertisement:
1138
1139 bool BluetoothLowEnergyRegisterAdvertisementFunction::DoWork() {
1140 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1141
1142 // Check permissions in manifest.
1143 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) {
1144 error_ = kErrorPermissionDenied;
1145 SendResponse(false);
1146 return false;
1147 }
1148
1149 // For this API to be available the app has to be either auto
1150 // launched in Kiosk Mode or the enable-ble-advertisement-in-apps
1151 // should be set.
1152 if (!(IsAutoLaunchedKioskApp(extension()->id()) ||
1153 IsPeripheralFlagEnabled())) {
1154 error_ = kErrorPermissionDenied;
1155 SendResponse(false);
1156 return false;
1157 }
1158
1159 BluetoothLowEnergyEventRouter* event_router =
1160 GetEventRouter(browser_context());
1161
1162 // The adapter must be initialized at this point, but return an error instead
1163 // of asserting.
1164 if (!event_router->HasAdapter()) {
1165 SetError(kErrorAdapterNotInitialized);
1166 SendResponse(false);
1167 return false;
1168 }
1169
1170 std::unique_ptr<apibtle::RegisterAdvertisement::Params> params(
1171 apibtle::RegisterAdvertisement::Params::Create(*args_));
1172 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
1173
1174 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data(
1175 new device::BluetoothAdvertisement::Data(
1176 params->advertisement.type ==
1177 apibtle::AdvertisementType::ADVERTISEMENT_TYPE_BROADCAST
1178 ? device::BluetoothAdvertisement::AdvertisementType::
1179 ADVERTISEMENT_TYPE_BROADCAST
1180 : device::BluetoothAdvertisement::AdvertisementType::
1181 ADVERTISEMENT_TYPE_PERIPHERAL));
1182
1183 advertisement_data->set_service_uuids(
1184 std::move(params->advertisement.service_uuids));
1185 advertisement_data->set_solicit_uuids(
1186 std::move(params->advertisement.solicit_uuids));
1187 if (params->advertisement.manufacturer_data) {
1188 advertisement_data->set_manufacturer_data(
1189 CreateManufacturerData(params->advertisement.manufacturer_data.get()));
1190 }
1191 if (params->advertisement.service_data) {
1192 advertisement_data->set_service_data(
1193 CreateServiceData(params->advertisement.service_data.get()));
1194 }
1195
1196 event_router->adapter()->RegisterAdvertisement(
1197 std::move(advertisement_data),
1198 base::Bind(
1199 &BluetoothLowEnergyRegisterAdvertisementFunction::SuccessCallback,
1200 this),
1201 base::Bind(
1202 &BluetoothLowEnergyRegisterAdvertisementFunction::ErrorCallback,
1203 this));
1204
1205 return true;
1206 }
1207
1208 void BluetoothLowEnergyRegisterAdvertisementFunction::SuccessCallback(
1209 scoped_refptr<device::BluetoothAdvertisement> advertisement) {
1210 results_ = apibtle::RegisterAdvertisement::Results::Create(AddAdvertisement(
1211 new BluetoothApiAdvertisement(extension_id(), advertisement)));
1212 SendResponse(true);
1213 }
1214
1215 void BluetoothLowEnergyRegisterAdvertisementFunction::ErrorCallback(
1216 device::BluetoothAdvertisement::ErrorCode status) {
1217 switch (status) {
1218 case device::BluetoothAdvertisement::ErrorCode::
1219 ERROR_ADVERTISEMENT_ALREADY_EXISTS:
1220 SetError(kStatusAdvertisementAlreadyExists);
1221 break;
1222 case device::BluetoothAdvertisement::ErrorCode::
1223 ERROR_ADVERTISEMENT_INVALID_LENGTH:
1224 SetError(kErrorInvalidAdvertisementLength);
1225 break;
1226 default:
1227 SetError(kErrorOperationFailed);
1228 }
1229 SendResponse(false);
1230 }
1231
1232 // UnregisterAdvertisement:
1233
1234 bool BluetoothLowEnergyUnregisterAdvertisementFunction::DoWork() {
1235 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1236
1237 // Check permission in the manifest.
1238 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) {
1239 error_ = kErrorPermissionDenied;
1240 SendResponse(false);
1241 return false;
1242 }
1243
1244 // For this API to be available the app has to be either auto
1245 // launched in Kiosk Mode or the enable-ble-advertisement-in-apps
1246 // should be set.
1247 if (!(IsAutoLaunchedKioskApp(extension()->id()) ||
1248 IsPeripheralFlagEnabled())) {
1249 error_ = kErrorPermissionDenied;
1250 SendResponse(false);
1251 return false;
1252 }
1253
1254 BluetoothLowEnergyEventRouter* event_router =
1255 GetEventRouter(browser_context());
1256
1257 // If we don't have an initialized adapter, unregistering is a no-op.
1258 if (!event_router->HasAdapter())
1259 return true;
1260
1261 std::unique_ptr<apibtle::UnregisterAdvertisement::Params> params(
1262 apibtle::UnregisterAdvertisement::Params::Create(*args_));
1263 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
1264
1265 BluetoothApiAdvertisement* advertisement =
1266 GetAdvertisement(params->advertisement_id);
1267 if (!advertisement) {
1268 error_ = kStatusAdvertisementDoesNotExist;
1269 SendResponse(false);
1270 return false;
1271 }
1272
1273 advertisement->advertisement()->Unregister(
1274 base::Bind(
1275 &BluetoothLowEnergyUnregisterAdvertisementFunction::SuccessCallback,
1276 this, params->advertisement_id),
1277 base::Bind(
1278 &BluetoothLowEnergyUnregisterAdvertisementFunction::ErrorCallback,
1279 this, params->advertisement_id));
1280
1281 return true;
1282 }
1283
1284 void BluetoothLowEnergyUnregisterAdvertisementFunction::SuccessCallback(
1285 int advertisement_id) {
1286 RemoveAdvertisement(advertisement_id);
1287 SendResponse(true);
1288 }
1289
1290 void BluetoothLowEnergyUnregisterAdvertisementFunction::ErrorCallback(
1291 int advertisement_id,
1292 device::BluetoothAdvertisement::ErrorCode status) {
1293 RemoveAdvertisement(advertisement_id);
1294 switch (status) {
1295 case device::BluetoothAdvertisement::ErrorCode::
1296 ERROR_ADVERTISEMENT_DOES_NOT_EXIST:
1297 SetError(kStatusAdvertisementDoesNotExist);
1298 break;
1299 default:
1300 SetError(kErrorOperationFailed);
1301 }
1302 SendResponse(false);
1303 }
1304
1305 // SetAdvertisingInterval:
1306
1307 template class BLEPeripheralExtensionFunction<
1308 apibtle::SetAdvertisingInterval::Params>;
1309
1310 void BluetoothLowEnergySetAdvertisingIntervalFunction::DoWork() {
1311 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1312 BluetoothLowEnergyEventRouter* event_router =
1313 GetEventRouter(browser_context());
1314 event_router->adapter()->SetAdvertisingInterval(
1315 base::TimeDelta::FromMilliseconds(params_->min_interval),
1316 base::TimeDelta::FromMilliseconds(params_->max_interval),
1317 base::Bind(
1318 &BluetoothLowEnergySetAdvertisingIntervalFunction::SuccessCallback,
1319 this),
1320 base::Bind(
1321 &BluetoothLowEnergySetAdvertisingIntervalFunction::ErrorCallback,
1322 this));
1323 #endif
1324 }
1325
1326 void BluetoothLowEnergySetAdvertisingIntervalFunction::SuccessCallback() {
1327 Respond(NoArguments());
1328 }
1329
1330 void BluetoothLowEnergySetAdvertisingIntervalFunction::ErrorCallback(
1331 device::BluetoothAdvertisement::ErrorCode status) {
1332 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
1333 switch (status) {
1334 case device::BluetoothAdvertisement::ErrorCode::
1335 ERROR_INVALID_ADVERTISEMENT_INTERVAL:
1336 Respond(Error(kStatusInvalidAdvertisingInterval));
1337 break;
1338 default:
1339 Respond(Error(kErrorOperationFailed));
1340 }
1341 #endif
1342 }
1343
1344 // createService:
1345
1346 template class BLEPeripheralExtensionFunction<apibtle::CreateService::Params>;
1347
1348 void BluetoothLowEnergyCreateServiceFunction::DoWork() {
1349 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1350 // Causes link error on Windows. API will never be on Windows, so #ifdefing.
1351 // TODO: Ideally this should be handled by our feature system, so that this
1352 // code doesn't even compile on OSes it isn't being used on, but currently this
1353 // is not possible.
1354 #if !defined(OS_WIN)
1355 base::WeakPtr<device::BluetoothLocalGattService> service =
1356 device::BluetoothLocalGattService::Create(
1357 event_router_->adapter(),
1358 device::BluetoothUUID(params_->service.uuid),
1359 params_->service.is_primary, nullptr, event_router_);
1360
1361 event_router_->AddServiceToApp(extension_id(), service->GetIdentifier());
1362 Respond(ArgumentList(
1363 apibtle::CreateService::Results::Create(service->GetIdentifier())));
1364 #else
1365 Respond(Error(kErrorPlatformNotSupported));
1366 #endif
1367 }
1368
1369 // createCharacteristic:
1370
1371 template class BLEPeripheralExtensionFunction<
1372 apibtle::CreateCharacteristic::Params>;
1373
1374 void BluetoothLowEnergyCreateCharacteristicFunction::DoWork() {
1375 device::BluetoothLocalGattService* service =
1376 event_router_->adapter()->GetGattService(params_->service_id);
1377 if (!service) {
1378 Respond(Error(kErrorInvalidServiceId));
1379 return;
1380 }
1381
1382 base::WeakPtr<device::BluetoothLocalGattCharacteristic> characteristic =
1383 device::BluetoothLocalGattCharacteristic::Create(
1384 device::BluetoothUUID(params_->characteristic.uuid),
1385 GetBluetoothProperties(params_->characteristic.properties),
1386 device::BluetoothGattCharacteristic::Permissions(), service);
1387
1388 // Keep a track of this characteristic so we can look it up later if a
1389 // descriptor lists it as its parent.
1390 event_router_->AddLocalCharacteristic(characteristic->GetIdentifier(),
1391 service->GetIdentifier());
1392
1393 Respond(ArgumentList(apibtle::CreateCharacteristic::Results::Create(
1394 characteristic->GetIdentifier())));
1395 }
1396
1397 // createDescriptor:
1398
1399 template class BLEPeripheralExtensionFunction<
1400 apibtle::CreateDescriptor::Params>;
1401
1402 void BluetoothLowEnergyCreateDescriptorFunction::DoWork() {
1403 device::BluetoothLocalGattCharacteristic* characteristic =
1404 event_router_->GetLocalCharacteristic(params_->characteristic_id);
1405 if (!characteristic) {
1406 Respond(Error(kErrorInvalidCharacteristicId));
1407 return;
1408 }
1409
1410 base::WeakPtr<device::BluetoothLocalGattDescriptor> descriptor =
1411 device::BluetoothLocalGattDescriptor::Create(
1412 device::BluetoothUUID(params_->descriptor.uuid),
1413 GetBluetoothPermissions(params_->descriptor.permissions),
1414 characteristic);
1415
1416 Respond(ArgumentList(
1417 apibtle::CreateDescriptor::Results::Create(descriptor->GetIdentifier())));
1418 }
1419
1420 // registerService:
1421
1422 template class BLEPeripheralExtensionFunction<apibtle::RegisterService::Params>;
1423
1424 void BluetoothLowEnergyRegisterServiceFunction::DoWork() {
1425 event_router_->RegisterGattService(
1426 extension(), params_->service_id,
1427 base::Bind(&BluetoothLowEnergyRegisterServiceFunction::SuccessCallback,
1428 this),
1429 base::Bind(&BluetoothLowEnergyRegisterServiceFunction::ErrorCallback,
1430 this));
1431 }
1432
1433 void BluetoothLowEnergyRegisterServiceFunction::SuccessCallback() {
1434 Respond(NoArguments());
1435 }
1436
1437 void BluetoothLowEnergyRegisterServiceFunction::ErrorCallback(
1438 BluetoothLowEnergyEventRouter::Status status) {
1439 Respond(Error(StatusToString(status)));
1440 }
1441
1442 // unregisterService:
1443
1444 template class BLEPeripheralExtensionFunction<
1445 apibtle::UnregisterService::Params>;
1446
1447 void BluetoothLowEnergyUnregisterServiceFunction::DoWork() {
1448 event_router_->UnregisterGattService(
1449 extension(), params_->service_id,
1450 base::Bind(&BluetoothLowEnergyUnregisterServiceFunction::SuccessCallback,
1451 this),
1452 base::Bind(&BluetoothLowEnergyUnregisterServiceFunction::ErrorCallback,
1453 this));
1454 }
1455
1456 void BluetoothLowEnergyUnregisterServiceFunction::SuccessCallback() {
1457 Respond(NoArguments());
1458 }
1459
1460 void BluetoothLowEnergyUnregisterServiceFunction::ErrorCallback(
1461 BluetoothLowEnergyEventRouter::Status status) {
1462 Respond(Error(StatusToString(status)));
1463 }
1464
1465 // notifyCharacteristicValueChanged:
1466
1467 template class BLEPeripheralExtensionFunction<
1468 apibtle::NotifyCharacteristicValueChanged::Params>;
1469
1470 void BluetoothLowEnergyNotifyCharacteristicValueChangedFunction::DoWork() {
1471 device::BluetoothLocalGattCharacteristic* characteristic =
1472 event_router_->GetLocalCharacteristic(params_->characteristic_id);
1473 if (!characteristic) {
1474 Respond(Error(kErrorInvalidCharacteristicId));
1475 return;
1476 }
1477 std::vector<uint8_t> uint8_vector;
1478 uint8_vector.assign(params_->notification.value.begin(),
1479 params_->notification.value.end());
1480
1481 bool indicate = params_->notification.should_indicate.get()
1482 ? *params_->notification.should_indicate
1483 : false;
1484 device::BluetoothLocalGattCharacteristic::NotificationStatus status =
1485 characteristic->NotifyValueChanged(nullptr, uint8_vector, indicate);
1486
1487 switch (status) {
1488 case device::BluetoothLocalGattCharacteristic::NOTIFICATION_SUCCESS:
1489 Respond(NoArguments());
1490 break;
1491 case device::BluetoothLocalGattCharacteristic::NOTIFY_PROPERTY_NOT_SET:
1492 Respond(Error(kErrorNotifyPropertyNotSet));
1493 break;
1494 case device::BluetoothLocalGattCharacteristic::INDICATE_PROPERTY_NOT_SET:
1495 Respond(Error(kErrorIndicatePropertyNotSet));
1496 break;
1497 case device::BluetoothLocalGattCharacteristic::SERVICE_NOT_REGISTERED:
1498 Respond(Error(kErrorServiceNotRegistered));
1499 break;
1500 default:
1501 LOG(ERROR) << "Unknown notification error!";
1502 Respond(Error(kErrorUnknownNotificationError));
1503 }
1504 }
1505
1506 // removeService:
1507
1508 template class BLEPeripheralExtensionFunction<apibtle::RemoveService::Params>;
1509
1510 void BluetoothLowEnergyRemoveServiceFunction::DoWork() {
1511 device::BluetoothLocalGattService* service =
1512 event_router_->adapter()->GetGattService(params_->service_id);
1513 if (!service) {
1514 Respond(Error(kErrorInvalidServiceId));
1515 return;
1516 }
1517 event_router_->RemoveServiceFromApp(extension_id(), service->GetIdentifier());
1518 service->Delete();
1519 Respond(NoArguments());
1520 }
1521
1522 // sendRequestResponse:
1523
1524 template class BLEPeripheralExtensionFunction<
1525 apibtle::SendRequestResponse::Params>;
1526
1527 void BluetoothLowEnergySendRequestResponseFunction::DoWork() {
1528 std::vector<uint8_t> uint8_vector;
1529 if (params_->response.value) {
1530 uint8_vector.assign(params_->response.value->begin(),
1531 params_->response.value->end());
1532 }
1533 event_router_->HandleRequestResponse(
1534 extension(), params_->response.request_id, params_->response.is_error,
1535 uint8_vector);
1536 Respond(NoArguments());
1537 }
1538
1539 } // namespace api
1540 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698