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 android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.SystemApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import com.android.bluetooth.flags.Flags; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.Objects; 31 32 /** 33 * Method of distance measurement. A list of this class will be returned by {@link 34 * DistanceMeasurementManager#getSupportedMethods()} to indicate the supported methods and their 35 * capability about angle measurement. 36 * 37 * @hide 38 */ 39 @SystemApi 40 public final class DistanceMeasurementMethod implements Parcelable { 41 42 private final int mId; 43 private final boolean mIsAzimuthAngleSupported; 44 private final boolean mIsAltitudeAngleSupported; 45 46 /** @hide */ 47 @Retention(RetentionPolicy.SOURCE) 48 @IntDef( 49 value = { 50 DISTANCE_MEASUREMENT_METHOD_AUTO, 51 DISTANCE_MEASUREMENT_METHOD_RSSI, 52 DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING 53 }) 54 @interface DistanceMeasurementMethodId {} 55 56 /** 57 * Choose method automatically, Bluetooth will use the most accurate method that local device 58 * supported to measurement distance. 59 * 60 * @hide 61 */ 62 @SystemApi public static final int DISTANCE_MEASUREMENT_METHOD_AUTO = 0; 63 64 /** 65 * Use remote RSSI and transmit power to measure the distance. 66 * 67 * @hide 68 */ 69 @SystemApi public static final int DISTANCE_MEASUREMENT_METHOD_RSSI = 1; 70 71 /** 72 * Use Channel Sounding to measure the distance. 73 * 74 * @hide 75 */ 76 @SystemApi 77 public static final int DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING = 2; 78 DistanceMeasurementMethod( int id, boolean isAzimuthAngleSupported, boolean isAltitudeAngleSupported)79 private DistanceMeasurementMethod( 80 int id, boolean isAzimuthAngleSupported, boolean isAltitudeAngleSupported) { 81 mId = id; 82 mIsAzimuthAngleSupported = isAzimuthAngleSupported; 83 mIsAltitudeAngleSupported = isAltitudeAngleSupported; 84 } 85 86 /** 87 * Id of the method used for {@link DistanceMeasurementParams.Builder#setMethod(int)} 88 * 89 * @return id of the method 90 * @deprecated use {@link #getMethodId} instead. 91 * @hide 92 */ 93 @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING_25Q2_APIS) 94 @Deprecated 95 @SystemApi getId()96 public double getId() { 97 return mId; 98 } 99 100 /** 101 * Id of the method used for {@link DistanceMeasurementParams.Builder#setMethodId(int)} 102 * 103 * @return ID of the measurement method 104 * @hide 105 */ 106 @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING_25Q2_APIS) 107 @SystemApi getMethodId()108 public @DistanceMeasurementMethodId int getMethodId() { 109 return mId; 110 } 111 112 /** 113 * Checks whether the azimuth angle is supported for this method. 114 * 115 * @return true if azimuth angle is supported, false otherwise 116 * @hide 117 */ 118 @SystemApi isAzimuthAngleSupported()119 public boolean isAzimuthAngleSupported() { 120 return mIsAzimuthAngleSupported; 121 } 122 123 /** 124 * Checks whether the altitude angle is supported for this method. 125 * 126 * @return true if altitude angle is supported, false otherwise 127 * @hide 128 */ 129 @SystemApi isAltitudeAngleSupported()130 public boolean isAltitudeAngleSupported() { 131 return mIsAltitudeAngleSupported; 132 } 133 134 /** 135 * {@inheritDoc} 136 * 137 * @hide 138 */ 139 @Override describeContents()140 public int describeContents() { 141 return 0; 142 } 143 144 /** 145 * {@inheritDoc} 146 * 147 * @hide 148 */ 149 @Override writeToParcel(Parcel out, int flags)150 public void writeToParcel(Parcel out, int flags) { 151 out.writeInt(mId); 152 out.writeBoolean(mIsAzimuthAngleSupported); 153 out.writeBoolean(mIsAltitudeAngleSupported); 154 } 155 156 /** 157 * @hide * 158 */ 159 @Override toString()160 public String toString() { 161 return "DistanceMeasurementMethod[" 162 + "id: " 163 + mId 164 + ", isAzimuthAngleSupported: " 165 + mIsAzimuthAngleSupported 166 + ", isAltitudeAngleSupported: " 167 + mIsAltitudeAngleSupported 168 + "]"; 169 } 170 171 @Override equals(Object o)172 public boolean equals(Object o) { 173 if (o == null) return false; 174 175 if (!(o instanceof DistanceMeasurementMethod)) return false; 176 177 final DistanceMeasurementMethod u = (DistanceMeasurementMethod) o; 178 return mId == u.mId; 179 } 180 181 @Override hashCode()182 public int hashCode() { 183 return Objects.hash(mId); 184 } 185 186 /** A {@link Parcelable.Creator} to create {@link DistanceMeasurementMethod} from parcel. */ 187 public static final @NonNull Parcelable.Creator<DistanceMeasurementMethod> CREATOR = 188 new Parcelable.Creator<DistanceMeasurementMethod>() { 189 @Override 190 public @NonNull DistanceMeasurementMethod createFromParcel(@NonNull Parcel in) { 191 return new Builder(in.readInt()) 192 .setAzimuthAngleSupported(in.readBoolean()) 193 .setAltitudeAngleSupported(in.readBoolean()) 194 .build(); 195 } 196 197 @Override 198 public @NonNull DistanceMeasurementMethod[] newArray(int size) { 199 return new DistanceMeasurementMethod[size]; 200 } 201 }; 202 203 /** 204 * Builder for {@link DistanceMeasurementMethod}. 205 * 206 * @hide 207 */ 208 @SystemApi 209 public static final class Builder { 210 private final int mId; 211 private boolean mIsAzimuthAngleSupported = false; 212 private boolean mIsAltitudeAngleSupported = false; 213 214 /** 215 * Constructor of the Builder. 216 * 217 * @param id id of the method 218 */ Builder(@istanceMeasurementMethodId int id)219 public Builder(@DistanceMeasurementMethodId int id) { 220 switch (id) { 221 case DISTANCE_MEASUREMENT_METHOD_AUTO: 222 case DISTANCE_MEASUREMENT_METHOD_RSSI: 223 case DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: 224 mId = id; 225 break; 226 default: 227 throw new IllegalArgumentException("unknown method id " + id); 228 } 229 } 230 231 /** 232 * Set if azimuth angle supported or not. 233 * 234 * @param supported {@code true} if azimuth angle supported, {@code false} otherwise 235 * @hide 236 */ 237 @SystemApi 238 @NonNull setAzimuthAngleSupported(boolean supported)239 public Builder setAzimuthAngleSupported(boolean supported) { 240 mIsAzimuthAngleSupported = supported; 241 return this; 242 } 243 244 /** 245 * Set if altitude angle supported or not. 246 * 247 * @param supported {@code true} if altitude angle supported, {@code false} otherwise 248 * @hide 249 */ 250 @SystemApi 251 @NonNull setAltitudeAngleSupported(boolean supported)252 public Builder setAltitudeAngleSupported(boolean supported) { 253 mIsAltitudeAngleSupported = supported; 254 return this; 255 } 256 257 /** 258 * Builds the {@link DistanceMeasurementMethod} object. 259 * 260 * @hide 261 */ 262 @SystemApi 263 @NonNull build()264 public DistanceMeasurementMethod build() { 265 return new DistanceMeasurementMethod( 266 mId, mIsAzimuthAngleSupported, mIsAltitudeAngleSupported); 267 } 268 } 269 } 270