1 /* 2 * Copyright (C) 2014 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.NonNull; 20 import android.annotation.SystemApi; 21 import android.bluetooth.le.AdvertisingSetParameters.AddressTypeStatus; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.util.Log; 25 26 /** 27 * The {@link AdvertiseSettings} provide a way to adjust advertising preferences for each Bluetooth 28 * LE advertisement instance. Use {@link AdvertiseSettings.Builder} to create an instance of this 29 * class. 30 */ 31 public final class AdvertiseSettings implements Parcelable { 32 private static final String TAG = AdvertiseSettings.class.getSimpleName(); 33 34 /** 35 * Perform Bluetooth LE advertising in low power mode. This is the default and preferred 36 * advertising mode as it consumes the least power. 37 */ 38 public static final int ADVERTISE_MODE_LOW_POWER = 0; 39 40 /** 41 * Perform Bluetooth LE advertising in balanced power mode. This is balanced between advertising 42 * frequency and power consumption. 43 */ 44 public static final int ADVERTISE_MODE_BALANCED = 1; 45 46 /** 47 * Perform Bluetooth LE advertising in low latency, high power mode. This has the highest power 48 * consumption and should not be used for continuous background advertising. 49 */ 50 public static final int ADVERTISE_MODE_LOW_LATENCY = 2; 51 52 /** 53 * Advertise using the lowest transmission (TX) power level. Low transmission power can be used 54 * to restrict the visibility range of advertising packets. 55 */ 56 public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0; 57 58 /** Advertise using low TX power level. */ 59 public static final int ADVERTISE_TX_POWER_LOW = 1; 60 61 /** Advertise using medium TX power level. */ 62 public static final int ADVERTISE_TX_POWER_MEDIUM = 2; 63 64 /** 65 * Advertise using high TX power level. This corresponds to largest visibility range of the 66 * advertising packet. 67 */ 68 public static final int ADVERTISE_TX_POWER_HIGH = 3; 69 70 /** The maximum limited advertisement duration as specified by the Bluetooth SIG */ 71 private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000; 72 73 private final int mAdvertiseMode; 74 private final int mAdvertiseTxPowerLevel; 75 private final int mAdvertiseTimeoutMillis; 76 private final boolean mAdvertiseConnectable; 77 private final boolean mAdvertiseDiscoverable; 78 private final int mOwnAddressType; 79 AdvertiseSettings( int advertiseMode, int advertiseTxPowerLevel, boolean advertiseConnectable, boolean discoverable, int advertiseTimeout, @AddressTypeStatus int ownAddressType)80 private AdvertiseSettings( 81 int advertiseMode, 82 int advertiseTxPowerLevel, 83 boolean advertiseConnectable, 84 boolean discoverable, 85 int advertiseTimeout, 86 @AddressTypeStatus int ownAddressType) { 87 mAdvertiseMode = advertiseMode; 88 mAdvertiseTxPowerLevel = advertiseTxPowerLevel; 89 mAdvertiseConnectable = advertiseConnectable; 90 mAdvertiseDiscoverable = discoverable; 91 mAdvertiseTimeoutMillis = advertiseTimeout; 92 mOwnAddressType = ownAddressType; 93 } 94 AdvertiseSettings(Parcel in)95 private AdvertiseSettings(Parcel in) { 96 mAdvertiseMode = in.readInt(); 97 mAdvertiseTxPowerLevel = in.readInt(); 98 mAdvertiseConnectable = in.readInt() != 0; 99 mAdvertiseTimeoutMillis = in.readInt(); 100 mOwnAddressType = in.readInt(); 101 mAdvertiseDiscoverable = in.readInt() != 0; 102 } 103 104 /** Returns the advertise mode. */ getMode()105 public int getMode() { 106 return mAdvertiseMode; 107 } 108 109 /** Returns the TX power level for advertising. */ getTxPowerLevel()110 public int getTxPowerLevel() { 111 return mAdvertiseTxPowerLevel; 112 } 113 114 /** Returns whether the advertisement will indicate connectable. */ isConnectable()115 public boolean isConnectable() { 116 return mAdvertiseConnectable; 117 } 118 119 /** Returns whether the advertisement will be discoverable. */ isDiscoverable()120 public boolean isDiscoverable() { 121 return mAdvertiseDiscoverable; 122 } 123 124 /** Returns the advertising time limit in milliseconds. */ getTimeout()125 public int getTimeout() { 126 return mAdvertiseTimeoutMillis; 127 } 128 129 /** 130 * @return the own address type for advertising 131 * @hide 132 */ 133 @SystemApi getOwnAddressType()134 public @AddressTypeStatus int getOwnAddressType() { 135 return mOwnAddressType; 136 } 137 138 @Override toString()139 public String toString() { 140 return "Settings [mAdvertiseMode=" 141 + mAdvertiseMode 142 + ", mAdvertiseTxPowerLevel=" 143 + mAdvertiseTxPowerLevel 144 + ", mAdvertiseConnectable=" 145 + mAdvertiseConnectable 146 + ", mAdvertiseDiscoverable=" 147 + mAdvertiseDiscoverable 148 + ", mAdvertiseTimeoutMillis=" 149 + mAdvertiseTimeoutMillis 150 + ", mOwnAddressType=" 151 + mOwnAddressType 152 + "]"; 153 } 154 155 @Override describeContents()156 public int describeContents() { 157 return 0; 158 } 159 160 @Override writeToParcel(Parcel dest, int flags)161 public void writeToParcel(Parcel dest, int flags) { 162 dest.writeInt(mAdvertiseMode); 163 dest.writeInt(mAdvertiseTxPowerLevel); 164 dest.writeInt(mAdvertiseConnectable ? 1 : 0); 165 dest.writeInt(mAdvertiseTimeoutMillis); 166 dest.writeInt(mOwnAddressType); 167 dest.writeInt(mAdvertiseDiscoverable ? 1 : 0); 168 } 169 170 public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseSettings> CREATOR = 171 new Creator<AdvertiseSettings>() { 172 @Override 173 public AdvertiseSettings[] newArray(int size) { 174 return new AdvertiseSettings[size]; 175 } 176 177 @Override 178 public AdvertiseSettings createFromParcel(Parcel in) { 179 return new AdvertiseSettings(in); 180 } 181 }; 182 183 /** Builder class for {@link AdvertiseSettings}. */ 184 public static final class Builder { 185 private int mMode = ADVERTISE_MODE_LOW_POWER; 186 private int mTxPowerLevel = ADVERTISE_TX_POWER_MEDIUM; 187 private int mTimeoutMillis = 0; 188 private boolean mConnectable = true; 189 private boolean mDiscoverable = true; 190 private int mOwnAddressType = AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT; 191 192 /** 193 * Set advertise mode to control the advertising power and latency. 194 * 195 * @param advertiseMode Bluetooth LE Advertising mode, can only be one of {@link 196 * AdvertiseSettings#ADVERTISE_MODE_LOW_POWER}, {@link 197 * AdvertiseSettings#ADVERTISE_MODE_BALANCED}, or {@link 198 * AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}. 199 * @throws IllegalArgumentException If the advertiseMode is invalid. 200 */ setAdvertiseMode(int advertiseMode)201 public Builder setAdvertiseMode(int advertiseMode) { 202 if (advertiseMode < ADVERTISE_MODE_LOW_POWER 203 || advertiseMode > ADVERTISE_MODE_LOW_LATENCY) { 204 throw new IllegalArgumentException("unknown mode " + advertiseMode); 205 } 206 mMode = advertiseMode; 207 return this; 208 } 209 210 /** 211 * Set advertise TX power level to control the transmission power level for the advertising. 212 * 213 * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of 214 * {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW}, {@link 215 * AdvertiseSettings#ADVERTISE_TX_POWER_LOW}, {@link 216 * AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM} or {@link 217 * AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}. 218 * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid. 219 */ setTxPowerLevel(int txPowerLevel)220 public Builder setTxPowerLevel(int txPowerLevel) { 221 if (txPowerLevel < ADVERTISE_TX_POWER_ULTRA_LOW 222 || txPowerLevel > ADVERTISE_TX_POWER_HIGH) { 223 throw new IllegalArgumentException("unknown tx power level " + txPowerLevel); 224 } 225 Log.d(TAG, "setTxPowerLevel: " + txPowerLevel); 226 mTxPowerLevel = txPowerLevel; 227 return this; 228 } 229 230 /** 231 * Set whether the advertisement type should be connectable or non-connectable. 232 * 233 * @param connectable Controls whether the advertisement type will be connectable (true) or 234 * non-connectable (false). 235 */ setConnectable(boolean connectable)236 public Builder setConnectable(boolean connectable) { 237 mConnectable = connectable; 238 return this; 239 } 240 241 /** 242 * Set whether the advertisement type should be discoverable or non-discoverable. 243 * 244 * @param discoverable Controls whether the advertisement type will be discoverable ({@code 245 * true}) or non-discoverable ({@code false}). 246 */ setDiscoverable(boolean discoverable)247 public @NonNull Builder setDiscoverable(boolean discoverable) { 248 mDiscoverable = discoverable; 249 return this; 250 } 251 252 /** 253 * Limit advertising to a given amount of time. 254 * 255 * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds. A value 256 * of 0 will disable the time limit. 257 * @throws IllegalArgumentException If the provided timeout is over 180000 ms. 258 */ setTimeout(int timeoutMillis)259 public Builder setTimeout(int timeoutMillis) { 260 if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) { 261 throw new IllegalArgumentException( 262 "timeoutMillis invalid (must be 0-" 263 + LIMITED_ADVERTISING_MAX_MILLIS 264 + " milliseconds)"); 265 } 266 mTimeoutMillis = timeoutMillis; 267 return this; 268 } 269 270 /** 271 * Set own address type for advertising to control public or privacy mode. If used to set 272 * address type anything other than {@link AdvertisingSetParameters#ADDRESS_TYPE_DEFAULT}, 273 * then it will require BLUETOOTH_PRIVILEGED permission and will be checked at the time of 274 * starting advertising. 275 * 276 * @throws IllegalArgumentException If the {@code ownAddressType} is invalid 277 * @hide 278 */ 279 @SystemApi setOwnAddressType(@ddressTypeStatus int ownAddressType)280 public @NonNull Builder setOwnAddressType(@AddressTypeStatus int ownAddressType) { 281 if (ownAddressType < AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT 282 || ownAddressType 283 > AdvertisingSetParameters.ADDRESS_TYPE_RANDOM_NON_RESOLVABLE) { 284 throw new IllegalArgumentException("unknown address type " + ownAddressType); 285 } 286 mOwnAddressType = ownAddressType; 287 return this; 288 } 289 290 /** Build the {@link AdvertiseSettings} object. */ build()291 public AdvertiseSettings build() { 292 return new AdvertiseSettings( 293 mMode, 294 mTxPowerLevel, 295 mConnectable, 296 mDiscoverable, 297 mTimeoutMillis, 298 mOwnAddressType); 299 } 300 } 301 } 302