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 android.bluetooth.le; 18 19 import static java.util.Objects.requireNonNull; 20 21 import android.annotation.RequiresNoPermission; 22 import android.annotation.RequiresPermission; 23 import android.annotation.SystemApi; 24 import android.bluetooth.BluetoothAdapter; 25 import android.bluetooth.IBluetoothGatt; 26 import android.bluetooth.annotations.RequiresBluetoothAdvertisePermission; 27 import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission; 28 import android.content.AttributionSource; 29 import android.os.RemoteException; 30 import android.util.Log; 31 32 /** 33 * This class provides a way to control single Bluetooth LE advertising instance. 34 * 35 * <p>To get an instance of {@link AdvertisingSet}, call the {@link 36 * BluetoothLeAdvertiser#startAdvertisingSet} method. 37 * 38 * @see AdvertiseData 39 */ 40 public final class AdvertisingSet { 41 private static final String TAG = "AdvertisingSet"; 42 43 private final IBluetoothGatt mGatt; 44 private int mAdvertiserId; 45 private AttributionSource mAttributionSource; 46 AdvertisingSet( IBluetoothGatt gatt, int advertiserId, BluetoothAdapter bluetoothAdapter, AttributionSource attributionSource)47 AdvertisingSet( 48 IBluetoothGatt gatt, 49 int advertiserId, 50 BluetoothAdapter bluetoothAdapter, 51 AttributionSource attributionSource) { 52 mAdvertiserId = advertiserId; 53 mAttributionSource = attributionSource; 54 mGatt = requireNonNull(gatt, "Bluetooth gatt cannot be null"); 55 } 56 setAdvertiserId(int advertiserId)57 /* package */ void setAdvertiserId(int advertiserId) { 58 mAdvertiserId = advertiserId; 59 } 60 61 /** 62 * Enables Advertising. This method returns immediately, the operation status is delivered 63 * through {@code callback.onAdvertisingEnabled()}. 64 * 65 * @param enable whether the advertising should be enabled (true), or disabled (false) 66 * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535 67 * (655,350 ms) 68 * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the 69 * controller shall attempt to send prior to terminating the extended advertising, even if 70 * the duration has not expired. Valid range is from 1 to 255. 71 */ 72 @RequiresLegacyBluetoothAdminPermission 73 @RequiresBluetoothAdvertisePermission 74 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) enableAdvertising(boolean enable, int duration, int maxExtendedAdvertisingEvents)75 public void enableAdvertising(boolean enable, int duration, int maxExtendedAdvertisingEvents) { 76 try { 77 mGatt.enableAdvertisingSet( 78 mAdvertiserId, 79 enable, 80 duration, 81 maxExtendedAdvertisingEvents, 82 mAttributionSource); 83 } catch (RemoteException e) { 84 Log.e(TAG, "remote exception - ", e); 85 } 86 } 87 88 /** 89 * Set/update data being Advertised. Make sure that data doesn't exceed the size limit for 90 * specified AdvertisingSetParameters. This method returns immediately, the operation status is 91 * delivered through {@code callback.onAdvertisingDataSet()}. 92 * 93 * <p>Advertising data must be empty if non-legacy scannable advertising is used. 94 * 95 * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link 96 * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable, 97 * three bytes will be added for flags. If the update takes place when the advertising set 98 * is enabled, the data can be maximum 251 bytes long. 99 */ 100 @RequiresLegacyBluetoothAdminPermission 101 @RequiresBluetoothAdvertisePermission 102 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) setAdvertisingData(AdvertiseData advertiseData)103 public void setAdvertisingData(AdvertiseData advertiseData) { 104 try { 105 mGatt.setAdvertisingData(mAdvertiserId, advertiseData, mAttributionSource); 106 } catch (RemoteException e) { 107 Log.e(TAG, "remote exception - ", e); 108 } 109 } 110 111 /** 112 * Set/update scan response data. Make sure that data doesn't exceed the size limit for 113 * specified AdvertisingSetParameters. This method returns immediately, the operation status is 114 * delivered through {@code callback.onScanResponseDataSet()}. 115 * 116 * @param scanResponse Scan response associated with the advertisement data. Size must not 117 * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes 118 * place when the advertising set is enabled, the data can be maximum 251 bytes long. 119 */ 120 @RequiresLegacyBluetoothAdminPermission 121 @RequiresBluetoothAdvertisePermission 122 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) setScanResponseData(AdvertiseData scanResponse)123 public void setScanResponseData(AdvertiseData scanResponse) { 124 try { 125 mGatt.setScanResponseData(mAdvertiserId, scanResponse, mAttributionSource); 126 } catch (RemoteException e) { 127 Log.e(TAG, "remote exception - ", e); 128 } 129 } 130 131 /** 132 * Update advertising parameters associated with this AdvertisingSet. Must be called when 133 * advertising is not active. This method returns immediately, the operation status is delivered 134 * through {@code callback.onAdvertisingParametersUpdated}. 135 * 136 * @param parameters advertising set parameters. 137 */ 138 @RequiresLegacyBluetoothAdminPermission 139 @RequiresBluetoothAdvertisePermission 140 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) setAdvertisingParameters(AdvertisingSetParameters parameters)141 public void setAdvertisingParameters(AdvertisingSetParameters parameters) { 142 try { 143 mGatt.setAdvertisingParameters(mAdvertiserId, parameters, mAttributionSource); 144 } catch (RemoteException e) { 145 Log.e(TAG, "remote exception - ", e); 146 } 147 } 148 149 /** 150 * Update periodic advertising parameters associated with this set. Must be called when periodic 151 * advertising is not enabled. This method returns immediately, the operation status is 152 * delivered through {@code callback.onPeriodicAdvertisingParametersUpdated()}. 153 */ 154 @RequiresLegacyBluetoothAdminPermission 155 @RequiresBluetoothAdvertisePermission 156 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters)157 public void setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters) { 158 try { 159 mGatt.setPeriodicAdvertisingParameters(mAdvertiserId, parameters, mAttributionSource); 160 } catch (RemoteException e) { 161 Log.e(TAG, "remote exception - ", e); 162 } 163 } 164 165 /** 166 * Used to set periodic advertising data, must be called after setPeriodicAdvertisingParameters, 167 * or after advertising was started with periodic advertising data set. This method returns 168 * immediately, the operation status is delivered through {@code 169 * callback.onPeriodicAdvertisingDataSet()}. 170 * 171 * @param periodicData Periodic advertising data. Size must not exceed {@link 172 * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the update takes place when the 173 * periodic advertising is enabled for this set, the data can be maximum 251 bytes long. 174 */ 175 @RequiresLegacyBluetoothAdminPermission 176 @RequiresBluetoothAdvertisePermission 177 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) setPeriodicAdvertisingData(AdvertiseData periodicData)178 public void setPeriodicAdvertisingData(AdvertiseData periodicData) { 179 try { 180 mGatt.setPeriodicAdvertisingData(mAdvertiserId, periodicData, mAttributionSource); 181 } catch (RemoteException e) { 182 Log.e(TAG, "remote exception - ", e); 183 } 184 } 185 186 /** 187 * Used to enable/disable periodic advertising. This method returns immediately, the operation 188 * status is delivered through {@code callback.onPeriodicAdvertisingEnable()}. 189 * 190 * @param enable whether the periodic advertising should be enabled (true), or disabled (false). 191 */ 192 @RequiresLegacyBluetoothAdminPermission 193 @RequiresBluetoothAdvertisePermission 194 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) setPeriodicAdvertisingEnabled(boolean enable)195 public void setPeriodicAdvertisingEnabled(boolean enable) { 196 try { 197 mGatt.setPeriodicAdvertisingEnable(mAdvertiserId, enable, mAttributionSource); 198 } catch (RemoteException e) { 199 Log.e(TAG, "remote exception - ", e); 200 } 201 } 202 203 /** 204 * Returns address associated with this advertising set. This method is exposed only for 205 * Bluetooth PTS tests, no app or system service should ever use it. 206 * 207 * @hide 208 */ 209 @RequiresBluetoothAdvertisePermission 210 @RequiresPermission( 211 allOf = { 212 android.Manifest.permission.BLUETOOTH_ADVERTISE, 213 android.Manifest.permission.BLUETOOTH_PRIVILEGED, 214 }) getOwnAddress()215 public void getOwnAddress() { 216 try { 217 mGatt.getOwnAddress(mAdvertiserId, mAttributionSource); 218 } catch (RemoteException e) { 219 Log.e(TAG, "remote exception - ", e); 220 } 221 } 222 223 /** 224 * Returns the advertiser ID associated with this advertising set. 225 * 226 * <p>This corresponds to the advertising set ID used at the HCI layer, in either LE Extended 227 * Advertising or Android-specific Multi-Advertising. 228 * 229 * @hide 230 */ 231 @RequiresNoPermission 232 @SystemApi getAdvertiserId()233 public int getAdvertiserId() { 234 return mAdvertiserId; 235 } 236 } 237