1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.googlecode.android_scripting.facade.bluetooth; 18 19 import android.app.Service; 20 import android.bluetooth.BluetoothAdapter; 21 import android.bluetooth.le.AdvertiseCallback; 22 import android.bluetooth.le.AdvertiseData; 23 import android.bluetooth.le.AdvertiseData.Builder; 24 import android.bluetooth.le.AdvertiseSettings; 25 import android.bluetooth.le.BluetoothLeAdvertiser; 26 import android.os.Bundle; 27 import android.os.ParcelUuid; 28 29 import com.googlecode.android_scripting.Log; 30 import com.googlecode.android_scripting.MainThread; 31 import com.googlecode.android_scripting.facade.EventFacade; 32 import com.googlecode.android_scripting.facade.FacadeManager; 33 import com.googlecode.android_scripting.jsonrpc.RpcReceiver; 34 import com.googlecode.android_scripting.rpc.Rpc; 35 import com.googlecode.android_scripting.rpc.RpcParameter; 36 37 import java.util.HashMap; 38 import java.util.List; 39 import java.util.concurrent.Callable; 40 41 /** 42 * BluetoothLe Advertise functions. 43 */ 44 45 public class BluetoothLeAdvertiseFacade extends RpcReceiver { 46 47 private final EventFacade mEventFacade; 48 private BluetoothAdapter mBluetoothAdapter; 49 private static int BleAdvertiseCallbackCount; 50 private static int BleAdvertiseSettingsCount; 51 private static int BleAdvertiseDataCount; 52 private final HashMap<Integer, MyAdvertiseCallback> mAdvertiseCallbackList; 53 private final BluetoothLeAdvertiser mAdvertise; 54 private final Service mService; 55 private Builder mAdvertiseDataBuilder; 56 private android.bluetooth.le.AdvertiseSettings.Builder mAdvertiseSettingsBuilder; 57 private final HashMap<Integer, AdvertiseData> mAdvertiseDataList; 58 private final HashMap<Integer, AdvertiseSettings> mAdvertiseSettingsList; 59 BluetoothLeAdvertiseFacade(FacadeManager manager)60 public BluetoothLeAdvertiseFacade(FacadeManager manager) { 61 super(manager); 62 mService = manager.getService(); 63 mBluetoothAdapter = MainThread.run(mService, 64 new Callable<BluetoothAdapter>() { 65 @Override 66 public BluetoothAdapter call() throws Exception { 67 return BluetoothAdapter.getDefaultAdapter(); 68 } 69 }); 70 mEventFacade = manager.getReceiver(EventFacade.class); 71 mAdvertiseCallbackList = new HashMap<Integer, MyAdvertiseCallback>(); 72 mAdvertise = mBluetoothAdapter.getBluetoothLeAdvertiser(); 73 mAdvertiseDataList = new HashMap<Integer, AdvertiseData>(); 74 mAdvertiseSettingsList = new HashMap<Integer, AdvertiseSettings>(); 75 mAdvertiseDataBuilder = new Builder(); 76 mAdvertiseSettingsBuilder = 77 new android.bluetooth.le.AdvertiseSettings.Builder(); 78 } 79 80 /** 81 * Constructs a MyAdvertiseCallback obj and returns its index 82 * 83 * @return MyAdvertiseCallback.index 84 */ 85 @Rpc(description = "Generate a new myAdvertisement Object") bleGenBleAdvertiseCallback()86 public Integer bleGenBleAdvertiseCallback() { 87 BleAdvertiseCallbackCount += 1; 88 int index = BleAdvertiseCallbackCount; 89 MyAdvertiseCallback mCallback = new MyAdvertiseCallback(index); 90 mAdvertiseCallbackList.put(mCallback.index, 91 mCallback); 92 return mCallback.index; 93 } 94 95 /** 96 * Constructs a AdvertiseData obj and returns its index 97 * 98 * @return index 99 */ 100 @Rpc(description = 101 "Constructs a new Builder obj for AdvertiseData and returns its index") bleBuildAdvertiseData()102 public Integer bleBuildAdvertiseData() { 103 BleAdvertiseDataCount += 1; 104 int index = BleAdvertiseDataCount; 105 mAdvertiseDataList.put(index, 106 mAdvertiseDataBuilder.build()); 107 mAdvertiseDataBuilder = new Builder(); 108 return index; 109 } 110 111 /** 112 * Constructs a Advertise Settings obj and returns its index 113 * 114 * @return index 115 */ 116 @Rpc(description = 117 "Constructs a new Builder obj for AdvertiseData and returns its index") bleBuildAdvertiseSettings()118 public Integer bleBuildAdvertiseSettings() { 119 BleAdvertiseSettingsCount += 1; 120 int index = BleAdvertiseSettingsCount; 121 mAdvertiseSettingsList.put(index, 122 mAdvertiseSettingsBuilder.build()); 123 mAdvertiseSettingsBuilder = 124 new android.bluetooth.le.AdvertiseSettings.Builder(); 125 return index; 126 } 127 128 /** 129 * Stops a ble advertisement 130 * 131 * @param index the id of the advertisement to stop advertising on 132 * @throws Exception 133 */ 134 @Rpc(description = "Stops an ongoing ble advertisement") bleStopBleAdvertising( @pcParametername = "index") Integer index)135 public void bleStopBleAdvertising( 136 @RpcParameter(name = "index") 137 Integer index) throws Exception { 138 if (mAdvertiseCallbackList.get(index) != null) { 139 Log.d("bluetooth_le mAdvertise " + index); 140 mAdvertise.stopAdvertising(mAdvertiseCallbackList 141 .get(index)); 142 } else { 143 throw new Exception("Invalid index input:" 144 + Integer.toString(index)); 145 } 146 } 147 148 /** 149 * Starts ble advertising 150 * 151 * @param callbackIndex The advertisementCallback index 152 * @param dataIndex the AdvertiseData index 153 * @param settingsIndex the advertisementsettings index 154 * @throws Exception 155 */ 156 @Rpc(description = "Starts ble advertisement") bleStartBleAdvertising( @pcParametername = "callbackIndex") Integer callbackIndex, @RpcParameter(name = "dataIndex") Integer dataIndex, @RpcParameter(name = "settingsIndex") Integer settingsIndex )157 public void bleStartBleAdvertising( 158 @RpcParameter(name = "callbackIndex") 159 Integer callbackIndex, 160 @RpcParameter(name = "dataIndex") 161 Integer dataIndex, 162 @RpcParameter(name = "settingsIndex") 163 Integer settingsIndex 164 ) throws Exception { 165 AdvertiseData mData = new AdvertiseData.Builder().build(); 166 AdvertiseSettings mSettings = new AdvertiseSettings.Builder().build(); 167 if (mAdvertiseDataList.get(dataIndex) != null) { 168 mData = mAdvertiseDataList.get(dataIndex); 169 } else { 170 throw new Exception("Invalid dataIndex input:" 171 + Integer.toString(dataIndex)); 172 } 173 if (mAdvertiseSettingsList.get(settingsIndex) != null) { 174 mSettings = mAdvertiseSettingsList.get(settingsIndex); 175 } else { 176 throw new Exception("Invalid settingsIndex input:" 177 + Integer.toString(settingsIndex)); 178 } 179 if (mAdvertiseCallbackList.get(callbackIndex) != null) { 180 Log.d("bluetooth_le starting a background advertisement on callback index: " 181 + Integer.toString(callbackIndex)); 182 mAdvertise.startAdvertising( 183 mSettings, mData, mAdvertiseCallbackList.get(callbackIndex)); 184 } else { 185 throw new Exception("Invalid callbackIndex input" 186 + Integer.toString(callbackIndex)); 187 } 188 } 189 190 /** 191 * Starts ble advertising with a scanResponse. ScanResponses are created in 192 * the same way 193 * AdvertiseData is created since they share the same object type. 194 * 195 * @param callbackIndex The advertisementCallback index 196 * @param dataIndex the AdvertiseData index 197 * @param settingsIndex the advertisementsettings index 198 * @param scanResponseIndex the scanResponse index 199 * @throws Exception 200 */ 201 @Rpc(description = "Starts ble advertisement") bleStartBleAdvertisingWithScanResponse( @pcParametername = "callbackIndex") Integer callbackIndex, @RpcParameter(name = "dataIndex") Integer dataIndex, @RpcParameter(name = "settingsIndex") Integer settingsIndex, @RpcParameter(name = "scanResponseIndex") Integer scanResponseIndex )202 public void bleStartBleAdvertisingWithScanResponse( 203 @RpcParameter(name = "callbackIndex") 204 Integer callbackIndex, 205 @RpcParameter(name = "dataIndex") 206 Integer dataIndex, 207 @RpcParameter(name = "settingsIndex") 208 Integer settingsIndex, 209 @RpcParameter(name = "scanResponseIndex") 210 Integer scanResponseIndex 211 ) throws Exception { 212 AdvertiseData mData = new AdvertiseData.Builder().build(); 213 AdvertiseSettings mSettings = new AdvertiseSettings.Builder().build(); 214 AdvertiseData mScanResponse = new AdvertiseData.Builder().build(); 215 216 if (mAdvertiseDataList.get(dataIndex) != null) { 217 mData = mAdvertiseDataList.get(dataIndex); 218 } else { 219 throw new Exception("Invalid dataIndex input:" 220 + Integer.toString(dataIndex)); 221 } 222 if (mAdvertiseSettingsList.get(settingsIndex) != null) { 223 mSettings = mAdvertiseSettingsList.get(settingsIndex); 224 } else { 225 throw new Exception("Invalid settingsIndex input:" 226 + Integer.toString(settingsIndex)); 227 } 228 if (mAdvertiseDataList.get(scanResponseIndex) != null) { 229 mScanResponse = mAdvertiseDataList.get(scanResponseIndex); 230 } else { 231 throw new Exception("Invalid scanResponseIndex input:" 232 + Integer.toString(settingsIndex)); 233 } 234 if (mAdvertiseCallbackList.get(callbackIndex) != null) { 235 Log.d("bluetooth_le starting a background advertise on callback index: " 236 + Integer.toString(callbackIndex)); 237 mAdvertise 238 .startAdvertising(mSettings, mData, mScanResponse, 239 mAdvertiseCallbackList.get(callbackIndex)); 240 } else { 241 throw new Exception("Invalid callbackIndex input" 242 + Integer.toString(callbackIndex)); 243 } 244 } 245 246 /** 247 * Get ble advertisement settings mode 248 * 249 * @param index the advertise settings object to use 250 * @return the mode of the advertise settings object 251 * @throws Exception 252 */ 253 @Rpc(description = "Get ble advertisement settings mode") bleGetAdvertiseSettingsMode( @pcParametername = "index") Integer index)254 public int bleGetAdvertiseSettingsMode( 255 @RpcParameter(name = "index") 256 Integer index) throws Exception { 257 if (mAdvertiseSettingsList.get(index) != null) { 258 AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index); 259 return mSettings.getMode(); 260 } else { 261 throw new Exception("Invalid index input:" 262 + Integer.toString(index)); 263 } 264 } 265 266 /** 267 * Get ble advertisement settings tx power level 268 * 269 * @param index the advertise settings object to use 270 * @return the tx power level of the advertise settings object 271 * @throws Exception 272 */ 273 @Rpc(description = "Get ble advertisement settings tx power level") bleGetAdvertiseSettingsTxPowerLevel( @pcParametername = "index") Integer index)274 public int bleGetAdvertiseSettingsTxPowerLevel( 275 @RpcParameter(name = "index") 276 Integer index) throws Exception { 277 if (mAdvertiseSettingsList.get(index) != null) { 278 AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index); 279 return mSettings.getTxPowerLevel(); 280 } else { 281 throw new Exception("Invalid index input:" + Integer.toString(index)); 282 } 283 } 284 285 /** 286 * Get ble advertisement settings isConnectable value 287 * 288 * @param index the advertise settings object to use 289 * @return the boolean value whether the advertisement will indicate 290 * connectable. 291 * @throws Exception 292 */ 293 @Rpc(description = "Get ble advertisement settings isConnectable value") bleGetAdvertiseSettingsIsConnectable( @pcParametername = "index") Integer index)294 public boolean bleGetAdvertiseSettingsIsConnectable( 295 @RpcParameter(name = "index") 296 Integer index) throws Exception { 297 if (mAdvertiseSettingsList.get(index) != null) { 298 AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index); 299 return mSettings.isConnectable(); 300 } else { 301 throw new Exception("Invalid index input:" + Integer.toString(index)); 302 } 303 } 304 305 /** 306 * Get ble advertisement data include tx power level 307 * 308 * @param index the advertise data object to use 309 * @return True if include tx power level, false otherwise 310 * @throws Exception 311 */ 312 @Rpc(description = "Get ble advertisement data include tx power level") bleGetAdvertiseDataIncludeTxPowerLevel( @pcParametername = "index") Integer index)313 public Boolean bleGetAdvertiseDataIncludeTxPowerLevel( 314 @RpcParameter(name = "index") 315 Integer index) throws Exception { 316 if (mAdvertiseDataList.get(index) != null) { 317 AdvertiseData mData = mAdvertiseDataList.get(index); 318 return mData.getIncludeTxPowerLevel(); 319 } else { 320 throw new Exception("Invalid index input:" 321 + Integer.toString(index)); 322 } 323 } 324 325 /** 326 * Get ble advertisement data manufacturer specific data 327 * 328 * @param index the advertise data object to use 329 * @param manufacturerId the id that corresponds to the manufacturer specific data. 330 * @return the corresponding manufacturer specific data to the manufacturer id. 331 * @throws Exception 332 */ 333 @Rpc(description = "Get ble advertisement data manufacturer specific data") bleGetAdvertiseDataManufacturerSpecificData( @pcParametername = "index") Integer index, @RpcParameter(name = "manufacturerId") Integer manufacturerId)334 public byte[] bleGetAdvertiseDataManufacturerSpecificData( 335 @RpcParameter(name = "index") 336 Integer index, 337 @RpcParameter(name = "manufacturerId") 338 Integer manufacturerId) throws Exception { 339 if (mAdvertiseDataList.get(index) != null) { 340 AdvertiseData mData = mAdvertiseDataList.get(index); 341 if (mData.getManufacturerSpecificData() != null) { 342 return mData.getManufacturerSpecificData().get(manufacturerId); 343 } else { 344 throw new Exception("Invalid manufacturerId input:" 345 + Integer.toString(manufacturerId)); 346 } 347 } else { 348 throw new Exception("Invalid index input:" 349 + Integer.toString(index)); 350 351 } 352 } 353 354 /** 355 * Get ble advertisement data include device name 356 * 357 * @param index the advertise data object to use 358 * @return the advertisement data's include device name 359 * @throws Exception 360 */ 361 @Rpc(description = "Get ble advertisement include device name") bleGetAdvertiseDataIncludeDeviceName( @pcParametername = "index") Integer index)362 public Boolean bleGetAdvertiseDataIncludeDeviceName( 363 @RpcParameter(name = "index") 364 Integer index) throws Exception { 365 if (mAdvertiseDataList.get(index) != null) { 366 AdvertiseData mData = mAdvertiseDataList.get(index); 367 return mData.getIncludeDeviceName(); 368 } else { 369 throw new Exception("Invalid index input:" 370 + Integer.toString(index)); 371 } 372 } 373 374 /** 375 * Get ble advertisement Service Data 376 * 377 * @param index the advertise data object to use 378 * @param serviceUuid the uuid corresponding to the service data. 379 * @return the advertisement data's service data 380 * @throws Exception 381 */ 382 @Rpc(description = "Get ble advertisement Service Data") bleGetAdvertiseDataServiceData( @pcParametername = "index") Integer index, @RpcParameter(name = "serviceUuid") String serviceUuid)383 public byte[] bleGetAdvertiseDataServiceData( 384 @RpcParameter(name = "index") 385 Integer index, 386 @RpcParameter(name = "serviceUuid") 387 String serviceUuid) throws Exception { 388 ParcelUuid uuidKey = ParcelUuid.fromString(serviceUuid); 389 if (mAdvertiseDataList.get(index) != null) { 390 AdvertiseData mData = mAdvertiseDataList.get(index); 391 if (mData.getServiceData().containsKey(uuidKey)) { 392 return mData.getServiceData().get(uuidKey); 393 } else { 394 throw new Exception("Invalid serviceUuid input:" + serviceUuid); 395 } 396 } else { 397 throw new Exception("Invalid index input:" 398 + Integer.toString(index)); 399 } 400 } 401 402 /** 403 * Get ble advertisement Service Uuids 404 * 405 * @param index the advertise data object to use 406 * @return the advertisement data's Service Uuids 407 * @throws Exception 408 */ 409 @Rpc(description = "Get ble advertisement Service Uuids") bleGetAdvertiseDataServiceUuids( @pcParametername = "index") Integer index)410 public List<ParcelUuid> bleGetAdvertiseDataServiceUuids( 411 @RpcParameter(name = "index") 412 Integer index) throws Exception { 413 if (mAdvertiseDataList.get(index) != null) { 414 AdvertiseData mData = mAdvertiseDataList.get(index); 415 return mData.getServiceUuids(); 416 } else { 417 throw new Exception("Invalid index input:" 418 + Integer.toString(index)); 419 } 420 } 421 422 /** 423 * Set ble advertisement data service uuids 424 * 425 * @param uuidList 426 * @throws Exception 427 */ 428 @Rpc(description = "Set ble advertisement data service uuids") bleSetAdvertiseDataSetServiceUuids( @pcParametername = "uuidList") String[] uuidList )429 public void bleSetAdvertiseDataSetServiceUuids( 430 @RpcParameter(name = "uuidList") 431 String[] uuidList 432 ) { 433 for (String uuid : uuidList) { 434 mAdvertiseDataBuilder.addServiceUuid(ParcelUuid.fromString(uuid)); 435 } 436 } 437 438 /** 439 * Set ble advertise data service uuids 440 * 441 * @param serviceDataUuid 442 * @param serviceData 443 * @throws Exception 444 */ 445 @Rpc(description = "Set ble advertise data service uuids") bleAddAdvertiseDataServiceData( @pcParametername = "serviceDataUuid") String serviceDataUuid, @RpcParameter(name = "serviceData") byte[] serviceData )446 public void bleAddAdvertiseDataServiceData( 447 @RpcParameter(name = "serviceDataUuid") 448 String serviceDataUuid, 449 @RpcParameter(name = "serviceData") 450 byte[] serviceData 451 ) { 452 mAdvertiseDataBuilder.addServiceData( 453 ParcelUuid.fromString(serviceDataUuid), 454 serviceData); 455 } 456 457 /** 458 * Set ble advertise data manufacturer id 459 * 460 * @param manufacturerId the manufacturer id to set 461 * @param manufacturerSpecificData the manufacturer specific data to set 462 * @throws Exception 463 */ 464 @Rpc(description = "Set ble advertise data manufacturerId") bleAddAdvertiseDataManufacturerId( @pcParametername = "manufacturerId") Integer manufacturerId, @RpcParameter(name = "manufacturerSpecificData") byte[] manufacturerSpecificData )465 public void bleAddAdvertiseDataManufacturerId( 466 @RpcParameter(name = "manufacturerId") 467 Integer manufacturerId, 468 @RpcParameter(name = "manufacturerSpecificData") 469 byte[] manufacturerSpecificData 470 ) { 471 mAdvertiseDataBuilder.addManufacturerData(manufacturerId, 472 manufacturerSpecificData); 473 } 474 475 /** 476 * Set ble advertise settings advertise mode 477 * 478 * @param advertiseMode 479 * @throws Exception 480 */ 481 @Rpc(description = "Set ble advertise settings advertise mode") bleSetAdvertiseSettingsAdvertiseMode( @pcParametername = "advertiseMode") Integer advertiseMode )482 public void bleSetAdvertiseSettingsAdvertiseMode( 483 @RpcParameter(name = "advertiseMode") 484 Integer advertiseMode 485 ) { 486 mAdvertiseSettingsBuilder.setAdvertiseMode(advertiseMode); 487 } 488 489 /** 490 * Set ble advertise settings tx power level 491 * 492 * @param txPowerLevel the tx power level to set 493 * @throws Exception 494 */ 495 @Rpc(description = "Set ble advertise settings tx power level") bleSetAdvertiseSettingsTxPowerLevel( @pcParametername = "txPowerLevel") Integer txPowerLevel )496 public void bleSetAdvertiseSettingsTxPowerLevel( 497 @RpcParameter(name = "txPowerLevel") 498 Integer txPowerLevel 499 ) { 500 mAdvertiseSettingsBuilder.setTxPowerLevel(txPowerLevel); 501 } 502 503 /** 504 * Set ble advertise settings the isConnectable value 505 * 506 * @param type the isConnectable value 507 * @throws Exception 508 */ 509 @Rpc(description = "Set ble advertise settings isConnectable value") bleSetAdvertiseSettingsIsConnectable( @pcParametername = "value") Boolean value )510 public void bleSetAdvertiseSettingsIsConnectable( 511 @RpcParameter(name = "value") 512 Boolean value 513 ) { 514 mAdvertiseSettingsBuilder.setConnectable(value); 515 } 516 517 /** 518 * Set ble advertisement data include tx power level 519 * 520 * @param includeTxPowerLevel boolean whether to include the tx 521 * power level or not in the advertisement 522 */ 523 @Rpc(description = "Set ble advertisement data include tx power level") bleSetAdvertiseDataIncludeTxPowerLevel( @pcParametername = "includeTxPowerLevel") Boolean includeTxPowerLevel )524 public void bleSetAdvertiseDataIncludeTxPowerLevel( 525 @RpcParameter(name = "includeTxPowerLevel") 526 Boolean includeTxPowerLevel 527 ) { 528 mAdvertiseDataBuilder.setIncludeTxPowerLevel(includeTxPowerLevel); 529 } 530 531 /** 532 * Set ble advertisement settings set timeout 533 * 534 * @param timeoutSeconds Limit advertising to a given amount of time. 535 */ 536 @Rpc(description = "Set ble advertisement data include tx power level") bleSetAdvertiseSettingsTimeout( @pcParametername = "timeoutSeconds") Integer timeoutSeconds )537 public void bleSetAdvertiseSettingsTimeout( 538 @RpcParameter(name = "timeoutSeconds") 539 Integer timeoutSeconds 540 ) { 541 mAdvertiseSettingsBuilder.setTimeout(timeoutSeconds); 542 } 543 544 /** 545 * Set ble advertisement data include device name 546 * 547 * @param includeDeviceName boolean whether to include device name or 548 * not in the advertisement 549 */ 550 @Rpc(description = "Set ble advertisement data include device name") bleSetAdvertiseDataIncludeDeviceName( @pcParametername = "includeDeviceName") Boolean includeDeviceName )551 public void bleSetAdvertiseDataIncludeDeviceName( 552 @RpcParameter(name = "includeDeviceName") 553 Boolean includeDeviceName 554 ) { 555 mAdvertiseDataBuilder.setIncludeDeviceName(includeDeviceName); 556 } 557 558 private class MyAdvertiseCallback extends AdvertiseCallback { 559 public Integer index; 560 private final Bundle mResults; 561 String mEventType; 562 MyAdvertiseCallback(int idx)563 public MyAdvertiseCallback(int idx) { 564 index = idx; 565 mEventType = "BleAdvertise"; 566 mResults = new Bundle(); 567 } 568 569 @Override onStartSuccess(AdvertiseSettings settingsInEffect)570 public void onStartSuccess(AdvertiseSettings settingsInEffect) { 571 Log.d("bluetooth_le_advertisement onSuccess " + mEventType + " " 572 + index); 573 mResults.putString("Type", "onSuccess"); 574 mResults.putParcelable("SettingsInEffect", settingsInEffect); 575 mEventFacade.postEvent(mEventType + index 576 + "onSuccess", mResults.clone()); 577 mResults.clear(); 578 } 579 580 @Override onStartFailure(int errorCode)581 public void onStartFailure(int errorCode) { 582 String errorString = "UNKNOWN_ERROR_CODE"; 583 if (errorCode 584 == AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED) { 585 errorString = "ADVERTISE_FAILED_ALREADY_STARTED"; 586 } else if (errorCode 587 == AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE) { 588 errorString = "ADVERTISE_FAILED_DATA_TOO_LARGE"; 589 } else if (errorCode 590 == AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED) { 591 errorString = "ADVERTISE_FAILED_FEATURE_UNSUPPORTED"; 592 } else if (errorCode 593 == AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR) { 594 errorString = "ADVERTISE_FAILED_INTERNAL_ERROR"; 595 } else if (errorCode 596 == AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) { 597 errorString = "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS"; 598 } 599 Log.d("bluetooth_le_advertisement onFailure " + mEventType + " " 600 + index + " error " + errorString); 601 mResults.putString("Type", "onFailure"); 602 mResults.putInt("ErrorCode", errorCode); 603 mResults.putString("Error", errorString); 604 mEventFacade.postEvent(mEventType + index + "onFailure", 605 mResults.clone()); 606 mResults.clear(); 607 } 608 } 609 610 /** 611 * Clear all advertise settings 612 * 613 * @param None 614 */ 615 @Rpc(description = "Clear all advertise settings") bleAdvertiseClearAll()616 public void bleAdvertiseClearAll() { 617 Log.d("bleAdvertiseClearAll: called"); 618 if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { 619 for (MyAdvertiseCallback mAdvertise : mAdvertiseCallbackList 620 .values()) { 621 if (mAdvertise != null) { 622 try{ 623 mBluetoothAdapter.getBluetoothLeAdvertiser() 624 .stopAdvertising(mAdvertise); 625 } catch (NullPointerException e) { 626 Log.e("Failed to stop ble advertising.", e); 627 } 628 } 629 } 630 } 631 mAdvertiseCallbackList.clear(); 632 mAdvertiseSettingsList.clear(); 633 mAdvertiseDataList.clear(); 634 } 635 636 @Override shutdown()637 public void shutdown() { 638 bleAdvertiseClearAll(); 639 } 640 } 641