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.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 @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) 77 @SystemApi 78 public static final int DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING = 2; 79 DistanceMeasurementMethod( int id, boolean isAzimuthAngleSupported, boolean isAltitudeAngleSupported)80 private DistanceMeasurementMethod( 81 int id, boolean isAzimuthAngleSupported, boolean isAltitudeAngleSupported) { 82 mId = id; 83 mIsAzimuthAngleSupported = isAzimuthAngleSupported; 84 mIsAltitudeAngleSupported = isAltitudeAngleSupported; 85 } 86 87 /** 88 * Id of the method used for {@link DistanceMeasurementParams.Builder#setMethod(int)} 89 * 90 * @return id of the method 91 * @hide 92 */ 93 @SystemApi getId()94 public @DistanceMeasurementMethodId double getId() { 95 return mId; 96 } 97 98 /** 99 * Checks whether the azimuth angle is supported for this method. 100 * 101 * @return true if azimuth angle is supported, false otherwise 102 * @hide 103 */ 104 @SystemApi isAzimuthAngleSupported()105 public boolean isAzimuthAngleSupported() { 106 return mIsAzimuthAngleSupported; 107 } 108 109 /** 110 * Checks whether the altitude angle is supported for this method. 111 * 112 * @return true if altitude angle is supported, false otherwise 113 * @hide 114 */ 115 @SystemApi isAltitudeAngleSupported()116 public boolean isAltitudeAngleSupported() { 117 return mIsAltitudeAngleSupported; 118 } 119 120 /** 121 * {@inheritDoc} 122 * 123 * @hide 124 */ 125 @Override describeContents()126 public int describeContents() { 127 return 0; 128 } 129 130 /** 131 * {@inheritDoc} 132 * 133 * @hide 134 */ 135 @Override writeToParcel(Parcel out, int flags)136 public void writeToParcel(Parcel out, int flags) { 137 out.writeInt(mId); 138 out.writeBoolean(mIsAzimuthAngleSupported); 139 out.writeBoolean(mIsAltitudeAngleSupported); 140 } 141 142 /** 143 * @hide * 144 */ 145 @Override toString()146 public String toString() { 147 return "DistanceMeasurementMethod[" 148 + "id: " 149 + mId 150 + ", isAzimuthAngleSupported: " 151 + mIsAzimuthAngleSupported 152 + ", isAltitudeAngleSupported: " 153 + mIsAltitudeAngleSupported 154 + "]"; 155 } 156 157 @Override equals(Object o)158 public boolean equals(Object o) { 159 if (o == null) return false; 160 161 if (!(o instanceof DistanceMeasurementMethod)) return false; 162 163 final DistanceMeasurementMethod u = (DistanceMeasurementMethod) o; 164 165 if (mId != u.getId()) { 166 return false; 167 } 168 169 return true; 170 } 171 172 @Override hashCode()173 public int hashCode() { 174 return Objects.hash(mId); 175 } 176 177 /** A {@link Parcelable.Creator} to create {@link DistanceMeasurementMethod} from parcel. */ 178 public static final @NonNull Parcelable.Creator<DistanceMeasurementMethod> CREATOR = 179 new Parcelable.Creator<DistanceMeasurementMethod>() { 180 @Override 181 public @NonNull DistanceMeasurementMethod createFromParcel(@NonNull Parcel in) { 182 return new Builder(in.readInt()) 183 .setAzimuthAngleSupported(in.readBoolean()) 184 .setAltitudeAngleSupported(in.readBoolean()) 185 .build(); 186 } 187 188 @Override 189 public @NonNull DistanceMeasurementMethod[] newArray(int size) { 190 return new DistanceMeasurementMethod[size]; 191 } 192 }; 193 194 /** 195 * Builder for {@link DistanceMeasurementMethod}. 196 * 197 * @hide 198 */ 199 @SystemApi 200 public static final class Builder { 201 private int mId; 202 private boolean mIsAzimuthAngleSupported = false; 203 private boolean mIsAltitudeAngleSupported = false; 204 205 /** 206 * Constructor of the Builder. 207 * 208 * @param id id of the method 209 */ Builder(@istanceMeasurementMethodId int id)210 public Builder(@DistanceMeasurementMethodId int id) { 211 switch (id) { 212 case DISTANCE_MEASUREMENT_METHOD_AUTO: 213 case DISTANCE_MEASUREMENT_METHOD_RSSI: 214 case DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: 215 mId = id; 216 break; 217 default: 218 throw new IllegalArgumentException("unknown method id " + id); 219 } 220 } 221 222 /** 223 * Set if azimuth angle supported or not. 224 * 225 * @param supported {@code true} if azimuth angle supported, {@code false} otherwise 226 * @hide 227 */ 228 @SystemApi 229 @NonNull setAzimuthAngleSupported(boolean supported)230 public Builder setAzimuthAngleSupported(boolean supported) { 231 mIsAzimuthAngleSupported = supported; 232 return this; 233 } 234 235 /** 236 * Set if altitude angle supported or not. 237 * 238 * @param supported {@code true} if altitude angle supported, {@code false} otherwise 239 * @hide 240 */ 241 @SystemApi 242 @NonNull setAltitudeAngleSupported(boolean supported)243 public Builder setAltitudeAngleSupported(boolean supported) { 244 mIsAltitudeAngleSupported = supported; 245 return this; 246 } 247 248 /** 249 * Builds the {@link DistanceMeasurementMethod} object. 250 * 251 * @hide 252 */ 253 @SystemApi 254 @NonNull build()255 public DistanceMeasurementMethod build() { 256 return new DistanceMeasurementMethod( 257 mId, mIsAzimuthAngleSupported, mIsAltitudeAngleSupported); 258 } 259 } 260 } 261