• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.android.bluetooth.gatt;
18 
19 import android.bluetooth.le.AdvertiseCallback;
20 import android.bluetooth.le.AdvertiseData;
21 import android.bluetooth.le.AdvertisingSetParameters;
22 import android.bluetooth.le.IAdvertisingSetCallback;
23 import android.bluetooth.le.PeriodicAdvertisingParameters;
24 import android.os.Handler;
25 import android.os.HandlerThread;
26 import android.os.IBinder;
27 import android.os.IInterface;
28 import android.os.Looper;
29 import android.os.RemoteException;
30 import android.util.Log;
31 
32 import com.android.bluetooth.btservice.AdapterService;
33 import com.android.bluetooth.gatt.GattService.AdvertiserMap;
34 import com.android.internal.annotations.VisibleForTesting;
35 
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.Map;
39 
40 /**
41  * Manages Bluetooth LE advertising operations and interacts with bluedroid stack. TODO: add tests.
42  *
43  * @hide
44  */
45 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
46 public class AdvertiseManager {
47     private static final boolean DBG = GattServiceConfig.DBG;
48     private static final String TAG = GattServiceConfig.TAG_PREFIX + "AdvertiseManager";
49 
50     private final GattService mService;
51     private final AdapterService mAdapterService;
52     private final AdvertiserMap mAdvertiserMap;
53     private Handler mHandler;
54     Map<IBinder, AdvertiserInfo> mAdvertisers = Collections.synchronizedMap(new HashMap<>());
55     static int sTempRegistrationId = -1;
56 
57     /**
58      * Constructor of {@link AdvertiseManager}.
59      */
AdvertiseManager(GattService service, AdapterService adapterService, AdvertiserMap advertiserMap)60     AdvertiseManager(GattService service, AdapterService adapterService,
61             AdvertiserMap advertiserMap) {
62         if (DBG) {
63             Log.d(TAG, "advertise manager created");
64         }
65         mService = service;
66         mAdapterService = adapterService;
67         mAdvertiserMap = advertiserMap;
68     }
69 
70     /**
71      * Start a {@link HandlerThread} that handles advertising operations.
72      */
start()73     void start() {
74         initializeNative();
75         HandlerThread thread = new HandlerThread("BluetoothAdvertiseManager");
76         thread.start();
77         mHandler = new Handler(thread.getLooper());
78     }
79 
cleanup()80     void cleanup() {
81         if (DBG) {
82             Log.d(TAG, "cleanup()");
83         }
84         cleanupNative();
85         mAdvertisers.clear();
86         sTempRegistrationId = -1;
87 
88         if (mHandler != null) {
89             // Shut down the thread
90             mHandler.removeCallbacksAndMessages(null);
91             Looper looper = mHandler.getLooper();
92             if (looper != null) {
93                 looper.quit();
94             }
95             mHandler = null;
96         }
97     }
98 
99     class AdvertiserInfo {
100         /* When id is negative, the registration is ongoing. When the registration finishes, id
101          * becomes equal to advertiser_id */
102         public Integer id;
103         public AdvertisingSetDeathRecipient deathRecipient;
104         public IAdvertisingSetCallback callback;
105 
AdvertiserInfo(Integer id, AdvertisingSetDeathRecipient deathRecipient, IAdvertisingSetCallback callback)106         AdvertiserInfo(Integer id, AdvertisingSetDeathRecipient deathRecipient,
107                 IAdvertisingSetCallback callback) {
108             this.id = id;
109             this.deathRecipient = deathRecipient;
110             this.callback = callback;
111         }
112     }
113 
toBinder(IAdvertisingSetCallback e)114     IBinder toBinder(IAdvertisingSetCallback e) {
115         return ((IInterface) e).asBinder();
116     }
117 
118     class AdvertisingSetDeathRecipient implements IBinder.DeathRecipient {
119         public IAdvertisingSetCallback callback;
120 
AdvertisingSetDeathRecipient(IAdvertisingSetCallback callback)121         AdvertisingSetDeathRecipient(IAdvertisingSetCallback callback) {
122             this.callback = callback;
123         }
124 
125         @Override
binderDied()126         public void binderDied() {
127             if (DBG) {
128                 Log.d(TAG, "Binder is dead - unregistering advertising set");
129             }
130             stopAdvertisingSet(callback);
131         }
132     }
133 
findAdvertiser(int advertiserId)134     Map.Entry<IBinder, AdvertiserInfo> findAdvertiser(int advertiserId) {
135         Map.Entry<IBinder, AdvertiserInfo> entry = null;
136         for (Map.Entry<IBinder, AdvertiserInfo> e : mAdvertisers.entrySet()) {
137             if (e.getValue().id == advertiserId) {
138                 entry = e;
139                 break;
140             }
141         }
142         return entry;
143     }
144 
onAdvertisingSetStarted(int regId, int advertiserId, int txPower, int status)145     void onAdvertisingSetStarted(int regId, int advertiserId, int txPower, int status)
146             throws Exception {
147         if (DBG) {
148             Log.d(TAG,
149                     "onAdvertisingSetStarted() - regId=" + regId + ", advertiserId=" + advertiserId
150                             + ", status=" + status);
151         }
152 
153         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(regId);
154 
155         if (entry == null) {
156             Log.i(TAG, "onAdvertisingSetStarted() - no callback found for regId " + regId);
157             // Advertising set was stopped before it was properly registered.
158             stopAdvertisingSetNative(advertiserId);
159             return;
160         }
161 
162         IAdvertisingSetCallback callback = entry.getValue().callback;
163         if (status == 0) {
164             entry.setValue(
165                     new AdvertiserInfo(advertiserId, entry.getValue().deathRecipient, callback));
166 
167             mAdvertiserMap.setAdvertiserIdByRegId(regId, advertiserId);
168         } else {
169             IBinder binder = entry.getKey();
170             binder.unlinkToDeath(entry.getValue().deathRecipient, 0);
171             mAdvertisers.remove(binder);
172 
173             AppAdvertiseStats stats = mAdvertiserMap.getAppAdvertiseStatsById(regId);
174             if (stats != null) {
175                 stats.recordAdvertiseStop();
176             }
177             mAdvertiserMap.removeAppAdvertiseStats(regId);
178         }
179 
180         callback.onAdvertisingSetStarted(advertiserId, txPower, status);
181     }
182 
onAdvertisingEnabled(int advertiserId, boolean enable, int status)183     void onAdvertisingEnabled(int advertiserId, boolean enable, int status) throws Exception {
184         if (DBG) {
185             Log.d(TAG, "onAdvertisingSetEnabled() - advertiserId=" + advertiserId + ", enable="
186                     + enable + ", status=" + status);
187         }
188 
189         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
190         if (entry == null) {
191             Log.i(TAG, "onAdvertisingSetEnable() - no callback found for advertiserId "
192                     + advertiserId);
193             return;
194         }
195 
196         IAdvertisingSetCallback callback = entry.getValue().callback;
197         callback.onAdvertisingEnabled(advertiserId, enable, status);
198 
199         if (!enable && status != 0) {
200             AppAdvertiseStats stats = mAdvertiserMap.getAppAdvertiseStatsById(advertiserId);
201             if (stats != null) {
202                 stats.recordAdvertiseStop();
203             }
204         }
205     }
206 
startAdvertisingSet(AdvertisingSetParameters parameters, AdvertiseData advertiseData, AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData, int duration, int maxExtAdvEvents, IAdvertisingSetCallback callback)207     void startAdvertisingSet(AdvertisingSetParameters parameters, AdvertiseData advertiseData,
208             AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters,
209             AdvertiseData periodicData, int duration, int maxExtAdvEvents,
210             IAdvertisingSetCallback callback) {
211         AdvertisingSetDeathRecipient deathRecipient = new AdvertisingSetDeathRecipient(callback);
212         IBinder binder = toBinder(callback);
213         try {
214             binder.linkToDeath(deathRecipient, 0);
215         } catch (RemoteException e) {
216             throw new IllegalArgumentException("Can't link to advertiser's death");
217         }
218 
219         String deviceName = AdapterService.getAdapterService().getName();
220         try {
221             byte[] advDataBytes = AdvertiseHelper.advertiseDataToBytes(advertiseData, deviceName);
222             byte[] scanResponseBytes =
223                     AdvertiseHelper.advertiseDataToBytes(scanResponse, deviceName);
224             byte[] periodicDataBytes =
225                     AdvertiseHelper.advertiseDataToBytes(periodicData, deviceName);
226 
227             int cbId = --sTempRegistrationId;
228             mAdvertisers.put(binder, new AdvertiserInfo(cbId, deathRecipient, callback));
229 
230             if (DBG) {
231                 Log.d(TAG, "startAdvertisingSet() - reg_id=" + cbId + ", callback: " + binder);
232             }
233 
234             mAdvertiserMap.add(cbId, callback, mService);
235             mAdvertiserMap.recordAdvertiseStart(cbId, parameters, advertiseData,
236                     scanResponse, periodicParameters, periodicData, duration, maxExtAdvEvents);
237 
238             startAdvertisingSetNative(parameters, advDataBytes, scanResponseBytes,
239                     periodicParameters, periodicDataBytes, duration, maxExtAdvEvents, cbId);
240 
241         } catch (IllegalArgumentException e) {
242             try {
243                 binder.unlinkToDeath(deathRecipient, 0);
244                 callback.onAdvertisingSetStarted(0x00, 0x00,
245                         AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
246             } catch (RemoteException exception) {
247                 Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception));
248             }
249         }
250     }
251 
onOwnAddressRead(int advertiserId, int addressType, String address)252     void onOwnAddressRead(int advertiserId, int addressType, String address)
253             throws RemoteException {
254         if (DBG) {
255             Log.d(TAG, "onOwnAddressRead() advertiserId=" + advertiserId);
256         }
257 
258         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
259         if (entry == null) {
260             Log.w(TAG, "onOwnAddressRead() - bad advertiserId " + advertiserId);
261             return;
262         }
263 
264         IAdvertisingSetCallback callback = entry.getValue().callback;
265         callback.onOwnAddressRead(advertiserId, addressType, address);
266     }
267 
getOwnAddress(int advertiserId)268     void getOwnAddress(int advertiserId) {
269         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
270         if (entry == null) {
271             Log.w(TAG, "getOwnAddress() - bad advertiserId " + advertiserId);
272             return;
273         }
274         getOwnAddressNative(advertiserId);
275     }
276 
stopAdvertisingSet(IAdvertisingSetCallback callback)277     void stopAdvertisingSet(IAdvertisingSetCallback callback) {
278         IBinder binder = toBinder(callback);
279         if (DBG) {
280             Log.d(TAG, "stopAdvertisingSet() " + binder);
281         }
282 
283         AdvertiserInfo adv = mAdvertisers.remove(binder);
284         if (adv == null) {
285             Log.e(TAG, "stopAdvertisingSet() - no client found for callback");
286             return;
287         }
288 
289         Integer advertiserId = adv.id;
290         binder.unlinkToDeath(adv.deathRecipient, 0);
291 
292         if (advertiserId < 0) {
293             Log.i(TAG, "stopAdvertisingSet() - advertiser not finished registration yet");
294             // Advertiser will be freed once initiated in onAdvertisingSetStarted()
295             return;
296         }
297 
298         stopAdvertisingSetNative(advertiserId);
299 
300         try {
301             callback.onAdvertisingSetStopped(advertiserId);
302         } catch (RemoteException e) {
303             Log.i(TAG, "error sending onAdvertisingSetStopped callback", e);
304         }
305 
306         mAdvertiserMap.recordAdvertiseStop(advertiserId);
307     }
308 
enableAdvertisingSet(int advertiserId, boolean enable, int duration, int maxExtAdvEvents)309     void enableAdvertisingSet(int advertiserId, boolean enable, int duration, int maxExtAdvEvents) {
310         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
311         if (entry == null) {
312             Log.w(TAG, "enableAdvertisingSet() - bad advertiserId " + advertiserId);
313             return;
314         }
315         enableAdvertisingSetNative(advertiserId, enable, duration, maxExtAdvEvents);
316 
317         mAdvertiserMap.enableAdvertisingSet(advertiserId,
318                 enable, duration, maxExtAdvEvents);
319     }
320 
setAdvertisingData(int advertiserId, AdvertiseData data)321     void setAdvertisingData(int advertiserId, AdvertiseData data) {
322         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
323         if (entry == null) {
324             Log.w(TAG, "setAdvertisingData() - bad advertiserId " + advertiserId);
325             return;
326         }
327         String deviceName = AdapterService.getAdapterService().getName();
328         try {
329             setAdvertisingDataNative(advertiserId,
330                     AdvertiseHelper.advertiseDataToBytes(data, deviceName));
331 
332             mAdvertiserMap.setAdvertisingData(advertiserId, data);
333         } catch (IllegalArgumentException e) {
334             try {
335                 onAdvertisingDataSet(advertiserId,
336                         AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
337             } catch (Exception exception) {
338                 Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception));
339             }
340         }
341     }
342 
setScanResponseData(int advertiserId, AdvertiseData data)343     void setScanResponseData(int advertiserId, AdvertiseData data) {
344         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
345         if (entry == null) {
346             Log.w(TAG, "setScanResponseData() - bad advertiserId " + advertiserId);
347             return;
348         }
349         String deviceName = AdapterService.getAdapterService().getName();
350         try {
351             setScanResponseDataNative(advertiserId,
352                     AdvertiseHelper.advertiseDataToBytes(data, deviceName));
353 
354             mAdvertiserMap.setScanResponseData(advertiserId, data);
355         } catch (IllegalArgumentException e) {
356             try {
357                 onScanResponseDataSet(advertiserId,
358                         AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
359             } catch (Exception exception) {
360                 Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception));
361             }
362         }
363     }
364 
setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters)365     void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) {
366         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
367         if (entry == null) {
368             Log.w(TAG, "setAdvertisingParameters() - bad advertiserId " + advertiserId);
369             return;
370         }
371         setAdvertisingParametersNative(advertiserId, parameters);
372 
373         mAdvertiserMap.setAdvertisingParameters(advertiserId, parameters);
374     }
375 
setPeriodicAdvertisingParameters(int advertiserId, PeriodicAdvertisingParameters parameters)376     void setPeriodicAdvertisingParameters(int advertiserId,
377             PeriodicAdvertisingParameters parameters) {
378         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
379         if (entry == null) {
380             Log.w(TAG, "setPeriodicAdvertisingParameters() - bad advertiserId " + advertiserId);
381             return;
382         }
383         setPeriodicAdvertisingParametersNative(advertiserId, parameters);
384 
385         mAdvertiserMap.setPeriodicAdvertisingParameters(advertiserId, parameters);
386     }
387 
setPeriodicAdvertisingData(int advertiserId, AdvertiseData data)388     void setPeriodicAdvertisingData(int advertiserId, AdvertiseData data) {
389         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
390         if (entry == null) {
391             Log.w(TAG, "setPeriodicAdvertisingData() - bad advertiserId " + advertiserId);
392             return;
393         }
394         String deviceName = AdapterService.getAdapterService().getName();
395         try {
396             setPeriodicAdvertisingDataNative(advertiserId,
397                     AdvertiseHelper.advertiseDataToBytes(data, deviceName));
398 
399             mAdvertiserMap.setPeriodicAdvertisingData(advertiserId, data);
400         } catch (IllegalArgumentException e) {
401             try {
402                 onPeriodicAdvertisingDataSet(advertiserId,
403                         AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
404             } catch (Exception exception) {
405                 Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception));
406             }
407         }
408     }
409 
setPeriodicAdvertisingEnable(int advertiserId, boolean enable)410     void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) {
411         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
412         if (entry == null) {
413             Log.w(TAG, "setPeriodicAdvertisingEnable() - bad advertiserId " + advertiserId);
414             return;
415         }
416         setPeriodicAdvertisingEnableNative(advertiserId, enable);
417     }
418 
onAdvertisingDataSet(int advertiserId, int status)419     void onAdvertisingDataSet(int advertiserId, int status) throws Exception {
420         if (DBG) {
421             Log.d(TAG,
422                     "onAdvertisingDataSet() advertiserId=" + advertiserId + ", status=" + status);
423         }
424 
425         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
426         if (entry == null) {
427             Log.i(TAG, "onAdvertisingDataSet() - bad advertiserId " + advertiserId);
428             return;
429         }
430 
431         IAdvertisingSetCallback callback = entry.getValue().callback;
432         callback.onAdvertisingDataSet(advertiserId, status);
433     }
434 
onScanResponseDataSet(int advertiserId, int status)435     void onScanResponseDataSet(int advertiserId, int status) throws Exception {
436         if (DBG) {
437             Log.d(TAG,
438                     "onScanResponseDataSet() advertiserId=" + advertiserId + ", status=" + status);
439         }
440 
441         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
442         if (entry == null) {
443             Log.i(TAG, "onScanResponseDataSet() - bad advertiserId " + advertiserId);
444             return;
445         }
446 
447         IAdvertisingSetCallback callback = entry.getValue().callback;
448         callback.onScanResponseDataSet(advertiserId, status);
449     }
450 
onAdvertisingParametersUpdated(int advertiserId, int txPower, int status)451     void onAdvertisingParametersUpdated(int advertiserId, int txPower, int status)
452             throws Exception {
453         if (DBG) {
454             Log.d(TAG,
455                     "onAdvertisingParametersUpdated() advertiserId=" + advertiserId + ", txPower="
456                             + txPower + ", status=" + status);
457         }
458 
459         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
460         if (entry == null) {
461             Log.i(TAG, "onAdvertisingParametersUpdated() - bad advertiserId " + advertiserId);
462             return;
463         }
464 
465         IAdvertisingSetCallback callback = entry.getValue().callback;
466         callback.onAdvertisingParametersUpdated(advertiserId, txPower, status);
467     }
468 
onPeriodicAdvertisingParametersUpdated(int advertiserId, int status)469     void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) throws Exception {
470         if (DBG) {
471             Log.d(TAG, "onPeriodicAdvertisingParametersUpdated() advertiserId=" + advertiserId
472                     + ", status=" + status);
473         }
474 
475         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
476         if (entry == null) {
477             Log.i(TAG,
478                     "onPeriodicAdvertisingParametersUpdated() - bad advertiserId " + advertiserId);
479             return;
480         }
481 
482         IAdvertisingSetCallback callback = entry.getValue().callback;
483         callback.onPeriodicAdvertisingParametersUpdated(advertiserId, status);
484     }
485 
onPeriodicAdvertisingDataSet(int advertiserId, int status)486     void onPeriodicAdvertisingDataSet(int advertiserId, int status) throws Exception {
487         if (DBG) {
488             Log.d(TAG, "onPeriodicAdvertisingDataSet() advertiserId=" + advertiserId + ", status="
489                     + status);
490         }
491 
492         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
493         if (entry == null) {
494             Log.i(TAG, "onPeriodicAdvertisingDataSet() - bad advertiserId " + advertiserId);
495             return;
496         }
497 
498         IAdvertisingSetCallback callback = entry.getValue().callback;
499         callback.onPeriodicAdvertisingDataSet(advertiserId, status);
500     }
501 
onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status)502     void onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status)
503             throws Exception {
504         if (DBG) {
505             Log.d(TAG, "onPeriodicAdvertisingEnabled() advertiserId=" + advertiserId + ", status="
506                     + status);
507         }
508 
509         Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiserId);
510         if (entry == null) {
511             Log.i(TAG, "onAdvertisingSetEnable() - bad advertiserId " + advertiserId);
512             return;
513         }
514 
515         IAdvertisingSetCallback callback = entry.getValue().callback;
516         callback.onPeriodicAdvertisingEnabled(advertiserId, enable, status);
517 
518         AppAdvertiseStats stats = mAdvertiserMap.getAppAdvertiseStatsById(advertiserId);
519         if (stats != null) {
520             stats.onPeriodicAdvertiseEnabled(enable);
521         }
522     }
523 
524     static {
classInitNative()525         classInitNative();
526     }
527 
classInitNative()528     private static native void classInitNative();
529 
initializeNative()530     private native void initializeNative();
531 
cleanupNative()532     private native void cleanupNative();
533 
startAdvertisingSetNative(AdvertisingSetParameters parameters, byte[] advertiseData, byte[] scanResponse, PeriodicAdvertisingParameters periodicParameters, byte[] periodicData, int duration, int maxExtAdvEvents, int regId)534     private native void startAdvertisingSetNative(AdvertisingSetParameters parameters,
535             byte[] advertiseData, byte[] scanResponse,
536             PeriodicAdvertisingParameters periodicParameters, byte[] periodicData, int duration,
537             int maxExtAdvEvents, int regId);
538 
getOwnAddressNative(int advertiserId)539     private native void getOwnAddressNative(int advertiserId);
540 
stopAdvertisingSetNative(int advertiserId)541     private native void stopAdvertisingSetNative(int advertiserId);
542 
enableAdvertisingSetNative(int advertiserId, boolean enable, int duration, int maxExtAdvEvents)543     private native void enableAdvertisingSetNative(int advertiserId, boolean enable, int duration,
544             int maxExtAdvEvents);
545 
setAdvertisingDataNative(int advertiserId, byte[] data)546     private native void setAdvertisingDataNative(int advertiserId, byte[] data);
547 
setScanResponseDataNative(int advertiserId, byte[] data)548     private native void setScanResponseDataNative(int advertiserId, byte[] data);
549 
setAdvertisingParametersNative(int advertiserId, AdvertisingSetParameters parameters)550     private native void setAdvertisingParametersNative(int advertiserId,
551             AdvertisingSetParameters parameters);
552 
setPeriodicAdvertisingParametersNative(int advertiserId, PeriodicAdvertisingParameters parameters)553     private native void setPeriodicAdvertisingParametersNative(int advertiserId,
554             PeriodicAdvertisingParameters parameters);
555 
setPeriodicAdvertisingDataNative(int advertiserId, byte[] data)556     private native void setPeriodicAdvertisingDataNative(int advertiserId, byte[] data);
557 
setPeriodicAdvertisingEnableNative(int advertiserId, boolean enable)558     private native void setPeriodicAdvertisingEnableNative(int advertiserId, boolean enable);
559 }
560