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