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