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 settings own address type
307      *
308      * @param index the advertise settings object to use
309      * @return the own address type of the advertise settings object
310      * @throws Exception
311      */
312     @Rpc(description = "Get ble advertisement settings tx power level")
bleGetAdvertiseSettingsOwnAddressType( @pcParametername = "index") Integer index)313     public int bleGetAdvertiseSettingsOwnAddressType(
314             @RpcParameter(name = "index")
315             Integer index) throws Exception {
316         if (mAdvertiseSettingsList.get(index) != null) {
317             AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index);
318             return mSettings.getOwnAddressType();
319         } else {
320             throw new Exception("Invalid index input:" + Integer.toString(index));
321         }
322     }
323 
324     /**
325      * Get ble advertisement data include tx power level
326      *
327      * @param index the advertise data object to use
328      * @return True if include tx power level, false otherwise
329      * @throws Exception
330      */
331     @Rpc(description = "Get ble advertisement data include tx power level")
bleGetAdvertiseDataIncludeTxPowerLevel( @pcParametername = "index") Integer index)332     public Boolean bleGetAdvertiseDataIncludeTxPowerLevel(
333             @RpcParameter(name = "index")
334             Integer index) throws Exception {
335         if (mAdvertiseDataList.get(index) != null) {
336             AdvertiseData mData = mAdvertiseDataList.get(index);
337             return mData.getIncludeTxPowerLevel();
338         } else {
339             throw new Exception("Invalid index input:"
340                     + Integer.toString(index));
341         }
342     }
343 
344     /**
345      * Get ble advertisement data manufacturer specific data
346      *
347      * @param index the advertise data object to use
348      * @param manufacturerId the id that corresponds to the manufacturer specific data.
349      * @return the corresponding manufacturer specific data to the manufacturer id.
350      * @throws Exception
351      */
352     @Rpc(description = "Get ble advertisement data manufacturer specific data")
bleGetAdvertiseDataManufacturerSpecificData( @pcParametername = "index") Integer index, @RpcParameter(name = "manufacturerId") Integer manufacturerId)353     public byte[] bleGetAdvertiseDataManufacturerSpecificData(
354             @RpcParameter(name = "index")
355             Integer index,
356             @RpcParameter(name = "manufacturerId")
357             Integer manufacturerId) throws Exception {
358         if (mAdvertiseDataList.get(index) != null) {
359             AdvertiseData mData = mAdvertiseDataList.get(index);
360             if (mData.getManufacturerSpecificData() != null) {
361                 return mData.getManufacturerSpecificData().get(manufacturerId);
362             } else {
363                 throw new Exception("Invalid manufacturerId input:"
364                         + Integer.toString(manufacturerId));
365             }
366         } else {
367             throw new Exception("Invalid index input:"
368                     + Integer.toString(index));
369 
370         }
371     }
372 
373     /**
374      * Get ble advertisement data include device name
375      *
376      * @param index the advertise data object to use
377      * @return the advertisement data's include device name
378      * @throws Exception
379      */
380     @Rpc(description = "Get ble advertisement include device name")
bleGetAdvertiseDataIncludeDeviceName( @pcParametername = "index") Integer index)381     public Boolean bleGetAdvertiseDataIncludeDeviceName(
382             @RpcParameter(name = "index")
383             Integer index) throws Exception {
384         if (mAdvertiseDataList.get(index) != null) {
385             AdvertiseData mData = mAdvertiseDataList.get(index);
386             return mData.getIncludeDeviceName();
387         } else {
388             throw new Exception("Invalid index input:"
389                     + Integer.toString(index));
390         }
391     }
392 
393     /**
394      * Get ble advertisement Service Data
395      *
396      * @param index the advertise data object to use
397      * @param serviceUuid the uuid corresponding to the service data.
398      * @return the advertisement data's service data
399      * @throws Exception
400      */
401     @Rpc(description = "Get ble advertisement Service Data")
bleGetAdvertiseDataServiceData( @pcParametername = "index") Integer index, @RpcParameter(name = "serviceUuid") String serviceUuid)402     public byte[] bleGetAdvertiseDataServiceData(
403             @RpcParameter(name = "index")
404             Integer index,
405             @RpcParameter(name = "serviceUuid")
406             String serviceUuid) throws Exception {
407         ParcelUuid uuidKey = ParcelUuid.fromString(serviceUuid);
408         if (mAdvertiseDataList.get(index) != null) {
409             AdvertiseData mData = mAdvertiseDataList.get(index);
410             if (mData.getServiceData().containsKey(uuidKey)) {
411                 return mData.getServiceData().get(uuidKey);
412             } else {
413                 throw new Exception("Invalid serviceUuid input:" + serviceUuid);
414             }
415         } else {
416             throw new Exception("Invalid index input:"
417                     + Integer.toString(index));
418         }
419     }
420 
421     /**
422      * Get ble advertisement Service Uuids
423      *
424      * @param index the advertise data object to use
425      * @return the advertisement data's Service Uuids
426      * @throws Exception
427      */
428     @Rpc(description = "Get ble advertisement Service Uuids")
bleGetAdvertiseDataServiceUuids( @pcParametername = "index") Integer index)429     public List<ParcelUuid> bleGetAdvertiseDataServiceUuids(
430             @RpcParameter(name = "index")
431             Integer index) throws Exception {
432         if (mAdvertiseDataList.get(index) != null) {
433             AdvertiseData mData = mAdvertiseDataList.get(index);
434             return mData.getServiceUuids();
435         } else {
436             throw new Exception("Invalid index input:"
437                     + Integer.toString(index));
438         }
439     }
440 
441     /**
442      * Set ble advertisement data service uuids
443      *
444      * @param uuidList
445      * @throws Exception
446      */
447     @Rpc(description = "Set ble advertisement data service uuids")
bleSetAdvertiseDataSetServiceUuids( @pcParametername = "uuidList") String[] uuidList )448     public void bleSetAdvertiseDataSetServiceUuids(
449             @RpcParameter(name = "uuidList")
450             String[] uuidList
451             ) {
452         for (String uuid : uuidList) {
453             mAdvertiseDataBuilder.addServiceUuid(ParcelUuid.fromString(uuid));
454         }
455     }
456 
457     /**
458      * Set ble advertise data service uuids
459      *
460      * @param serviceDataUuid
461      * @param serviceData
462      * @throws Exception
463      */
464     @Rpc(description = "Set ble advertise data service uuids")
bleAddAdvertiseDataServiceData( @pcParametername = "serviceDataUuid") String serviceDataUuid, @RpcParameter(name = "serviceData") byte[] serviceData )465     public void bleAddAdvertiseDataServiceData(
466             @RpcParameter(name = "serviceDataUuid")
467             String serviceDataUuid,
468             @RpcParameter(name = "serviceData")
469             byte[] serviceData
470             ) {
471         mAdvertiseDataBuilder.addServiceData(
472                 ParcelUuid.fromString(serviceDataUuid),
473                 serviceData);
474     }
475 
476     /**
477      * Set ble advertise data manufacturer id
478      *
479      * @param manufacturerId the manufacturer id to set
480      * @param manufacturerSpecificData the manufacturer specific data to set
481      * @throws Exception
482      */
483     @Rpc(description = "Set ble advertise data manufacturerId")
bleAddAdvertiseDataManufacturerId( @pcParametername = "manufacturerId") Integer manufacturerId, @RpcParameter(name = "manufacturerSpecificData") byte[] manufacturerSpecificData )484     public void bleAddAdvertiseDataManufacturerId(
485             @RpcParameter(name = "manufacturerId")
486             Integer manufacturerId,
487             @RpcParameter(name = "manufacturerSpecificData")
488             byte[] manufacturerSpecificData
489             ) {
490         mAdvertiseDataBuilder.addManufacturerData(manufacturerId,
491                 manufacturerSpecificData);
492     }
493 
494     /**
495      * Set ble advertise settings advertise mode
496      *
497      * @param advertiseMode
498      * @throws Exception
499      */
500     @Rpc(description = "Set ble advertise settings advertise mode")
bleSetAdvertiseSettingsAdvertiseMode( @pcParametername = "advertiseMode") Integer advertiseMode )501     public void bleSetAdvertiseSettingsAdvertiseMode(
502             @RpcParameter(name = "advertiseMode")
503             Integer advertiseMode
504             ) {
505         mAdvertiseSettingsBuilder.setAdvertiseMode(advertiseMode);
506     }
507 
508     /**
509      * Set ble advertise settings tx power level
510      *
511      * @param txPowerLevel the tx power level to set
512      * @throws Exception
513      */
514     @Rpc(description = "Set ble advertise settings tx power level")
bleSetAdvertiseSettingsTxPowerLevel( @pcParametername = "txPowerLevel") Integer txPowerLevel )515     public void bleSetAdvertiseSettingsTxPowerLevel(
516             @RpcParameter(name = "txPowerLevel")
517             Integer txPowerLevel
518             ) {
519         mAdvertiseSettingsBuilder.setTxPowerLevel(txPowerLevel);
520     }
521 
522     /**
523      * Set ble advertise settings the isConnectable value
524      *
525      * @param type the isConnectable value
526      * @throws Exception
527      */
528     @Rpc(description = "Set ble advertise settings isConnectable value")
bleSetAdvertiseSettingsIsConnectable( @pcParametername = "value") Boolean value )529     public void bleSetAdvertiseSettingsIsConnectable(
530             @RpcParameter(name = "value")
531             Boolean value
532             ) {
533         mAdvertiseSettingsBuilder.setConnectable(value);
534     }
535 
536     /**
537      * Set ble advertise settings own address type
538      *
539      * @param ownAddressType the own address type to set
540      * @throws Exception
541      */
542     @Rpc(description = "Set ble advertise settings tx power level")
bleSetAdvertiseSettingsOwnAddressType( @pcParametername = "ownAddressType") Integer ownAddressType)543     public void bleSetAdvertiseSettingsOwnAddressType(
544             @RpcParameter(name = "ownAddressType")
545             Integer ownAddressType) {
546         mAdvertiseSettingsBuilder.setOwnAddressType(ownAddressType);
547     }
548 
549     /**
550      * Set ble advertisement data include tx power level
551      *
552      * @param includeTxPowerLevel boolean whether to include the tx
553      *         power level or not in the advertisement
554      */
555     @Rpc(description = "Set ble advertisement data include tx power level")
bleSetAdvertiseDataIncludeTxPowerLevel( @pcParametername = "includeTxPowerLevel") Boolean includeTxPowerLevel )556     public void bleSetAdvertiseDataIncludeTxPowerLevel(
557             @RpcParameter(name = "includeTxPowerLevel")
558             Boolean includeTxPowerLevel
559             ) {
560         mAdvertiseDataBuilder.setIncludeTxPowerLevel(includeTxPowerLevel);
561     }
562 
563     /**
564      * Set ble advertisement settings set timeout
565      *
566      * @param timeoutSeconds Limit advertising to a given amount of time.
567      */
568     @Rpc(description = "Set ble advertisement data include tx power level")
bleSetAdvertiseSettingsTimeout( @pcParametername = "timeoutSeconds") Integer timeoutSeconds )569     public void bleSetAdvertiseSettingsTimeout(
570             @RpcParameter(name = "timeoutSeconds")
571             Integer timeoutSeconds
572             ) {
573         mAdvertiseSettingsBuilder.setTimeout(timeoutSeconds);
574     }
575 
576     /**
577      * Set ble advertisement data include device name
578      *
579      * @param includeDeviceName boolean whether to include device name or
580      *        not in the advertisement
581      */
582     @Rpc(description = "Set ble advertisement data include device name")
bleSetAdvertiseDataIncludeDeviceName( @pcParametername = "includeDeviceName") Boolean includeDeviceName )583     public void bleSetAdvertiseDataIncludeDeviceName(
584             @RpcParameter(name = "includeDeviceName")
585             Boolean includeDeviceName
586             ) {
587         mAdvertiseDataBuilder.setIncludeDeviceName(includeDeviceName);
588     }
589 
590     private class MyAdvertiseCallback extends AdvertiseCallback {
591         public Integer index;
592         private final Bundle mResults;
593         String mEventType;
594 
MyAdvertiseCallback(int idx)595         public MyAdvertiseCallback(int idx) {
596             index = idx;
597             mEventType = "BleAdvertise";
598             mResults = new Bundle();
599         }
600 
601         @Override
onStartSuccess(AdvertiseSettings settingsInEffect)602         public void onStartSuccess(AdvertiseSettings settingsInEffect) {
603             Log.d("bluetooth_le_advertisement onSuccess " + mEventType + " "
604                     + index);
605             mResults.putString("Type", "onSuccess");
606             mResults.putParcelable("SettingsInEffect", settingsInEffect);
607             mEventFacade.postEvent(mEventType + index
608                     + "onSuccess", mResults.clone());
609             mResults.clear();
610         }
611 
612         @Override
onStartFailure(int errorCode)613         public void onStartFailure(int errorCode) {
614             String errorString = "UNKNOWN_ERROR_CODE";
615             if (errorCode
616                     == AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED) {
617                 errorString = "ADVERTISE_FAILED_ALREADY_STARTED";
618             } else if (errorCode
619                     == AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE) {
620                 errorString = "ADVERTISE_FAILED_DATA_TOO_LARGE";
621             } else if (errorCode
622                     == AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED) {
623                 errorString = "ADVERTISE_FAILED_FEATURE_UNSUPPORTED";
624             } else if (errorCode
625                     == AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR) {
626                 errorString = "ADVERTISE_FAILED_INTERNAL_ERROR";
627             } else if (errorCode
628                     == AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) {
629                 errorString = "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS";
630             }
631             Log.d("bluetooth_le_advertisement onFailure " + mEventType + " "
632                     + index + " error " + errorString);
633             mResults.putString("Type", "onFailure");
634             mResults.putInt("ErrorCode", errorCode);
635             mResults.putString("Error", errorString);
636             mEventFacade.postEvent(mEventType + index + "onFailure",
637                     mResults.clone());
638             mResults.clear();
639         }
640     }
641 
642     /**
643      * Clear all advertise settings
644      *
645      * @param None
646      */
647     @Rpc(description = "Clear all advertise settings")
bleAdvertiseClearAll()648     public void bleAdvertiseClearAll() {
649         Log.d("bleAdvertiseClearAll: called");
650         if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
651             for (MyAdvertiseCallback mAdvertise : mAdvertiseCallbackList
652                 .values()) {
653                 if (mAdvertise != null) {
654                     try{
655                         mBluetoothAdapter.getBluetoothLeAdvertiser()
656                             .stopAdvertising(mAdvertise);
657                     } catch (NullPointerException e) {
658                         Log.e("Failed to stop ble advertising.", e);
659                     }
660                 }
661             }
662         }
663         mAdvertiseCallbackList.clear();
664         mAdvertiseSettingsList.clear();
665         mAdvertiseDataList.clear();
666     }
667 
668     @Override
shutdown()669     public void shutdown() {
670         bleAdvertiseClearAll();
671     }
672 }
673