AdvertiseManager.java revision 8cc4343c3b71c7a4d57c0b8c669b0a6188185f6b
127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/* 2917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski * Copyright (C) 2017 The Android Open Source Project 327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * 427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Licensed under the Apache License, Version 2.0 (the "License"); 527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * you may not use this file except in compliance with the License. 627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * You may obtain a copy of the License at 727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * 827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * http://www.apache.org/licenses/LICENSE-2.0 927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * 1027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Unless required by applicable law or agreed to in writing, software 1127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * distributed under the License is distributed on an "AS IS" BASIS, 1227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * See the License for the specific language governing permissions and 1427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * limitations under the License. 1527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */ 1627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 1727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangpackage com.android.bluetooth.gatt; 1827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 19917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport android.bluetooth.le.AdvertiseData; 20917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport android.bluetooth.le.AdvertisingSetParameters; 21917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport android.bluetooth.le.IAdvertisingSetCallback; 22917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport android.bluetooth.le.PeriodicAdvertisingParameters; 2327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport android.os.Handler; 2427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport android.os.HandlerThread; 25917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport android.os.IBinder; 26917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport android.os.IInterface; 2727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport android.os.Looper; 2827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport android.os.Message; 2927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport android.os.RemoteException; 3027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport android.util.Log; 3127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport com.android.bluetooth.Utils; 3227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport com.android.bluetooth.btservice.AdapterService; 33917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport java.util.Collections; 34917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport java.util.HashMap; 3527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport java.util.HashSet; 36917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowskiimport java.util.Map; 3727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport java.util.Set; 3827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport java.util.UUID; 3927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport java.util.concurrent.CountDownLatch; 4027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangimport java.util.concurrent.TimeUnit; 4127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 4227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang/** 43a1664d61821a59145f8095a75373403a0c54244eWei Wang * Manages Bluetooth LE advertising operations and interacts with bluedroid stack. TODO: add tests. 4427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * 4527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * @hide 4627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */ 4727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wangclass AdvertiseManager { 4827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang private static final boolean DBG = GattServiceConfig.DBG; 4927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang private static final String TAG = GattServiceConfig.TAG_PREFIX + "AdvertiseManager"; 5027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 5127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang private final GattService mService; 52a1664d61821a59145f8095a75373403a0c54244eWei Wang private final AdapterService mAdapterService; 53917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski private Handler mHandler; 54917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Map<IBinder, AdvertiserInfo> mAdvertisers = Collections.synchronizedMap(new HashMap<>()); 55917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski static int sTempRegistrationId = -1; 5627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 5727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang /** 5827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Constructor of {@link AdvertiseManager}. 5927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */ 60a1664d61821a59145f8095a75373403a0c54244eWei Wang AdvertiseManager(GattService service, AdapterService adapterService) { 6127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang logd("advertise manager created"); 62a1664d61821a59145f8095a75373403a0c54244eWei Wang mService = service; 63a1664d61821a59145f8095a75373403a0c54244eWei Wang mAdapterService = adapterService; 6427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 6527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 6627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang /** 6727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang * Start a {@link HandlerThread} that handles advertising operations. 6827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang */ 6927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang void start() { 70917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski initializeNative(); 7127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang HandlerThread thread = new HandlerThread("BluetoothAdvertiseManager"); 7227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang thread.start(); 73917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski mHandler = new Handler(thread.getLooper()); 7427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 7527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 7627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang void cleanup() { 77917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski logd("cleanup()"); 78917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski cleanupNative(); 79917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski mAdvertisers.clear(); 80917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski sTempRegistrationId = -1; 81ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra 82ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra if (mHandler != null) { 83ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra // Shut down the thread 84ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra mHandler.removeCallbacksAndMessages(null); 85ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra Looper looper = mHandler.getLooper(); 86ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra if (looper != null) { 87ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra looper.quit(); 88ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra } 89ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra mHandler = null; 90ba73d4b554ff0016d6b11a6102c2a75b5b0c149dMatadeen Mishra } 9127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 9227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 93917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski class AdvertiserInfo { 94917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski /* When id is negative, the registration is ongoing. When the registration finishes, id 95917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski * becomes equal to advertiser_id */ 96917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski public Integer id; 97917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski public AdvertisingSetDeathRecipient deathRecipient; 98917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski public IAdvertisingSetCallback callback; 99917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski 100917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski AdvertiserInfo(Integer id, AdvertisingSetDeathRecipient deathRecipient, 101917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IAdvertisingSetCallback callback) { 102917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski this.id = id; 103917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski this.deathRecipient = deathRecipient; 104917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski this.callback = callback; 1057bdbdb9c5c81e08957c442f91d70fb34d8b34ddeJakub Pawlowski } 10664bf8e33481bb787aec895c603748eedb634a93bJakub Pawlowski } 10764bf8e33481bb787aec895c603748eedb634a93bJakub Pawlowski 108917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IBinder toBinder(IAdvertisingSetCallback e) { 109917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski return ((IInterface) e).asBinder(); 11027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 11127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 112917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski class AdvertisingSetDeathRecipient implements IBinder.DeathRecipient { 113917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IAdvertisingSetCallback callback; 114917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski 115917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski public AdvertisingSetDeathRecipient(IAdvertisingSetCallback callback) { 116917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski this.callback = callback; 11727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 11827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 119917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski @Override 120917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski public void binderDied() { 121917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (DBG) Log.d(TAG, "Binder is dead - unregistering advertising set"); 122917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski stopAdvertisingSet(callback); 12327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 12427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 12527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 126917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> findAdvertiser(int advertiser_id) { 127917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = null; 128917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski for (Map.Entry<IBinder, AdvertiserInfo> e : mAdvertisers.entrySet()) { 129917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (e.getValue().id == advertiser_id) { 130917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski entry = e; 131917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski break; 13218999c2cfd477050de0ca88c3a73458235d82656Wei Wang } 13318999c2cfd477050de0ca88c3a73458235d82656Wei Wang } 134917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski return entry; 13518999c2cfd477050de0ca88c3a73458235d82656Wei Wang } 13618999c2cfd477050de0ca88c3a73458235d82656Wei Wang 1378cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onAdvertisingSetStarted(int reg_id, int advertiser_id, int tx_power, int status) 1388cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski throws Exception { 139917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (DBG) 140917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Log.d(TAG, "onAdvertisingSetStarted() - reg_id=" + reg_id + ", advertiser_id=" 141917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski + advertiser_id + ", status=" + status); 142917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski 143917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(reg_id); 14427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 145917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (entry == null) { 146917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Log.i(TAG, "onAdvertisingSetStarted() - no callback found for reg_id " + reg_id); 147917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski // Advertising set was stopped before it was properly registered. 148917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski stopAdvertisingSetNative(advertiser_id); 149917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski return; 15027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 15127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 152917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 153917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (status == 0) { 154917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski entry.setValue( 155917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski new AdvertiserInfo(advertiser_id, entry.getValue().deathRecipient, callback)); 156917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski } else { 157917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IBinder binder = entry.getKey(); 158917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski binder.unlinkToDeath(entry.getValue().deathRecipient, 0); 159917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski mAdvertisers.remove(binder); 16027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 16127bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 1628cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski callback.onAdvertisingSetStarted(advertiser_id, tx_power, status); 163917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski } 16427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 1658cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onAdvertisingEnabled(int advertiser_id, boolean enable, int status) throws Exception { 166917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski logd("onAdvertisingSetEnabled() - advertiser_id=" + advertiser_id + ", enable=" + enable 167917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski + ", status=" + status); 16827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 169917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id); 170917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (entry == null) { 171917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Log.i(TAG, "onAdvertisingSetEnable() - no callback found for advertiser_id " 172917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski + advertiser_id); 173917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski return; 17427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 175917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski 176917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 177917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski callback.onAdvertisingEnabled(advertiser_id, enable, status); 17827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 17927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 180917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski void startAdvertisingSet(AdvertisingSetParameters parameters, AdvertiseData advertiseData, 181917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters, 182b3246f3a27d269b4c0ef19cb2c8772d039eb26ccJakub Pawlowski AdvertiseData periodicData, int timeout, IAdvertisingSetCallback callback) { 183917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski AdvertisingSetDeathRecipient deathRecipient = new AdvertisingSetDeathRecipient(callback); 184917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IBinder binder = toBinder(callback); 185917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski try { 186917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski binder.linkToDeath(deathRecipient, 0); 187917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski } catch (RemoteException e) { 188917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski throw new IllegalArgumentException("Can't link to advertiser's death"); 18927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 19027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 191917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski String deviceName = AdapterService.getAdapterService().getName(); 192917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski byte[] adv_data = AdvertiseHelper.advertiseDataToBytes(advertiseData, deviceName); 193917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski byte[] scan_response = AdvertiseHelper.advertiseDataToBytes(scanResponse, deviceName); 194917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski byte[] periodic_data = AdvertiseHelper.advertiseDataToBytes(periodicData, deviceName); 195917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski 196917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski int cb_id = --sTempRegistrationId; 197917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski mAdvertisers.put(binder, new AdvertiserInfo(cb_id, deathRecipient, callback)); 198917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski 199917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski logd("startAdvertisingSet() - reg_id=" + cb_id + ", callback: " + binder); 200b3246f3a27d269b4c0ef19cb2c8772d039eb26ccJakub Pawlowski startAdvertisingSetNative(parameters, adv_data, scan_response, periodicParameters, 201b3246f3a27d269b4c0ef19cb2c8772d039eb26ccJakub Pawlowski periodic_data, timeout, cb_id); 202917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski } 203917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski 204917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski void stopAdvertisingSet(IAdvertisingSetCallback callback) { 205917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski IBinder binder = toBinder(callback); 206917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (DBG) Log.d(TAG, "stopAdvertisingSet() " + binder); 20727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 208917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski AdvertiserInfo adv = mAdvertisers.remove(binder); 209917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (adv == null) { 210917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Log.e(TAG, "stopAdvertisingSet() - no client found for callback"); 211917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski return; 212917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski } 21364bf8e33481bb787aec895c603748eedb634a93bJakub Pawlowski 214917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Integer advertiser_id = adv.id; 215917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski binder.unlinkToDeath(adv.deathRecipient, 0); 21664bf8e33481bb787aec895c603748eedb634a93bJakub Pawlowski 217917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski if (advertiser_id < 0) { 218917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski Log.i(TAG, "stopAdvertisingSet() - advertiser not finished registration yet"); 219917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski // Advertiser will be freed once initiated in onAdvertisingSetStarted() 220917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski return; 221917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski } 222e82cce565b1549001f5a70526239c2d92106f85aJakub Pawlowski 223917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski stopAdvertisingSetNative(advertiser_id); 22427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 22527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 2268cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void enableAdvertisingSet(int advertiserId, boolean enable, int timeout) { 2278cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski enableAdvertisingSetNative(advertiserId, enable, timeout); 2288cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2298cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2308cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void setAdvertisingData(int advertiserId, AdvertiseData data) { 2318cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski String deviceName = AdapterService.getAdapterService().getName(); 2328cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski setAdvertisingDataNative( 2338cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); 2348cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2358cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2368cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void setScanResponseData(int advertiserId, AdvertiseData data) { 2378cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski String deviceName = AdapterService.getAdapterService().getName(); 2388cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski setScanResponseDataNative( 2398cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); 2408cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2418cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2428cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) { 2438cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski setAdvertisingParametersNative(advertiserId, parameters); 2448cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2458cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2468cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void setPeriodicAdvertisingParameters( 2478cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski int advertiserId, PeriodicAdvertisingParameters parameters) { 2488cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski setPeriodicAdvertisingParametersNative(advertiserId, parameters); 2498cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2508cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2518cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void setPeriodicAdvertisingData(int advertiserId, AdvertiseData data) { 2528cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski String deviceName = AdapterService.getAdapterService().getName(); 2538cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski setPeriodicAdvertisingDataNative( 2548cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); 2558cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2568cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2578cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) { 2588cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski setPeriodicAdvertisingEnableNative(advertiserId, enable); 2598cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2608cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2618cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onAdvertisingDataSet(int advertiser_id, int status) throws Exception { 2628cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski logd("onAdvertisingDataSet() advertiser_id=" + advertiser_id + ", status=" + status); 2638cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2648cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id); 2658cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski if (entry == null) { 2668cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Log.i(TAG, "onAdvertisingDataSet() - bad advertiser_id " + advertiser_id); 2678cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski return; 2688cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2698cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2708cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 2718cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski callback.onAdvertisingDataSet(advertiser_id, status); 2728cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2738cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2748cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onScanResponseDataSet(int advertiser_id, int status) throws Exception { 2758cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski logd("onScanResponseDataSet() advertiser_id=" + advertiser_id + ", status=" + status); 2768cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2778cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id); 2788cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski if (entry == null) { 2798cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Log.i(TAG, "onScanResponseDataSet() - bad advertiser_id " + advertiser_id); 2808cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski return; 2818cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2828cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2838cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 2848cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski callback.onScanResponseDataSet(advertiser_id, status); 2858cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2868cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2878cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onAdvertisingParametersUpdated(int advertiser_id, int tx_power, int status) 2888cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski throws Exception { 2898cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski logd("onAdvertisingParametersUpdated() advertiser_id=" + advertiser_id + ", tx_power=" 2908cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski + tx_power + ", status=" + status); 2918cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2928cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id); 2938cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski if (entry == null) { 2948cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Log.i(TAG, "onAdvertisingParametersUpdated() - bad advertiser_id " + advertiser_id); 2958cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski return; 2968cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 2978cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 2988cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 2998cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski callback.onAdvertisingParametersUpdated(advertiser_id, tx_power, status); 3008cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 3018cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3028cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onPeriodicAdvertisingParametersUpdated(int advertiser_id, int status) throws Exception { 3038cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski logd("onPeriodicAdvertisingParametersUpdated() advertiser_id=" + advertiser_id + ", status=" 3048cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski + status); 3058cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3068cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id); 3078cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski if (entry == null) { 3088cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Log.i(TAG, "onPeriodicAdvertisingParametersUpdated() - bad advertiser_id " 3098cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski + advertiser_id); 3108cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski return; 3118cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 3128cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3138cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 3148cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski callback.onPeriodicAdvertisingParametersUpdated(advertiser_id, status); 3158cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 3168cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3178cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onPeriodicAdvertisingDataSet(int advertiser_id, int status) throws Exception { 3188cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski logd("onPeriodicAdvertisingDataSet() advertiser_id=" + advertiser_id + ", status=" 3198cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski + status); 3208cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3218cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id); 3228cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski if (entry == null) { 3238cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Log.i(TAG, "onPeriodicAdvertisingDataSet() - bad advertiser_id " + advertiser_id); 3248cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski return; 3258cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 3268cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3278cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 3288cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski callback.onPeriodicAdvertisingDataSet(advertiser_id, status); 3298cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 3308cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3318cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski void onPeriodicAdvertisingEnable(int advertiser_id, boolean enable, int status) 3328cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski throws Exception { 3338cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski logd("onPeriodicAdvertisingEnable() advertiser_id=" + advertiser_id + ", status=" + status); 3348cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3358cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Map.Entry<IBinder, AdvertiserInfo> entry = findAdvertiser(advertiser_id); 3368cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski if (entry == null) { 3378cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski Log.i(TAG, "onAdvertisingSetEnable() - bad advertiser_id " + advertiser_id); 3388cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski return; 3398cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 3408cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 3418cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski IAdvertisingSetCallback callback = entry.getValue().callback; 3428cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski callback.onPeriodicAdvertisingEnable(advertiser_id, enable, status); 3438cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski } 3448cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski 34527bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang private void logd(String s) { 34627bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang if (DBG) { 34727bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang Log.d(TAG, s); 34827bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 34927bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 35027bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 351917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski static { 352917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski classInitNative(); 35327bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang } 35427bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang 355917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski private native static void classInitNative(); 356917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski private native void initializeNative(); 357917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski private native void cleanupNative(); 358917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski private native void startAdvertisingSetNative(AdvertisingSetParameters parameters, 359917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski byte[] advertiseData, byte[] scanResponse, 360b3246f3a27d269b4c0ef19cb2c8772d039eb26ccJakub Pawlowski PeriodicAdvertisingParameters periodicParameters, byte[] periodicData, int timeout, 361b3246f3a27d269b4c0ef19cb2c8772d039eb26ccJakub Pawlowski int reg_id); 362917f34e18aa235e68ac0663e24f52100e95970b7Jakub Pawlowski private native void stopAdvertisingSetNative(int advertiser_id); 3638cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski private native void enableAdvertisingSetNative(int advertiserId, boolean enable, int timeout); 3648cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski private native void setAdvertisingDataNative(int advertiserId, byte[] data); 3658cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski private native void setScanResponseDataNative(int advertiserId, byte[] data); 3668cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski private native void setAdvertisingParametersNative( 3678cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski int advertiserId, AdvertisingSetParameters parameters); 3688cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski private native void setPeriodicAdvertisingParametersNative( 3698cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski int advertiserId, PeriodicAdvertisingParameters parameters); 3708cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski private native void setPeriodicAdvertisingDataNative(int advertiserId, byte[] data); 3718cc4343c3b71c7a4d57c0b8c669b0a6188185f6bJakub Pawlowski private native void setPeriodicAdvertisingEnableNative(int advertiserId, boolean enable); 37227bd5f277ccf471f2fa9cd9151a2a226b51bc825Wei Wang} 373