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.SystemApi; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 23 /** 24 * Bluetooth LE scan settings are passed to {@link BluetoothLeScanner#startScan} to define the 25 * parameters for the scan. 26 */ 27 public final class ScanSettings implements Parcelable { 28 /** 29 * Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the 30 * least power. 31 */ 32 public static final int SCAN_MODE_LOW_POWER = 0; 33 34 /** 35 * Perform Bluetooth LE scan in balanced power mode. Scan results are returned at a rate that 36 * provides a good trade-off between scan frequency and power consumption. 37 */ 38 public static final int SCAN_MODE_BALANCED = 1; 39 40 /** 41 * Scan using highest duty cycle. It's recommended to only use this mode when the application is 42 * running in the foreground. 43 */ 44 public static final int SCAN_MODE_LOW_LATENCY = 2; 45 46 /** 47 * Trigger a callback for every Bluetooth advertisement found that matches the filter criteria. 48 * If no filter is active, all advertisement packets are reported. 49 */ 50 public static final int CALLBACK_TYPE_ALL_MATCHES = 1; 51 52 /** 53 * A result callback is only triggered for the first advertisement packet received that matches 54 * the filter criteria. 55 * 56 * @hide 57 */ 58 @SystemApi 59 public static final int CALLBACK_TYPE_FIRST_MATCH = 2; 60 61 /** 62 * Receive a callback when advertisements are no longer received from a device that has been 63 * previously reported by a first match callback. 64 * 65 * @hide 66 */ 67 @SystemApi 68 public static final int CALLBACK_TYPE_MATCH_LOST = 4; 69 70 /** 71 * Request full scan results which contain the device, rssi, advertising data, scan response as 72 * well as the scan timestamp. 73 * 74 * @hide 75 */ 76 @SystemApi 77 public static final int SCAN_RESULT_TYPE_FULL = 0; 78 79 /** 80 * Request abbreviated scan results which contain the device, rssi and scan timestamp. 81 * <p> 82 * <b>Note:</b> It is possible for an application to get more scan results than it asked for, if 83 * there are multiple apps using this type. 84 * 85 * @hide 86 */ 87 @SystemApi 88 public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1; 89 90 // Bluetooth LE scan mode. 91 private int mScanMode; 92 93 // Bluetooth LE scan callback type 94 private int mCallbackType; 95 96 // Bluetooth LE scan result type 97 private int mScanResultType; 98 99 // Time of delay for reporting the scan result 100 private long mReportDelayMillis; 101 102 public int getScanMode() { 103 return mScanMode; 104 } 105 106 public int getCallbackType() { 107 return mCallbackType; 108 } 109 110 public int getScanResultType() { 111 return mScanResultType; 112 } 113 114 /** 115 * Returns report delay timestamp based on the device clock. 116 */ 117 public long getReportDelayMillis() { 118 return mReportDelayMillis; 119 } 120 121 private ScanSettings(int scanMode, int callbackType, int scanResultType, 122 long reportDelayMillis) { 123 mScanMode = scanMode; 124 mCallbackType = callbackType; 125 mScanResultType = scanResultType; 126 mReportDelayMillis = reportDelayMillis; 127 } 128 129 private ScanSettings(Parcel in) { 130 mScanMode = in.readInt(); 131 mCallbackType = in.readInt(); 132 mScanResultType = in.readInt(); 133 mReportDelayMillis = in.readLong(); 134 } 135 136 @Override 137 public void writeToParcel(Parcel dest, int flags) { 138 dest.writeInt(mScanMode); 139 dest.writeInt(mCallbackType); 140 dest.writeInt(mScanResultType); 141 dest.writeLong(mReportDelayMillis); 142 } 143 144 @Override 145 public int describeContents() { 146 return 0; 147 } 148 149 public static final Parcelable.Creator<ScanSettings> 150 CREATOR = new Creator<ScanSettings>() { 151 @Override 152 public ScanSettings[] newArray(int size) { 153 return new ScanSettings[size]; 154 } 155 156 @Override 157 public ScanSettings createFromParcel(Parcel in) { 158 return new ScanSettings(in); 159 } 160 }; 161 162 /** 163 * Builder for {@link ScanSettings}. 164 */ 165 public static final class Builder { 166 private int mScanMode = SCAN_MODE_LOW_POWER; 167 private int mCallbackType = CALLBACK_TYPE_ALL_MATCHES; 168 private int mScanResultType = SCAN_RESULT_TYPE_FULL; 169 private long mReportDelayMillis = 0; 170 171 /** 172 * Set scan mode for Bluetooth LE scan. 173 * 174 * @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER}, 175 * {@link ScanSettings#SCAN_MODE_BALANCED} or 176 * {@link ScanSettings#SCAN_MODE_LOW_LATENCY}. 177 * @throws IllegalArgumentException If the {@code scanMode} is invalid. 178 */ 179 public Builder setScanMode(int scanMode) { 180 if (scanMode < SCAN_MODE_LOW_POWER || scanMode > SCAN_MODE_LOW_LATENCY) { 181 throw new IllegalArgumentException("invalid scan mode " + scanMode); 182 } 183 mScanMode = scanMode; 184 return this; 185 } 186 187 /** 188 * Set callback type for Bluetooth LE scan. 189 * 190 * @param callbackType The callback type flags for the scan. 191 * @throws IllegalArgumentException If the {@code callbackType} is invalid. 192 * @hide 193 */ 194 @SystemApi 195 public Builder setCallbackType(int callbackType) { 196 197 if (!isValidCallbackType(callbackType)) { 198 throw new IllegalArgumentException("invalid callback type - " + callbackType); 199 } 200 mCallbackType = callbackType; 201 return this; 202 } 203 204 // Returns true if the callbackType is valid. 205 private boolean isValidCallbackType(int callbackType) { 206 if (callbackType == CALLBACK_TYPE_ALL_MATCHES || 207 callbackType == CALLBACK_TYPE_FIRST_MATCH || 208 callbackType == CALLBACK_TYPE_MATCH_LOST) { 209 return true; 210 } 211 return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST); 212 } 213 214 /** 215 * Set scan result type for Bluetooth LE scan. 216 * 217 * @param scanResultType Type for scan result, could be either 218 * {@link ScanSettings#SCAN_RESULT_TYPE_FULL} or 219 * {@link ScanSettings#SCAN_RESULT_TYPE_ABBREVIATED}. 220 * @throws IllegalArgumentException If the {@code scanResultType} is invalid. 221 * @hide 222 */ 223 @SystemApi 224 public Builder setScanResultType(int scanResultType) { 225 if (scanResultType < SCAN_RESULT_TYPE_FULL 226 || scanResultType > SCAN_RESULT_TYPE_ABBREVIATED) { 227 throw new IllegalArgumentException( 228 "invalid scanResultType - " + scanResultType); 229 } 230 mScanResultType = scanResultType; 231 return this; 232 } 233 234 /** 235 * Set report delay timestamp for Bluetooth LE scan. 236 * 237 * @param reportDelayMillis Delay of report in milliseconds. Set to 0 to be notified of 238 * results immediately. Values > 0 causes the scan results to be queued up and 239 * delivered after the requested delay or when the internal buffers fill up. 240 * @throws IllegalArgumentException If {@code reportDelayMillis} < 0. 241 */ 242 public Builder setReportDelay(long reportDelayMillis) { 243 if (reportDelayMillis < 0) { 244 throw new IllegalArgumentException("reportDelay must be > 0"); 245 } 246 mReportDelayMillis = reportDelayMillis; 247 return this; 248 } 249 250 /** 251 * Build {@link ScanSettings}. 252 */ 253 public ScanSettings build() { 254 return new ScanSettings(mScanMode, mCallbackType, mScanResultType, 255 mReportDelayMillis); 256 } 257 } 258 } 259