blob: 504118ec5da8b783f54c126651fa29d4facf26d0 [file] [log] [blame]
Wei Wang6d811182014-05-22 12:10:25 -07001/*
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
17package android.bluetooth.le;
18
Wei Wangaf74e662014-07-09 14:03:42 -070019import android.annotation.SystemApi;
Jakub Pawlowski9e377192017-04-12 08:51:22 -070020import android.bluetooth.BluetoothDevice;
Wei Wang6d811182014-05-22 12:10:25 -070021import android.os.Parcel;
22import android.os.Parcelable;
23
24/**
Wei Wangec64dbf2014-07-24 17:06:57 -070025 * Bluetooth LE scan settings are passed to {@link BluetoothLeScanner#startScan} to define the
26 * parameters for the scan.
Wei Wang6d811182014-05-22 12:10:25 -070027 */
28public final class ScanSettings implements Parcelable {
Wei Wang41907622015-01-12 20:02:37 -080029
30 /**
31 * A special Bluetooth LE scan mode. Applications using this scan mode will passively listen for
32 * other scan results without starting BLE scans themselves.
Wei Wang41907622015-01-12 20:02:37 -080033 */
34 public static final int SCAN_MODE_OPPORTUNISTIC = -1;
35
Wei Wang6d811182014-05-22 12:10:25 -070036 /**
Wei Wangec64dbf2014-07-24 17:06:57 -070037 * Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the
Vinay Kalia958154b2017-09-05 13:51:58 -070038 * least power. This mode is enforced if the scanning application is not in foreground.
Wei Wang6d811182014-05-22 12:10:25 -070039 */
40 public static final int SCAN_MODE_LOW_POWER = 0;
Wei Wangaf74e662014-07-09 14:03:42 -070041
Wei Wang6d811182014-05-22 12:10:25 -070042 /**
Wei Wangec64dbf2014-07-24 17:06:57 -070043 * Perform Bluetooth LE scan in balanced power mode. Scan results are returned at a rate that
44 * provides a good trade-off between scan frequency and power consumption.
Wei Wang6d811182014-05-22 12:10:25 -070045 */
46 public static final int SCAN_MODE_BALANCED = 1;
Wei Wangaf74e662014-07-09 14:03:42 -070047
Wei Wang6d811182014-05-22 12:10:25 -070048 /**
Wei Wangec64dbf2014-07-24 17:06:57 -070049 * Scan using highest duty cycle. It's recommended to only use this mode when the application is
50 * running in the foreground.
Wei Wang6d811182014-05-22 12:10:25 -070051 */
52 public static final int SCAN_MODE_LOW_LATENCY = 2;
53
54 /**
Wei Wangec64dbf2014-07-24 17:06:57 -070055 * Trigger a callback for every Bluetooth advertisement found that matches the filter criteria.
56 * If no filter is active, all advertisement packets are reported.
Wei Wang6d811182014-05-22 12:10:25 -070057 */
Wei Wangaf74e662014-07-09 14:03:42 -070058 public static final int CALLBACK_TYPE_ALL_MATCHES = 1;
Wei Wang6d811182014-05-22 12:10:25 -070059
60 /**
Wei Wangec64dbf2014-07-24 17:06:57 -070061 * A result callback is only triggered for the first advertisement packet received that matches
62 * the filter criteria.
Wei Wangaf74e662014-07-09 14:03:42 -070063 */
64 public static final int CALLBACK_TYPE_FIRST_MATCH = 2;
65
66 /**
67 * Receive a callback when advertisements are no longer received from a device that has been
68 * previously reported by a first match callback.
69 */
70 public static final int CALLBACK_TYPE_MATCH_LOST = 4;
71
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -070072
Wei Wangaf74e662014-07-09 14:03:42 -070073 /**
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -070074 * Determines how many advertisements to match per filter, as this is scarce hw resource
75 */
76 /**
77 * Match one advertisement per filter
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -070078 */
79 public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1;
80
81 /**
82 * Match few advertisement per filter, depends on current capability and availibility of
83 * the resources in hw
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -070084 */
85 public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2;
86
87 /**
88 * Match as many advertisement per filter as hw could allow, depends on current
89 * capability and availibility of the resources in hw
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -070090 */
91 public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3;
92
93
94 /**
95 * In Aggressive mode, hw will determine a match sooner even with feeble signal strength
96 * and few number of sightings/match in a duration.
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -070097 */
98 public static final int MATCH_MODE_AGGRESSIVE = 1;
99
100 /**
101 * For sticky mode, higher threshold of signal strength and sightings is required
102 * before reporting by hw
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700103 */
104 public static final int MATCH_MODE_STICKY = 2;
105
106 /**
107 * Request full scan results which contain the device, rssi, advertising data, scan response
108 * as well as the scan timestamp.
Wei Wang9960b572014-08-15 13:25:30 -0700109 *
110 * @hide
Wei Wang6d811182014-05-22 12:10:25 -0700111 */
Wei Wang9960b572014-08-15 13:25:30 -0700112 @SystemApi
Wei Wang6d811182014-05-22 12:10:25 -0700113 public static final int SCAN_RESULT_TYPE_FULL = 0;
Wei Wangaf74e662014-07-09 14:03:42 -0700114
Wei Wang6d811182014-05-22 12:10:25 -0700115 /**
Wei Wangaf74e662014-07-09 14:03:42 -0700116 * Request abbreviated scan results which contain the device, rssi and scan timestamp.
Wei Wangec64dbf2014-07-24 17:06:57 -0700117 * <p>
118 * <b>Note:</b> It is possible for an application to get more scan results than it asked for, if
119 * there are multiple apps using this type.
120 *
Wei Wang6d811182014-05-22 12:10:25 -0700121 * @hide
122 */
Wei Wangaf74e662014-07-09 14:03:42 -0700123 @SystemApi
124 public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1;
Wei Wang6d811182014-05-22 12:10:25 -0700125
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800126 /**
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800127 * Use all supported PHYs for scanning.
128 * This will check the controller capabilities, and start
129 * the scan on 1Mbit and LE Coded PHYs if supported, or on
130 * the 1Mbit PHY only.
131 */
132 public static final int PHY_LE_ALL_SUPPORTED = 255;
133
Wei Wang6d811182014-05-22 12:10:25 -0700134 // Bluetooth LE scan mode.
135 private int mScanMode;
136
137 // Bluetooth LE scan callback type
138 private int mCallbackType;
139
140 // Bluetooth LE scan result type
141 private int mScanResultType;
142
143 // Time of delay for reporting the scan result
Wei Wang685c17582014-07-16 22:02:03 -0700144 private long mReportDelayMillis;
Wei Wang6d811182014-05-22 12:10:25 -0700145
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700146 private int mMatchMode;
147
148 private int mNumOfMatchesPerFilter;
149
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800150 // Include only legacy advertising results
151 private boolean mLegacy;
152
153 private int mPhy;
154
Wei Wang6d811182014-05-22 12:10:25 -0700155 public int getScanMode() {
156 return mScanMode;
157 }
158
159 public int getCallbackType() {
160 return mCallbackType;
161 }
162
163 public int getScanResultType() {
164 return mScanResultType;
165 }
166
167 /**
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700168 * @hide
169 */
170 public int getMatchMode() {
171 return mMatchMode;
172 }
173
174 /**
175 * @hide
176 */
177 public int getNumOfMatches() {
178 return mNumOfMatchesPerFilter;
179 }
180
181 /**
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800182 * Returns whether only legacy advertisements will be returned.
183 * Legacy advertisements include advertisements as specified
184 * by the Bluetooth core specification 4.2 and below.
185 */
186 public boolean getLegacy() {
187 return mLegacy;
188 }
189
190 /**
191 * Returns the physical layer used during a scan.
192 */
193 public int getPhy() {
194 return mPhy;
195 }
196
197 /**
Wei Wang6d811182014-05-22 12:10:25 -0700198 * Returns report delay timestamp based on the device clock.
199 */
Wei Wang685c17582014-07-16 22:02:03 -0700200 public long getReportDelayMillis() {
201 return mReportDelayMillis;
Wei Wang6d811182014-05-22 12:10:25 -0700202 }
203
204 private ScanSettings(int scanMode, int callbackType, int scanResultType,
Jack Hea355e5e2017-08-22 16:06:54 -0700205 long reportDelayMillis, int matchMode,
206 int numOfMatchesPerFilter, boolean legacy, int phy) {
Wei Wang6d811182014-05-22 12:10:25 -0700207 mScanMode = scanMode;
208 mCallbackType = callbackType;
209 mScanResultType = scanResultType;
Wei Wangec64dbf2014-07-24 17:06:57 -0700210 mReportDelayMillis = reportDelayMillis;
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700211 mNumOfMatchesPerFilter = numOfMatchesPerFilter;
Wei Wangc5065ee2015-05-01 00:50:32 -0700212 mMatchMode = matchMode;
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800213 mLegacy = legacy;
214 mPhy = phy;
Wei Wang6d811182014-05-22 12:10:25 -0700215 }
216
217 private ScanSettings(Parcel in) {
218 mScanMode = in.readInt();
219 mCallbackType = in.readInt();
220 mScanResultType = in.readInt();
Wei Wang685c17582014-07-16 22:02:03 -0700221 mReportDelayMillis = in.readLong();
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700222 mMatchMode = in.readInt();
223 mNumOfMatchesPerFilter = in.readInt();
Jack He2992cd02017-08-22 21:21:23 -0700224 mLegacy = in.readInt() != 0;
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800225 mPhy = in.readInt();
Wei Wang6d811182014-05-22 12:10:25 -0700226 }
227
228 @Override
229 public void writeToParcel(Parcel dest, int flags) {
230 dest.writeInt(mScanMode);
231 dest.writeInt(mCallbackType);
232 dest.writeInt(mScanResultType);
Wei Wang685c17582014-07-16 22:02:03 -0700233 dest.writeLong(mReportDelayMillis);
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700234 dest.writeInt(mMatchMode);
235 dest.writeInt(mNumOfMatchesPerFilter);
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800236 dest.writeInt(mLegacy ? 1 : 0);
237 dest.writeInt(mPhy);
Wei Wang6d811182014-05-22 12:10:25 -0700238 }
239
240 @Override
241 public int describeContents() {
242 return 0;
243 }
244
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700245 public static final @android.annotation.NonNull Parcelable.Creator<ScanSettings> CREATOR =
Jack He2992cd02017-08-22 21:21:23 -0700246 new Creator<ScanSettings>() {
Jack Hea355e5e2017-08-22 16:06:54 -0700247 @Override
248 public ScanSettings[] newArray(int size) {
249 return new ScanSettings[size];
250 }
Wei Wang6d811182014-05-22 12:10:25 -0700251
Jack Hea355e5e2017-08-22 16:06:54 -0700252 @Override
253 public ScanSettings createFromParcel(Parcel in) {
254 return new ScanSettings(in);
255 }
256 };
Wei Wang6d811182014-05-22 12:10:25 -0700257
258 /**
259 * Builder for {@link ScanSettings}.
260 */
261 public static final class Builder {
262 private int mScanMode = SCAN_MODE_LOW_POWER;
Wei Wangaf74e662014-07-09 14:03:42 -0700263 private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES;
Wei Wang6d811182014-05-22 12:10:25 -0700264 private int mScanResultType = SCAN_RESULT_TYPE_FULL;
Wei Wang685c17582014-07-16 22:02:03 -0700265 private long mReportDelayMillis = 0;
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700266 private int mMatchMode = MATCH_MODE_AGGRESSIVE;
Jack Hea355e5e2017-08-22 16:06:54 -0700267 private int mNumOfMatchesPerFilter = MATCH_NUM_MAX_ADVERTISEMENT;
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800268 private boolean mLegacy = true;
269 private int mPhy = PHY_LE_ALL_SUPPORTED;
270
Wei Wang6d811182014-05-22 12:10:25 -0700271 /**
272 * Set scan mode for Bluetooth LE scan.
273 *
Wei Wangaf74e662014-07-09 14:03:42 -0700274 * @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER},
Jack Hea355e5e2017-08-22 16:06:54 -0700275 * {@link ScanSettings#SCAN_MODE_BALANCED} or {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
Wei Wang6d811182014-05-22 12:10:25 -0700276 * @throws IllegalArgumentException If the {@code scanMode} is invalid.
277 */
278 public Builder setScanMode(int scanMode) {
Wei Wang41907622015-01-12 20:02:37 -0800279 if (scanMode < SCAN_MODE_OPPORTUNISTIC || scanMode > SCAN_MODE_LOW_LATENCY) {
Wei Wang6d811182014-05-22 12:10:25 -0700280 throw new IllegalArgumentException("invalid scan mode " + scanMode);
281 }
282 mScanMode = scanMode;
283 return this;
284 }
285
286 /**
287 * Set callback type for Bluetooth LE scan.
288 *
Wei Wangaf74e662014-07-09 14:03:42 -0700289 * @param callbackType The callback type flags for the scan.
Wei Wang6d811182014-05-22 12:10:25 -0700290 * @throws IllegalArgumentException If the {@code callbackType} is invalid.
291 */
292 public Builder setCallbackType(int callbackType) {
Wei Wangec64dbf2014-07-24 17:06:57 -0700293
294 if (!isValidCallbackType(callbackType)) {
Wei Wang6d811182014-05-22 12:10:25 -0700295 throw new IllegalArgumentException("invalid callback type - " + callbackType);
296 }
297 mCallbackType = callbackType;
298 return this;
299 }
300
Wei Wangec64dbf2014-07-24 17:06:57 -0700301 // Returns true if the callbackType is valid.
302 private boolean isValidCallbackType(int callbackType) {
Jack He2992cd02017-08-22 21:21:23 -0700303 if (callbackType == CALLBACK_TYPE_ALL_MATCHES
304 || callbackType == CALLBACK_TYPE_FIRST_MATCH
305 || callbackType == CALLBACK_TYPE_MATCH_LOST) {
Wei Wangec64dbf2014-07-24 17:06:57 -0700306 return true;
307 }
308 return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST);
309 }
310
Wei Wang6d811182014-05-22 12:10:25 -0700311 /**
312 * Set scan result type for Bluetooth LE scan.
313 *
Jack Hea355e5e2017-08-22 16:06:54 -0700314 * @param scanResultType Type for scan result, could be either {@link
315 * ScanSettings#SCAN_RESULT_TYPE_FULL} or {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}.
Wei Wang6d811182014-05-22 12:10:25 -0700316 * @throws IllegalArgumentException If the {@code scanResultType} is invalid.
Wei Wang6d811182014-05-22 12:10:25 -0700317 * @hide
318 */
Wei Wangaf74e662014-07-09 14:03:42 -0700319 @SystemApi
Wei Wang6d811182014-05-22 12:10:25 -0700320 public Builder setScanResultType(int scanResultType) {
321 if (scanResultType < SCAN_RESULT_TYPE_FULL
Wei Wangaf74e662014-07-09 14:03:42 -0700322 || scanResultType > SCAN_RESULT_TYPE_ABBREVIATED) {
Wei Wang6d811182014-05-22 12:10:25 -0700323 throw new IllegalArgumentException(
324 "invalid scanResultType - " + scanResultType);
325 }
326 mScanResultType = scanResultType;
327 return this;
328 }
329
330 /**
331 * Set report delay timestamp for Bluetooth LE scan.
Wei Wang685c17582014-07-16 22:02:03 -0700332 *
Wei Wang9960b572014-08-15 13:25:30 -0700333 * @param reportDelayMillis Delay of report in milliseconds. Set to 0 to be notified of
Jack Hea355e5e2017-08-22 16:06:54 -0700334 * results immediately. Values &gt; 0 causes the scan results to be queued up and delivered
335 * after the requested delay or when the internal buffers fill up.
Wei Wangec64dbf2014-07-24 17:06:57 -0700336 * @throws IllegalArgumentException If {@code reportDelayMillis} &lt; 0.
Wei Wang6d811182014-05-22 12:10:25 -0700337 */
Wei Wang9960b572014-08-15 13:25:30 -0700338 public Builder setReportDelay(long reportDelayMillis) {
Wei Wang685c17582014-07-16 22:02:03 -0700339 if (reportDelayMillis < 0) {
Wei Wang9960b572014-08-15 13:25:30 -0700340 throw new IllegalArgumentException("reportDelay must be > 0");
Wei Wang685c17582014-07-16 22:02:03 -0700341 }
342 mReportDelayMillis = reportDelayMillis;
Wei Wang6d811182014-05-22 12:10:25 -0700343 return this;
344 }
345
346 /**
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700347 * Set the number of matches for Bluetooth LE scan filters hardware match
348 *
349 * @param numOfMatches The num of matches can be one of
Jack Hea355e5e2017-08-22 16:06:54 -0700350 * {@link ScanSettings#MATCH_NUM_ONE_ADVERTISEMENT}
351 * or {@link ScanSettings#MATCH_NUM_FEW_ADVERTISEMENT} or {@link
352 * ScanSettings#MATCH_NUM_MAX_ADVERTISEMENT}
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700353 * @throws IllegalArgumentException If the {@code matchMode} is invalid.
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700354 */
355 public Builder setNumOfMatches(int numOfMatches) {
356 if (numOfMatches < MATCH_NUM_ONE_ADVERTISEMENT
357 || numOfMatches > MATCH_NUM_MAX_ADVERTISEMENT) {
358 throw new IllegalArgumentException("invalid numOfMatches " + numOfMatches);
359 }
360 mNumOfMatchesPerFilter = numOfMatches;
361 return this;
362 }
363
364 /**
365 * Set match mode for Bluetooth LE scan filters hardware match
366 *
Jack Hea355e5e2017-08-22 16:06:54 -0700367 * @param matchMode The match mode can be one of {@link ScanSettings#MATCH_MODE_AGGRESSIVE}
368 * or {@link ScanSettings#MATCH_MODE_STICKY}
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700369 * @throws IllegalArgumentException If the {@code matchMode} is invalid.
Prerepa Viswanadhame593d0a2015-04-07 14:36:53 -0700370 */
371 public Builder setMatchMode(int matchMode) {
372 if (matchMode < MATCH_MODE_AGGRESSIVE
373 || matchMode > MATCH_MODE_STICKY) {
374 throw new IllegalArgumentException("invalid matchMode " + matchMode);
375 }
376 mMatchMode = matchMode;
377 return this;
378 }
379
380 /**
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800381 * Set whether only legacy advertisments should be returned in scan results.
382 * Legacy advertisements include advertisements as specified by the
383 * Bluetooth core specification 4.2 and below. This is true by default
384 * for compatibility with older apps.
385 *
386 * @param legacy true if only legacy advertisements will be returned
387 */
388 public Builder setLegacy(boolean legacy) {
389 mLegacy = legacy;
390 return this;
391 }
392
393 /**
394 * Set the Physical Layer to use during this scan.
395 * This is used only if {@link ScanSettings.Builder#setLegacy}
396 * is set to false.
397 * {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}
398 * may be used to check whether LE Coded phy is supported by calling
399 * {@link android.bluetooth.BluetoothAdapter#isLeCodedPhySupported}.
400 * Selecting an unsupported phy will result in failure to start scan.
401 *
Jack Hea355e5e2017-08-22 16:06:54 -0700402 * @param phy Can be one of {@link BluetoothDevice#PHY_LE_1M}, {@link
403 * BluetoothDevice#PHY_LE_CODED} or {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
Jakub Pawlowski3aca9332017-01-17 07:50:46 -0800404 */
405 public Builder setPhy(int phy) {
406 mPhy = phy;
407 return this;
408 }
409
410 /**
Wei Wang6d811182014-05-22 12:10:25 -0700411 * Build {@link ScanSettings}.
412 */
413 public ScanSettings build() {
414 return new ScanSettings(mScanMode, mCallbackType, mScanResultType,
Jack Hea355e5e2017-08-22 16:06:54 -0700415 mReportDelayMillis, mMatchMode,
416 mNumOfMatchesPerFilter, mLegacy, mPhy);
Wei Wang6d811182014-05-22 12:10:25 -0700417 }
418 }
419}