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.os.Parcel;
20 import android.os.Parcelable;
21 
22 /**
23  * The {@link AdvertiseSettings} provide a way to adjust advertising preferences for each
24  * Bluetooth LE advertisement instance. Use {@link AdvertiseSettings.Builder} to create an
25  * instance of this class.
26  */
27 public final class AdvertiseSettings implements Parcelable {
28     /**
29      * Perform Bluetooth LE advertising in low power mode. This is the default and preferred
30      * advertising mode as it consumes the least power.
31      */
32     public static final int ADVERTISE_MODE_LOW_POWER = 0;
33 
34     /**
35      * Perform Bluetooth LE advertising in balanced power mode. This is balanced between advertising
36      * frequency and power consumption.
37      */
38     public static final int ADVERTISE_MODE_BALANCED = 1;
39 
40     /**
41      * Perform Bluetooth LE advertising in low latency, high power mode. This has the highest power
42      * consumption and should not be used for continuous background advertising.
43      */
44     public static final int ADVERTISE_MODE_LOW_LATENCY = 2;
45 
46     /**
47      * Advertise using the lowest transmission (TX) power level. Low transmission power can be used
48      * to restrict the visibility range of advertising packets.
49      */
50     public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0;
51 
52     /**
53      * Advertise using low TX power level.
54      */
55     public static final int ADVERTISE_TX_POWER_LOW = 1;
56 
57     /**
58      * Advertise using medium TX power level.
59      */
60     public static final int ADVERTISE_TX_POWER_MEDIUM = 2;
61 
62     /**
63      * Advertise using high TX power level. This corresponds to largest visibility range of the
64      * advertising packet.
65      */
66     public static final int ADVERTISE_TX_POWER_HIGH = 3;
67 
68     /**
69      * The maximum limited advertisement duration as specified by the Bluetooth SIG
70      */
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 
AdvertiseSettings(int advertiseMode, int advertiseTxPowerLevel, boolean advertiseConnectable, int advertiseTimeout)78     private AdvertiseSettings(int advertiseMode, int advertiseTxPowerLevel,
79             boolean advertiseConnectable, int advertiseTimeout) {
80         mAdvertiseMode = advertiseMode;
81         mAdvertiseTxPowerLevel = advertiseTxPowerLevel;
82         mAdvertiseConnectable = advertiseConnectable;
83         mAdvertiseTimeoutMillis = advertiseTimeout;
84     }
85 
AdvertiseSettings(Parcel in)86     private AdvertiseSettings(Parcel in) {
87         mAdvertiseMode = in.readInt();
88         mAdvertiseTxPowerLevel = in.readInt();
89         mAdvertiseConnectable = in.readInt() != 0;
90         mAdvertiseTimeoutMillis = in.readInt();
91     }
92 
93     /**
94      * Returns the advertise mode.
95      */
getMode()96     public int getMode() {
97         return mAdvertiseMode;
98     }
99 
100     /**
101      * Returns the TX power level for advertising.
102      */
getTxPowerLevel()103     public int getTxPowerLevel() {
104         return mAdvertiseTxPowerLevel;
105     }
106 
107     /**
108      * Returns whether the advertisement will indicate connectable.
109      */
isConnectable()110     public boolean isConnectable() {
111         return mAdvertiseConnectable;
112     }
113 
114     /**
115      * Returns the advertising time limit in milliseconds.
116      */
getTimeout()117     public int getTimeout() {
118         return mAdvertiseTimeoutMillis;
119     }
120 
121     @Override
toString()122     public String toString() {
123         return "Settings [mAdvertiseMode=" + mAdvertiseMode
124                 + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
125                 + ", mAdvertiseConnectable=" + mAdvertiseConnectable
126                 + ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis + "]";
127     }
128 
129     @Override
describeContents()130     public int describeContents() {
131         return 0;
132     }
133 
134     @Override
writeToParcel(Parcel dest, int flags)135     public void writeToParcel(Parcel dest, int flags) {
136         dest.writeInt(mAdvertiseMode);
137         dest.writeInt(mAdvertiseTxPowerLevel);
138         dest.writeInt(mAdvertiseConnectable ? 1 : 0);
139         dest.writeInt(mAdvertiseTimeoutMillis);
140     }
141 
142     public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseSettings> CREATOR =
143             new Creator<AdvertiseSettings>() {
144                 @Override
145                 public AdvertiseSettings[] newArray(int size) {
146                     return new AdvertiseSettings[size];
147                 }
148 
149                 @Override
150                 public AdvertiseSettings createFromParcel(Parcel in) {
151                     return new AdvertiseSettings(in);
152                 }
153             };
154 
155     /**
156      * Builder class for {@link AdvertiseSettings}.
157      */
158     public static final class Builder {
159         private int mMode = ADVERTISE_MODE_LOW_POWER;
160         private int mTxPowerLevel = ADVERTISE_TX_POWER_MEDIUM;
161         private int mTimeoutMillis = 0;
162         private boolean mConnectable = true;
163 
164         /**
165          * Set advertise mode to control the advertising power and latency.
166          *
167          * @param advertiseMode Bluetooth LE Advertising mode, can only be one of {@link
168          * AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
169          * {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED},
170          * or {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
171          * @throws IllegalArgumentException If the advertiseMode is invalid.
172          */
setAdvertiseMode(int advertiseMode)173         public Builder setAdvertiseMode(int advertiseMode) {
174             if (advertiseMode < ADVERTISE_MODE_LOW_POWER
175                     || advertiseMode > ADVERTISE_MODE_LOW_LATENCY) {
176                 throw new IllegalArgumentException("unknown mode " + advertiseMode);
177             }
178             mMode = advertiseMode;
179             return this;
180         }
181 
182         /**
183          * Set advertise TX power level to control the transmission power level for the advertising.
184          *
185          * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of
186          * {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW}, {@link
187          * AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
188          * {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM}
189          * or {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
190          * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
191          */
setTxPowerLevel(int txPowerLevel)192         public Builder setTxPowerLevel(int txPowerLevel) {
193             if (txPowerLevel < ADVERTISE_TX_POWER_ULTRA_LOW
194                     || txPowerLevel > ADVERTISE_TX_POWER_HIGH) {
195                 throw new IllegalArgumentException("unknown tx power level " + txPowerLevel);
196             }
197             mTxPowerLevel = txPowerLevel;
198             return this;
199         }
200 
201         /**
202          * Set whether the advertisement type should be connectable or non-connectable.
203          *
204          * @param connectable Controls whether the advertisment type will be connectable (true) or
205          * non-connectable (false).
206          */
setConnectable(boolean connectable)207         public Builder setConnectable(boolean connectable) {
208             mConnectable = connectable;
209             return this;
210         }
211 
212         /**
213          * Limit advertising to a given amount of time.
214          *
215          * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds. A value
216          * of 0 will disable the time limit.
217          * @throws IllegalArgumentException If the provided timeout is over 180000 ms.
218          */
setTimeout(int timeoutMillis)219         public Builder setTimeout(int timeoutMillis) {
220             if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
221                 throw new IllegalArgumentException("timeoutMillis invalid (must be 0-"
222                         + LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
223             }
224             mTimeoutMillis = timeoutMillis;
225             return this;
226         }
227 
228         /**
229          * Build the {@link AdvertiseSettings} object.
230          */
build()231         public AdvertiseSettings build() {
232             return new AdvertiseSettings(mMode, mTxPowerLevel, mConnectable, mTimeoutMillis);
233         }
234     }
235 }
236