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