1 /* 2 * Copyright (C) 2021 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.location.provider; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 24 import com.android.internal.util.Preconditions; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * Location provider properties. 32 */ 33 public final class ProviderProperties implements Parcelable { 34 35 /** 36 * A constant indicating low power usage. 37 */ 38 public static final int POWER_USAGE_LOW = 1; 39 40 /** 41 * A constant indicating a medium power usage. 42 */ 43 public static final int POWER_USAGE_MEDIUM = 2; 44 45 /** 46 * A constant indicating high power usage. 47 */ 48 public static final int POWER_USAGE_HIGH = 3; 49 50 /** @hide */ 51 @Retention(RetentionPolicy.SOURCE) 52 @IntDef(prefix = "POWER_USAGE_", value = {POWER_USAGE_LOW, POWER_USAGE_MEDIUM, 53 POWER_USAGE_HIGH}) 54 public @interface PowerUsage {} 55 56 /** 57 * A constant indicating a finer location accuracy. 58 */ 59 public static final int ACCURACY_FINE = 1; 60 61 /** 62 * A constant indicating a coarser location accuracy. 63 */ 64 public static final int ACCURACY_COARSE = 2; 65 66 /** @hide */ 67 @Retention(RetentionPolicy.SOURCE) 68 @IntDef(prefix = "ACCURACY_", value = {ACCURACY_FINE, ACCURACY_COARSE}) 69 public @interface Accuracy {} 70 71 private final boolean mHasNetworkRequirement; 72 private final boolean mHasSatelliteRequirement; 73 private final boolean mHasCellRequirement; 74 private final boolean mHasMonetaryCost; 75 private final boolean mHasAltitudeSupport; 76 private final boolean mHasSpeedSupport; 77 private final boolean mHasBearingSupport; 78 private final @PowerUsage int mPowerUsage; 79 private final @Accuracy int mAccuracy; 80 ProviderProperties(boolean hasNetworkRequirement, boolean hasSatelliteRequirement, boolean hasCellRequirement, boolean hasMonetaryCost, boolean hasAltitudeSupport, boolean hasSpeedSupport, boolean hasBearingSupport, @PowerUsage int powerUsage, @Accuracy int accuracy)81 private ProviderProperties(boolean hasNetworkRequirement, boolean hasSatelliteRequirement, 82 boolean hasCellRequirement, boolean hasMonetaryCost, boolean hasAltitudeSupport, 83 boolean hasSpeedSupport, boolean hasBearingSupport, 84 @PowerUsage int powerUsage, @Accuracy int accuracy) { 85 mHasNetworkRequirement = hasNetworkRequirement; 86 mHasSatelliteRequirement = hasSatelliteRequirement; 87 mHasCellRequirement = hasCellRequirement; 88 mHasMonetaryCost = hasMonetaryCost; 89 mHasAltitudeSupport = hasAltitudeSupport; 90 mHasSpeedSupport = hasSpeedSupport; 91 mHasBearingSupport = hasBearingSupport; 92 mPowerUsage = powerUsage; 93 mAccuracy = accuracy; 94 } 95 96 /** 97 * True if provider requires access to a data network (e.g., the Internet). 98 */ hasNetworkRequirement()99 public boolean hasNetworkRequirement() { 100 return mHasNetworkRequirement; 101 } 102 103 /** 104 * True if the provider requires access to a satellite-based positioning system (e.g., GPS). 105 */ hasSatelliteRequirement()106 public boolean hasSatelliteRequirement() { 107 return mHasSatelliteRequirement; 108 } 109 110 /** 111 * True if the provider requires access to a cellular network (e.g., for cell tower IDs). 112 */ hasCellRequirement()113 public boolean hasCellRequirement() { 114 return mHasCellRequirement; 115 } 116 117 /** 118 * True if this provider may result in a monetary charge to the user. Network usage is not 119 * considered a monetary cost. 120 */ hasMonetaryCost()121 public boolean hasMonetaryCost() { 122 return mHasMonetaryCost; 123 } 124 125 /** 126 * True if the provider is able to provide altitude under at least some conditions. 127 */ hasAltitudeSupport()128 public boolean hasAltitudeSupport() { 129 return mHasAltitudeSupport; 130 } 131 132 /** 133 * True if the provider is able to provide speed under at least some conditions. 134 */ hasSpeedSupport()135 public boolean hasSpeedSupport() { 136 return mHasSpeedSupport; 137 } 138 139 /** 140 * True if the provider is able to provide bearing under at least some conditions. 141 */ hasBearingSupport()142 public boolean hasBearingSupport() { 143 return mHasBearingSupport; 144 } 145 146 /** 147 * Power usage for this provider. 148 */ getPowerUsage()149 public @PowerUsage int getPowerUsage() { 150 return mPowerUsage; 151 } 152 153 /** 154 * Rough location accuracy for this provider, primarily with respect to horizontal location 155 * accuracy. 156 */ getAccuracy()157 public @Accuracy int getAccuracy() { 158 return mAccuracy; 159 } 160 161 public static final @NonNull Creator<ProviderProperties> CREATOR = 162 new Creator<ProviderProperties>() { 163 @Override 164 public ProviderProperties createFromParcel(Parcel in) { 165 return new ProviderProperties( 166 /* hasNetworkRequirement= */ in.readBoolean(), 167 /* hasSatelliteRequirement= */ in.readBoolean(), 168 /* hasCellRequirement= */ in.readBoolean(), 169 /* hasMonetaryCost= */ in.readBoolean(), 170 /* hasAltitudeSupport= */ in.readBoolean(), 171 /* hasSpeedSupport= */ in.readBoolean(), 172 /* hasBearingSupport= */ in.readBoolean(), 173 /* powerUsage= */ in.readInt(), 174 /* accuracy= */ in.readInt()); 175 } 176 177 @Override 178 public ProviderProperties[] newArray(int size) { 179 return new ProviderProperties[size]; 180 } 181 }; 182 183 @Override describeContents()184 public int describeContents() { 185 return 0; 186 } 187 188 @Override writeToParcel(@onNull Parcel parcel, int flags)189 public void writeToParcel(@NonNull Parcel parcel, int flags) { 190 parcel.writeBoolean(mHasNetworkRequirement); 191 parcel.writeBoolean(mHasSatelliteRequirement); 192 parcel.writeBoolean(mHasCellRequirement); 193 parcel.writeBoolean(mHasMonetaryCost); 194 parcel.writeBoolean(mHasAltitudeSupport); 195 parcel.writeBoolean(mHasSpeedSupport); 196 parcel.writeBoolean(mHasBearingSupport); 197 parcel.writeInt(mPowerUsage); 198 parcel.writeInt(mAccuracy); 199 } 200 201 @Override equals(Object o)202 public boolean equals(Object o) { 203 if (this == o) { 204 return true; 205 } 206 if (!(o instanceof ProviderProperties)) { 207 return false; 208 } 209 ProviderProperties that = (ProviderProperties) o; 210 return mHasNetworkRequirement == that.mHasNetworkRequirement 211 && mHasSatelliteRequirement == that.mHasSatelliteRequirement 212 && mHasCellRequirement == that.mHasCellRequirement 213 && mHasMonetaryCost == that.mHasMonetaryCost 214 && mHasAltitudeSupport == that.mHasAltitudeSupport 215 && mHasSpeedSupport == that.mHasSpeedSupport 216 && mHasBearingSupport == that.mHasBearingSupport 217 && mPowerUsage == that.mPowerUsage 218 && mAccuracy == that.mAccuracy; 219 } 220 221 @Override hashCode()222 public int hashCode() { 223 return Objects.hash(mHasNetworkRequirement, mHasSatelliteRequirement, mHasCellRequirement, 224 mHasMonetaryCost, mHasAltitudeSupport, mHasSpeedSupport, mHasBearingSupport, 225 mPowerUsage, mAccuracy); 226 } 227 228 @Override toString()229 public String toString() { 230 StringBuilder b = new StringBuilder("ProviderProperties["); 231 b.append("powerUsage=").append(powerToString(mPowerUsage)).append(", "); 232 b.append("accuracy=").append(accuracyToString(mAccuracy)); 233 if (mHasNetworkRequirement || mHasSatelliteRequirement || mHasCellRequirement) { 234 b.append(", requires="); 235 if (mHasNetworkRequirement) { 236 b.append("network,"); 237 } 238 if (mHasSatelliteRequirement) { 239 b.append("satellite,"); 240 } 241 if (mHasCellRequirement) { 242 b.append("cell,"); 243 } 244 b.setLength(b.length() - 1); 245 } 246 if (mHasMonetaryCost) { 247 b.append(", hasMonetaryCost"); 248 } 249 if (mHasBearingSupport || mHasSpeedSupport || mHasAltitudeSupport) { 250 b.append(", supports=["); 251 if (mHasBearingSupport) { 252 b.append("bearing,"); 253 } 254 if (mHasSpeedSupport) { 255 b.append("speed,"); 256 } 257 if (mHasAltitudeSupport) { 258 b.append("altitude,"); 259 } 260 b.setLength(b.length() - 1); 261 b.append("]"); 262 } 263 b.append("]"); 264 return b.toString(); 265 } 266 powerToString(@owerUsage int power)267 private static String powerToString(@PowerUsage int power) { 268 switch (power) { 269 case POWER_USAGE_LOW: 270 return "Low"; 271 case POWER_USAGE_MEDIUM: 272 return "Medium"; 273 case POWER_USAGE_HIGH: 274 return "High"; 275 default: 276 throw new AssertionError(); 277 } 278 } 279 accuracyToString(@ccuracy int accuracy)280 private static String accuracyToString(@Accuracy int accuracy) { 281 switch (accuracy) { 282 case ACCURACY_COARSE: 283 return "Coarse"; 284 case ACCURACY_FINE: 285 return "Fine"; 286 default: 287 throw new AssertionError(); 288 } 289 } 290 291 /** 292 * Builder for ProviderProperties. 293 */ 294 public static final class Builder { 295 296 private boolean mHasNetworkRequirement; 297 private boolean mHasSatelliteRequirement; 298 private boolean mHasCellRequirement; 299 private boolean mHasMonetaryCost; 300 private boolean mHasAltitudeSupport; 301 private boolean mHasSpeedSupport; 302 private boolean mHasBearingSupport; 303 private @PowerUsage int mPowerUsage; 304 private @Accuracy int mAccuracy; 305 Builder()306 public Builder() { 307 mHasNetworkRequirement = false; 308 mHasSatelliteRequirement = false; 309 mHasCellRequirement = false; 310 mHasMonetaryCost = false; 311 mHasAltitudeSupport = false; 312 mHasSpeedSupport = false; 313 mHasBearingSupport = false; 314 mPowerUsage = POWER_USAGE_HIGH; 315 mAccuracy = ACCURACY_COARSE; 316 } 317 Builder(@onNull ProviderProperties providerProperties)318 public Builder(@NonNull ProviderProperties providerProperties) { 319 mHasNetworkRequirement = providerProperties.mHasNetworkRequirement; 320 mHasSatelliteRequirement = providerProperties.mHasSatelliteRequirement; 321 mHasCellRequirement = providerProperties.mHasCellRequirement; 322 mHasMonetaryCost = providerProperties.mHasMonetaryCost; 323 mHasAltitudeSupport = providerProperties.mHasAltitudeSupport; 324 mHasSpeedSupport = providerProperties.mHasSpeedSupport; 325 mHasBearingSupport = providerProperties.mHasBearingSupport; 326 mPowerUsage = providerProperties.mPowerUsage; 327 mAccuracy = providerProperties.mAccuracy; 328 } 329 330 /** 331 * Sets whether a provider requires network access. False by default. 332 */ setHasNetworkRequirement(boolean requiresNetwork)333 public @NonNull Builder setHasNetworkRequirement(boolean requiresNetwork) { 334 mHasNetworkRequirement = requiresNetwork; 335 return this; 336 } 337 338 /** 339 * Sets whether a provider requires satellite access. False by default. 340 */ setHasSatelliteRequirement(boolean requiresSatellite)341 public @NonNull Builder setHasSatelliteRequirement(boolean requiresSatellite) { 342 mHasSatelliteRequirement = requiresSatellite; 343 return this; 344 } 345 346 /** 347 * Sets whether a provider requires cell tower access. False by default. 348 */ setHasCellRequirement(boolean requiresCell)349 public @NonNull Builder setHasCellRequirement(boolean requiresCell) { 350 mHasCellRequirement = requiresCell; 351 return this; 352 } 353 354 /** 355 * Sets whether a provider has a monetary cost. False by default. 356 */ setHasMonetaryCost(boolean monetaryCost)357 public @NonNull Builder setHasMonetaryCost(boolean monetaryCost) { 358 mHasMonetaryCost = monetaryCost; 359 return this; 360 } 361 362 /** 363 * Sets whether a provider can provide altitude information. False by default. 364 */ setHasAltitudeSupport(boolean supportsAltitude)365 public @NonNull Builder setHasAltitudeSupport(boolean supportsAltitude) { 366 mHasAltitudeSupport = supportsAltitude; 367 return this; 368 } 369 370 /** 371 * Sets whether a provider can provide speed information. False by default. 372 */ setHasSpeedSupport(boolean supportsSpeed)373 public @NonNull Builder setHasSpeedSupport(boolean supportsSpeed) { 374 mHasSpeedSupport = supportsSpeed; 375 return this; 376 } 377 378 /** 379 * Sets whether a provider can provide bearing information. False by default. 380 */ setHasBearingSupport(boolean supportsBearing)381 public @NonNull Builder setHasBearingSupport(boolean supportsBearing) { 382 mHasBearingSupport = supportsBearing; 383 return this; 384 } 385 386 /** 387 * Sets a very rough bucket of provider power usage. {@link #POWER_USAGE_HIGH} by default. 388 */ setPowerUsage(@owerUsage int powerUsage)389 public @NonNull Builder setPowerUsage(@PowerUsage int powerUsage) { 390 mPowerUsage = Preconditions.checkArgumentInRange(powerUsage, POWER_USAGE_LOW, 391 POWER_USAGE_HIGH, "powerUsage"); 392 return this; 393 } 394 395 /** 396 * Sets a very rough bucket of provider location accuracy. {@link #ACCURACY_COARSE} by 397 * default. 398 */ setAccuracy(@ccuracy int accuracy)399 public @NonNull Builder setAccuracy(@Accuracy int accuracy) { 400 mAccuracy = Preconditions.checkArgumentInRange(accuracy, ACCURACY_FINE, 401 ACCURACY_COARSE, "accuracy"); 402 return this; 403 } 404 405 /** 406 * Builds a new ProviderProperties. 407 */ build()408 public @NonNull ProviderProperties build() { 409 return new ProviderProperties(mHasNetworkRequirement, mHasSatelliteRequirement, 410 mHasCellRequirement, mHasMonetaryCost, mHasAltitudeSupport, mHasSpeedSupport, 411 mHasBearingSupport, mPowerUsage, mAccuracy); 412 } 413 } 414 } 415