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