1 /* 2 * Copyright (C) 2022 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 static java.util.Objects.requireNonNull; 20 21 import android.annotation.IntDef; 22 import android.annotation.IntRange; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.SystemApi; 26 import android.bluetooth.BluetoothDevice; 27 import android.bluetooth.le.DistanceMeasurementMethod.DistanceMeasurementMethodId; 28 import android.os.Parcel; 29 import android.os.Parcelable; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 34 /** 35 * The {@link DistanceMeasurementParams} provide a way to adjust distance measurement preferences. 36 * Use {@link DistanceMeasurementParams.Builder} to create an instance of this class. 37 * 38 * @hide 39 */ 40 @SystemApi 41 public final class DistanceMeasurementParams implements Parcelable { 42 43 /** @hide */ 44 @Retention(RetentionPolicy.SOURCE) 45 @IntDef(value = {REPORT_FREQUENCY_LOW, REPORT_FREQUENCY_MEDIUM, REPORT_FREQUENCY_HIGH}) 46 @interface ReportFrequency {} 47 48 /** 49 * Perform distance measurement in low frequency. This is the default frequency as it consumes 50 * the least power. 51 * 52 * @hide 53 */ 54 @SystemApi public static final int REPORT_FREQUENCY_LOW = 0; 55 56 /** 57 * Perform distance measurement in medium frequency. Provides a good trade-off between report 58 * frequency and power consumption. 59 * 60 * @hide 61 */ 62 @SystemApi public static final int REPORT_FREQUENCY_MEDIUM = 1; 63 64 /** 65 * Perform distance measurement in high frequency. It's recommended to only use this mode when 66 * the application is running in the foreground. 67 * 68 * @hide 69 */ 70 @SystemApi public static final int REPORT_FREQUENCY_HIGH = 2; 71 72 private static final int REPORT_DURATION_MAX = Integer.MAX_VALUE; 73 private static final int REPORT_DURATION_DEFAULT = REPORT_DURATION_MAX; 74 75 private final BluetoothDevice mDevice; 76 private final int mDuration; 77 private final int mFrequency; 78 private final int mMethodId; 79 private final ChannelSoundingParams mChannelSoundingParams; 80 81 /** @hide */ DistanceMeasurementParams( @onNull BluetoothDevice device, int duration, int frequency, int methodId, ChannelSoundingParams channelSoundingParams)82 public DistanceMeasurementParams( 83 @NonNull BluetoothDevice device, 84 int duration, 85 int frequency, 86 int methodId, 87 ChannelSoundingParams channelSoundingParams) { 88 mDevice = requireNonNull(device); 89 mDuration = duration; 90 mFrequency = frequency; 91 mMethodId = methodId; 92 mChannelSoundingParams = channelSoundingParams; 93 } 94 95 /** 96 * Returns device of this DistanceMeasurementParams. 97 * 98 * @hide 99 */ 100 @SystemApi getDevice()101 public @NonNull BluetoothDevice getDevice() { 102 return mDevice; 103 } 104 105 /** 106 * Returns duration in seconds of this DistanceMeasurementParams. Once the distance measurement 107 * successfully started, the Bluetooth process will keep reporting the measurement result until 108 * this time has been reached or the session is explicitly stopped with {@link 109 * DistanceMeasurementSession#stopSession} 110 * 111 * @hide 112 */ 113 @SystemApi getDurationSeconds()114 public @IntRange(from = 0) int getDurationSeconds() { 115 return mDuration; 116 } 117 118 /** 119 * Returns frequency of this DistanceMeasurementParams. The Bluetooth process uses this value to 120 * determine report frequency of the measurement result. 121 * 122 * @hide 123 */ 124 @SystemApi getFrequency()125 public @ReportFrequency int getFrequency() { 126 return mFrequency; 127 } 128 129 /** 130 * Returns method id of this DistanceMeasurementParams. 131 * 132 * @hide 133 */ 134 @SystemApi getMethodId()135 public @DistanceMeasurementMethodId int getMethodId() { 136 return mMethodId; 137 } 138 139 /** 140 * Returns {@link ChannelSoundingParams} of this DistanceMeasurementParams. 141 * 142 * @hide 143 */ 144 @SystemApi getChannelSoundingParams()145 public @Nullable ChannelSoundingParams getChannelSoundingParams() { 146 return mChannelSoundingParams; 147 } 148 149 /** 150 * Get the default duration in seconds of the parameter. 151 * 152 * @hide 153 */ 154 @SystemApi getDefaultDurationSeconds()155 public static int getDefaultDurationSeconds() { 156 return REPORT_DURATION_DEFAULT; 157 } 158 159 /** 160 * Get the maximum duration in seconds that can be set for the parameter. 161 * 162 * @hide 163 */ 164 @SystemApi getMaxDurationSeconds()165 public static int getMaxDurationSeconds() { 166 return REPORT_DURATION_MAX; 167 } 168 169 /** 170 * {@inheritDoc} 171 * 172 * @hide 173 */ 174 @Override describeContents()175 public int describeContents() { 176 return 0; 177 } 178 179 /** 180 * {@inheritDoc} 181 * 182 * @hide 183 */ 184 @Override writeToParcel(Parcel out, int flags)185 public void writeToParcel(Parcel out, int flags) { 186 mDevice.writeToParcel(out, flags); 187 out.writeInt(mDuration); 188 out.writeInt(mFrequency); 189 out.writeInt(mMethodId); 190 191 out.writeInt(mChannelSoundingParams == null ? 0 : 1); 192 if (mChannelSoundingParams != null) { 193 mChannelSoundingParams.writeToParcel(out, flags); 194 } 195 } 196 197 /** A {@link Parcelable.Creator} to create {@link DistanceMeasurementParams} from parcel. */ 198 public static final @NonNull Parcelable.Creator<DistanceMeasurementParams> CREATOR = 199 new Parcelable.Creator<DistanceMeasurementParams>() { 200 @Override 201 public @NonNull DistanceMeasurementParams createFromParcel(@NonNull Parcel in) { 202 Builder builder = new Builder(BluetoothDevice.CREATOR.createFromParcel(in)); 203 builder.setDurationSeconds(in.readInt()); 204 builder.setFrequency(in.readInt()); 205 builder.setMethodId(in.readInt()); 206 if (in.readInt() == 1) { 207 builder.setChannelSoundingParams( 208 ChannelSoundingParams.CREATOR.createFromParcel(in)); 209 } 210 return builder.build(); 211 } 212 213 @Override 214 public @NonNull DistanceMeasurementParams[] newArray(int size) { 215 return new DistanceMeasurementParams[size]; 216 } 217 }; 218 219 /** 220 * Builder for {@link DistanceMeasurementParams}. 221 * 222 * @hide 223 */ 224 @SystemApi 225 public static final class Builder { 226 private BluetoothDevice mDevice = null; 227 private int mDuration = REPORT_DURATION_DEFAULT; 228 private int mFrequency = REPORT_FREQUENCY_LOW; 229 private int mMethodId = DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI; 230 private ChannelSoundingParams mChannelSoundingParams = null; 231 232 /** 233 * Constructor of the Builder. 234 * 235 * @param device the remote device for the distance measurement 236 */ Builder(@onNull BluetoothDevice device)237 public Builder(@NonNull BluetoothDevice device) { 238 mDevice = requireNonNull(device); 239 } 240 241 /** 242 * Set duration in seconds for the DistanceMeasurementParams. Once the distance measurement 243 * successfully started, the Bluetooth process will keep reporting the measurement result 244 * until this time has been reached or the session is explicitly stopped with {@link 245 * DistanceMeasurementSession#stopSession}. 246 * 247 * @param duration duration in seconds of this DistanceMeasurementParams 248 * @return the same Builder instance 249 * @throws IllegalArgumentException if duration greater than {@link 250 * DistanceMeasurementParams#getMaxDurationSeconds()} or less than zero. 251 * @hide 252 */ 253 @SystemApi setDurationSeconds(@ntRangefrom = 0) int duration)254 public @NonNull Builder setDurationSeconds(@IntRange(from = 0) int duration) { 255 if (duration < 0 || duration > getMaxDurationSeconds()) { 256 throw new IllegalArgumentException("illegal duration " + duration); 257 } 258 mDuration = duration; 259 return this; 260 } 261 262 /** 263 * Set frequency for the DistanceMeasurementParams. The Bluetooth process uses this value to 264 * determine report frequency of the measurement result. 265 * 266 * @param frequency frequency of this DistanceMeasurementParams 267 * @return the same Builder instance 268 * @hide 269 */ 270 @SystemApi setFrequency(@eportFrequency int frequency)271 public @NonNull Builder setFrequency(@ReportFrequency int frequency) { 272 switch (frequency) { 273 case REPORT_FREQUENCY_LOW: 274 case REPORT_FREQUENCY_MEDIUM: 275 case REPORT_FREQUENCY_HIGH: 276 mFrequency = frequency; 277 break; 278 default: 279 throw new IllegalArgumentException("unknown frequency " + frequency); 280 } 281 return this; 282 } 283 284 /** 285 * Set method id for the DistanceMeasurementParams. 286 * 287 * @param methodId method id of this DistanceMeasurementParams 288 * @return the same Builder instance 289 * @hide 290 */ 291 @SystemApi setMethodId(@istanceMeasurementMethodId int methodId)292 public @NonNull Builder setMethodId(@DistanceMeasurementMethodId int methodId) { 293 switch (methodId) { 294 case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO: 295 case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: 296 case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: 297 mMethodId = methodId; 298 break; 299 default: 300 throw new IllegalArgumentException("unknown method id " + methodId); 301 } 302 return this; 303 } 304 305 /** 306 * Set {@link ChannelSoundingParams} for the DistanceMeasurementParams. 307 * 308 * @param channelSoundingParams parameters for Channel Sounding 309 * @return the same Builder instance 310 * @hide 311 */ 312 @SystemApi setChannelSoundingParams( @onNull ChannelSoundingParams channelSoundingParams)313 public @NonNull Builder setChannelSoundingParams( 314 @NonNull ChannelSoundingParams channelSoundingParams) { 315 mChannelSoundingParams = channelSoundingParams; 316 return this; 317 } 318 319 /** 320 * Build the {@link DistanceMeasurementParams} object. 321 * 322 * @hide 323 */ 324 @SystemApi build()325 public @NonNull DistanceMeasurementParams build() { 326 return new DistanceMeasurementParams( 327 mDevice, mDuration, mFrequency, mMethodId, mChannelSoundingParams); 328 } 329 } 330 } 331