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