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