From f6a861a34fbfea24b47c988bb604d131f56d6278 Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Tue, 29 Sep 2020 13:03:08 -0700 Subject: [PATCH] Add quality to LocationRequest/ProviderRequest Expose quality APIs publically after refactoring them to match external usage of quality constants. Removes list of location requests from provider request, as there is no client that really uses this, and it feels like too much information to give to providers. Bug: 168624248 Test: presubmits Change-Id: Icf8a9f6096da0071d97190d3f7196948492e52a1 --- .../android/server/DeviceIdleController.java | 2 +- api/current.txt | 5 + api/system-current.txt | 12 +- api/test-current.txt | 10 +- .../android/location/LocationRequest.java | 189 ++++++++++-------- .../internal/location/ProviderRequest.java | 111 ++++++---- location/lib/api/current.txt | 27 +-- .../provider/LocationRequestUnbundled.java | 56 +++--- .../provider/ProviderRequestUnbundled.java | 30 ++- non-updatable-api/current.txt | 5 + non-updatable-api/system-current.txt | 12 +- .../location/fused/FusedLocationProvider.java | 44 ++-- .../fused/tests/FusedLocationServiceTest.java | 17 +- .../ui/FusedPrintersProvider.java | 2 +- .../location/LocationProviderManager.java | 34 ++-- .../PassiveLocationProviderManager.java | 15 +- .../location/gnss/GnssLocationProvider.java | 4 +- .../location/LocationProviderManagerTest.java | 7 - 18 files changed, 305 insertions(+), 277 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index 1a81587990f25..81f22fe36ea1b 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -2179,7 +2179,7 @@ public class DeviceIdleController extends SystemService if (getContext().getResources().getBoolean( com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) { mLocationRequest = new LocationRequest.Builder(/*intervalMillis=*/ 0) - .setQuality(LocationRequest.ACCURACY_FINE) + .setQuality(LocationRequest.QUALITY_HIGH_ACCURACY) .setMaxUpdates(1) .build(); } diff --git a/api/current.txt b/api/current.txt index ac6970a6bf470..b1f6c0696b390 100644 --- a/api/current.txt +++ b/api/current.txt @@ -24099,9 +24099,13 @@ package android.location { method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates(); method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters(); method @IntRange(from=0) public long getMinUpdateIntervalMillis(); + method public int getQuality(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL + field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66 + field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64 + field public static final int QUALITY_LOW_POWER = 104; // 0x68 } public static final class LocationRequest.Builder { @@ -24114,6 +24118,7 @@ package android.location { method @NonNull public android.location.LocationRequest.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int); method @NonNull public android.location.LocationRequest.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float); method @NonNull public android.location.LocationRequest.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long); + method @NonNull public android.location.LocationRequest.Builder setQuality(int); } public interface OnNmeaMessageListener { diff --git a/api/system-current.txt b/api/system-current.txt index daf712c3b9ad8..45e262d727fe5 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4174,7 +4174,6 @@ package android.location { method @Deprecated public long getInterval(); method @Deprecated public int getNumUpdates(); method @Deprecated @NonNull public String getProvider(); - method public int getQuality(); method @Deprecated public float getSmallestDisplacement(); method @NonNull public android.os.WorkSource getWorkSource(); method public boolean isHiddenFromAppOps(); @@ -4193,11 +4192,11 @@ package android.location { method @Deprecated @NonNull public android.location.LocationRequest setQuality(int); method @Deprecated @NonNull public android.location.LocationRequest setSmallestDisplacement(float); method @Deprecated public void setWorkSource(@Nullable android.os.WorkSource); - field public static final int ACCURACY_BLOCK = 102; // 0x66 - field public static final int ACCURACY_CITY = 104; // 0x68 - field public static final int ACCURACY_FINE = 100; // 0x64 - field public static final int POWER_HIGH = 203; // 0xcb - field public static final int POWER_LOW = 201; // 0xc9 + field @Deprecated public static final int ACCURACY_BLOCK = 102; // 0x66 + field @Deprecated public static final int ACCURACY_CITY = 104; // 0x68 + field @Deprecated public static final int ACCURACY_FINE = 100; // 0x64 + field @Deprecated public static final int POWER_HIGH = 203; // 0xcb + field @Deprecated public static final int POWER_LOW = 201; // 0xc9 field @Deprecated public static final int POWER_NONE = 200; // 0xc8 } @@ -4205,7 +4204,6 @@ package android.location { method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS) public android.location.LocationRequest.Builder setHiddenFromAppOps(boolean); method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest.Builder setLocationSettingsIgnored(boolean); method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.location.LocationRequest.Builder setLowPower(boolean); - method @NonNull public android.location.LocationRequest.Builder setQuality(int); method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.LocationRequest.Builder setWorkSource(@Nullable android.os.WorkSource); } diff --git a/api/test-current.txt b/api/test-current.txt index 6c3df282e09aa..b34c948a96fbf 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1777,11 +1777,11 @@ package android.location { method public boolean isHiddenFromAppOps(); method public boolean isLocationSettingsIgnored(); method public boolean isLowPower(); - field public static final int ACCURACY_BLOCK = 102; // 0x66 - field public static final int ACCURACY_CITY = 104; // 0x68 - field public static final int ACCURACY_FINE = 100; // 0x64 - field public static final int POWER_HIGH = 203; // 0xcb - field public static final int POWER_LOW = 201; // 0xc9 + field @Deprecated public static final int ACCURACY_BLOCK = 102; // 0x66 + field @Deprecated public static final int ACCURACY_CITY = 104; // 0x68 + field @Deprecated public static final int ACCURACY_FINE = 100; // 0x64 + field @Deprecated public static final int POWER_HIGH = 203; // 0xcb + field @Deprecated public static final int POWER_LOW = 201; // 0xc9 } public static final class LocationRequest.Builder { diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index e03643c4c6328..4977c2161be94 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -21,6 +21,7 @@ import static java.lang.Math.min; import android.Manifest; import android.annotation.FloatRange; +import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; @@ -38,6 +39,8 @@ import android.util.TimeUtils; import com.android.internal.util.Preconditions; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Objects; @@ -65,16 +68,41 @@ public final class LocationRequest implements Parcelable { */ public static final long PASSIVE_INTERVAL = Long.MAX_VALUE; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({QUALITY_LOW_POWER, QUALITY_BALANCED_POWER_ACCURACY, QUALITY_HIGH_ACCURACY}) + public @interface Quality {} + + /** + * A quality constant indicating a location provider may choose to satisfy this request by + * providing very accurate locations at the expense of potentially increased power usage. + */ + public static final int QUALITY_HIGH_ACCURACY = 100; + + /** + * A quality constant indicating a location provider may choose to satisfy this request by + * equally balancing power and accuracy constraints. + */ + public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; + + /** + * A quality constant indicating a location provider may choose to satisfy this request by + * providing less accurate locations in order to save power. + */ + public static final int QUALITY_LOW_POWER = 104; + /** * Used with {@link #setQuality} to request the most accurate locations available. * *

This may be up to 1 meter accuracy, although this is implementation dependent. * * @hide + * @deprecated Use {@link #QUALITY_HIGH_ACCURACY} instead. */ + @Deprecated @SystemApi @TestApi - public static final int ACCURACY_FINE = 100; + public static final int ACCURACY_FINE = QUALITY_HIGH_ACCURACY; /** * Used with {@link #setQuality} to request "block" level accuracy. @@ -84,10 +112,12 @@ public final class LocationRequest implements Parcelable { * such as this often consumes less power. * * @hide + * @deprecated Use {@link #QUALITY_BALANCED_POWER_ACCURACY} instead. */ + @Deprecated @SystemApi @TestApi - public static final int ACCURACY_BLOCK = 102; + public static final int ACCURACY_BLOCK = QUALITY_BALANCED_POWER_ACCURACY; /** * Used with {@link #setQuality} to request "city" level accuracy. @@ -97,10 +127,12 @@ public final class LocationRequest implements Parcelable { * such as this often consumes less power. * * @hide + * @deprecated Use {@link #QUALITY_LOW_POWER} instead. */ + @Deprecated @SystemApi @TestApi - public static final int ACCURACY_CITY = 104; + public static final int ACCURACY_CITY = QUALITY_LOW_POWER; /** * Used with {@link #setQuality} to require no direct power impact (passive locations). @@ -123,7 +155,9 @@ public final class LocationRequest implements Parcelable { * possible. * * @hide + * @deprecated Use {@link #QUALITY_LOW_POWER} instead. */ + @Deprecated @SystemApi @TestApi public static final int POWER_LOW = 201; @@ -134,7 +168,9 @@ public final class LocationRequest implements Parcelable { *

This location request will allow high power location work. * * @hide + * @deprecated Use {@link #QUALITY_HIGH_ACCURACY} instead. */ + @Deprecated @SystemApi @TestApi public static final int POWER_HIGH = 203; @@ -144,7 +180,7 @@ public final class LocationRequest implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " + "LocationManager} methods to provide the provider explicitly.") @Nullable private String mProvider; - private int mQuality; + private @Quality int mQuality; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " + "LocationRequest} instead.") private long mInterval; @@ -168,7 +204,7 @@ public final class LocationRequest implements Parcelable { public static LocationRequest create() { // 60 minutes is the default legacy interval return new LocationRequest.Builder(60 * 60 * 1000) - .setQuality(POWER_LOW) + .setQuality(QUALITY_LOW_POWER) .build(); } @@ -241,7 +277,7 @@ public final class LocationRequest implements Parcelable { private LocationRequest( @Nullable String provider, long intervalMillis, - int quality, + @Quality int quality, long expireAtRealtimeMillis, long durationMillis, int maxUpdates, @@ -251,9 +287,6 @@ public final class LocationRequest implements Parcelable { boolean locationSettingsIgnored, boolean lowPower, WorkSource workSource) { - Preconditions.checkArgument(intervalMillis != PASSIVE_INTERVAL || quality == POWER_NONE); - Preconditions.checkArgument(minUpdateIntervalMillis <= intervalMillis); - mProvider = provider; mInterval = intervalMillis; mQuality = quality; @@ -297,24 +330,39 @@ public final class LocationRequest implements Parcelable { @SystemApi @Deprecated public @NonNull LocationRequest setQuality(int quality) { - mQuality = Builder.checkQuality(quality, true); + switch (quality) { + case POWER_HIGH: + // fall through + case ACCURACY_FINE: + mQuality = QUALITY_HIGH_ACCURACY; + break; + case ACCURACY_BLOCK: + mQuality = QUALITY_BALANCED_POWER_ACCURACY; + break; + case POWER_LOW: + // fall through + case ACCURACY_CITY: + mQuality = QUALITY_LOW_POWER; + break; + case POWER_NONE: + mInterval = PASSIVE_INTERVAL; + break; + default: + throw new IllegalArgumentException("invalid quality: " + quality); + } + return this; } /** - * Returns the quality of the location request. + * Returns the quality hint for this location request. The quality hint informs the provider how + * it should attempt to manage any accuracy vs power tradeoffs while attempting to satisfy this + * location request. * - * @return the quality of the location request - * - * @hide + * @return the desired quality tradeoffs between accuracy and power */ - @SystemApi - public int getQuality() { - if (mInterval == PASSIVE_INTERVAL) { - return POWER_NONE; - } else { - return mQuality; - } + public @Quality int getQuality() { + return mQuality; } /** @@ -749,97 +797,65 @@ public final class LocationRequest implements Parcelable { if (mProvider != null) { s.append(mProvider).append(" "); } - if (mQuality != POWER_NONE && mQuality != ACCURACY_BLOCK) { - s.append(qualityToString(mQuality)).append(" "); - } if (mInterval != PASSIVE_INTERVAL) { s.append("@"); TimeUtils.formatDuration(mInterval, s); + + switch (mQuality) { + case QUALITY_HIGH_ACCURACY: + s.append(" HIGH_ACCURACY"); + break; + case QUALITY_BALANCED_POWER_ACCURACY: + s.append(" BALANCED"); + break; + case QUALITY_LOW_POWER: + s.append(" LOW_POWER"); + break; + } } else { s.append("PASSIVE"); } if (mExpireAtRealtimeMillis != Long.MAX_VALUE) { - s.append(" expireAt=").append(TimeUtils.formatRealtime(mExpireAtRealtimeMillis)); + s.append(", expireAt=").append(TimeUtils.formatRealtime(mExpireAtRealtimeMillis)); } if (mDurationMillis != Long.MAX_VALUE) { - s.append(" duration="); + s.append(", duration="); TimeUtils.formatDuration(mDurationMillis, s); } if (mMaxUpdates != Integer.MAX_VALUE) { - s.append(" maxUpdates=").append(mMaxUpdates); + s.append(", maxUpdates=").append(mMaxUpdates); } if (mMinUpdateIntervalMillis != IMPLICIT_MIN_UPDATE_INTERVAL && mMinUpdateIntervalMillis < mInterval) { - s.append(" minUpdateInterval="); + s.append(", minUpdateInterval="); TimeUtils.formatDuration(mMinUpdateIntervalMillis, s); } if (mMinUpdateDistanceMeters > 0.0) { - s.append(" minUpdateDistance=").append(mMinUpdateDistanceMeters); + s.append(", minUpdateDistance=").append(mMinUpdateDistanceMeters); } if (mLowPower) { - s.append(" lowPower"); + s.append(", lowPower"); } if (mHideFromAppOps) { - s.append(" hiddenFromAppOps"); + s.append(", hiddenFromAppOps"); } if (mLocationSettingsIgnored) { - s.append(" locationSettingsIgnored"); + s.append(", locationSettingsIgnored"); } - if (mWorkSource != null) { - s.append(" ").append(mWorkSource); + if (mWorkSource != null && !mWorkSource.isEmpty()) { + s.append(", ").append(mWorkSource); } s.append(']'); return s.toString(); } - private static String qualityToString(int quality) { - switch (quality) { - case ACCURACY_FINE: - return "ACCURACY_FINE"; - case ACCURACY_BLOCK: - return "ACCURACY_BLOCK"; - case ACCURACY_CITY: - return "ACCURACY_CITY"; - case POWER_NONE: - return "POWER_NONE"; - case POWER_LOW: - return "POWER_LOW"; - case POWER_HIGH: - return "POWER_HIGH"; - default: - return "???"; - } - } - /** * A builder class for {@link LocationRequest}. */ public static final class Builder { - private static int checkQuality(int quality, boolean allowDeprecated) { - switch (quality) { - case ACCURACY_FINE: - // fall through - case ACCURACY_BLOCK: - // fall through - case ACCURACY_CITY: - // fall through - case POWER_LOW: - // fall through - case POWER_HIGH: - return quality; - case POWER_NONE: - if (allowDeprecated) { - return quality; - } - // fall through - default: - throw new IllegalArgumentException("invalid quality: " + quality); - } - } - private long mIntervalMillis; - private int mQuality; + private @Quality int mQuality; private long mDurationMillis; private int mMaxUpdates; private long mMinUpdateIntervalMillis; @@ -857,7 +873,7 @@ public final class LocationRequest implements Parcelable { // gives us a range check setIntervalMillis(intervalMillis); - mQuality = ACCURACY_BLOCK; + mQuality = QUALITY_BALANCED_POWER_ACCURACY; mDurationMillis = Long.MAX_VALUE; mMaxUpdates = Integer.MAX_VALUE; mMinUpdateIntervalMillis = IMPLICIT_MIN_UPDATE_INTERVAL; @@ -885,9 +901,6 @@ public final class LocationRequest implements Parcelable { // handle edge cases that can only happen with location request that has been modified // by deprecated SystemApi methods - if (mQuality == POWER_NONE) { - mIntervalMillis = PASSIVE_INTERVAL; - } if (mIntervalMillis == PASSIVE_INTERVAL && mMinUpdateIntervalMillis == IMPLICIT_MIN_UPDATE_INTERVAL) { // this is the legacy default minimum update interval, so if we're forced to @@ -914,11 +927,17 @@ public final class LocationRequest implements Parcelable { } /** - * @hide + * Sets the request quality. The quality is a hint to providers on how they should weigh + * power vs accuracy tradeoffs. High accuracy locations may cost more power to produce, and + * lower accuracy locations may cost less power to produce. Defaults to + * {@link #QUALITY_BALANCED_POWER_ACCURACY}. */ - @SystemApi - public @NonNull Builder setQuality(int quality) { - mQuality = checkQuality(quality, false); + public @NonNull Builder setQuality(@Quality int quality) { + Preconditions.checkArgument( + quality == QUALITY_LOW_POWER || quality == QUALITY_BALANCED_POWER_ACCURACY + || quality == QUALITY_HIGH_ACCURACY, + "quality must be a defined QUALITY constant, not " + quality); + mQuality = quality; return this; } @@ -1102,7 +1121,7 @@ public final class LocationRequest implements Parcelable { return new LocationRequest( null, mIntervalMillis, - mIntervalMillis != PASSIVE_INTERVAL ? mQuality : POWER_NONE, + mQuality, Long.MAX_VALUE, mDurationMillis, mMaxUpdates, diff --git a/location/java/com/android/internal/location/ProviderRequest.java b/location/java/com/android/internal/location/ProviderRequest.java index fee86ceb453a9..00ba5523b8d45 100644 --- a/location/java/com/android/internal/location/ProviderRequest.java +++ b/location/java/com/android/internal/location/ProviderRequest.java @@ -16,10 +16,15 @@ package com.android.internal.location; +import static android.location.LocationRequest.QUALITY_BALANCED_POWER_ACCURACY; +import static android.location.LocationRequest.QUALITY_HIGH_ACCURACY; +import static android.location.LocationRequest.QUALITY_LOW_POWER; + import android.annotation.IntRange; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; import android.location.LocationRequest; +import android.location.LocationRequest.Quality; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -41,7 +46,7 @@ public final class ProviderRequest implements Parcelable { public static final long INTERVAL_DISABLED = Long.MAX_VALUE; public static final ProviderRequest EMPTY_REQUEST = new ProviderRequest( - INTERVAL_DISABLED, false, false, Collections.emptyList(), new WorkSource()); + INTERVAL_DISABLED, QUALITY_BALANCED_POWER_ACCURACY, false, false, new WorkSource()); @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link " + "ProviderRequest}") @@ -49,6 +54,7 @@ public final class ProviderRequest implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link " + "ProviderRequest}") public final long interval; + private final @Quality int mQuality; private final boolean mLowPower; private final boolean mLocationSettingsIgnored; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link " @@ -56,15 +62,24 @@ public final class ProviderRequest implements Parcelable { public final List locationRequests; private final WorkSource mWorkSource; - private ProviderRequest(long intervalMillis, boolean lowPower, - boolean locationSettingsIgnored, @NonNull List locationRequests, - @NonNull WorkSource workSource) { + private ProviderRequest(long intervalMillis, @Quality int quality, boolean lowPower, + boolean locationSettingsIgnored, @NonNull WorkSource workSource) { reportLocation = intervalMillis != INTERVAL_DISABLED; interval = intervalMillis; + mQuality = quality; mLowPower = lowPower; mLocationSettingsIgnored = locationSettingsIgnored; - this.locationRequests = locationRequests; - mWorkSource = workSource; + if (intervalMillis != INTERVAL_DISABLED) { + locationRequests = Collections.singletonList(new LocationRequest.Builder(intervalMillis) + .setQuality(quality) + .setLowPower(lowPower) + .setLocationSettingsIgnored(locationSettingsIgnored) + .setWorkSource(workSource) + .build()); + } else { + locationRequests = Collections.emptyList(); + } + mWorkSource = Objects.requireNonNull(workSource); } /** @@ -83,6 +98,15 @@ public final class ProviderRequest implements Parcelable { return interval; } + /** + * The quality hint for this location request. The quality hint informs the provider how it + * should attempt to manage any accuracy vs power tradeoffs while attempting to satisfy this + * provider request. + */ + public @Quality int getQuality() { + return mQuality; + } + /** * Whether any applicable hardware low power modes should be used to satisfy this request. */ @@ -99,13 +123,6 @@ public final class ProviderRequest implements Parcelable { return mLocationSettingsIgnored; } - /** - * The full list of location requests contributing to this provider request. - */ - public @NonNull List getLocationRequests() { - return locationRequests; - } - /** * The power blame for this provider request. */ @@ -117,13 +134,17 @@ public final class ProviderRequest implements Parcelable { new Parcelable.Creator() { @Override public ProviderRequest createFromParcel(Parcel in) { - return new ProviderRequest( - /* intervalMillis= */ in.readLong(), - /* lowPower= */ in.readBoolean(), - /* locationSettingsIgnored= */ in.readBoolean(), - /* locationRequests= */ - in.createTypedArrayList(LocationRequest.CREATOR), - /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); + long intervalMillis = in.readLong(); + if (intervalMillis == INTERVAL_DISABLED) { + return EMPTY_REQUEST; + } else { + return new ProviderRequest( + intervalMillis, + /* quality= */ in.readInt(), + /* lowPower= */ in.readBoolean(), + /* locationSettingsIgnored= */ in.readBoolean(), + /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); + } } @Override @@ -140,10 +161,12 @@ public final class ProviderRequest implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeLong(interval); - parcel.writeBoolean(mLowPower); - parcel.writeBoolean(mLocationSettingsIgnored); - parcel.writeTypedList(locationRequests); - parcel.writeTypedObject(mWorkSource, flags); + if (interval != INTERVAL_DISABLED) { + parcel.writeInt(mQuality); + parcel.writeBoolean(mLowPower); + parcel.writeBoolean(mLocationSettingsIgnored); + parcel.writeTypedObject(mWorkSource, flags); + } } @Override @@ -160,16 +183,16 @@ public final class ProviderRequest implements Parcelable { return that.interval == INTERVAL_DISABLED; } else { return interval == that.interval + && mQuality == that.mQuality && mLowPower == that.mLowPower && mLocationSettingsIgnored == that.mLocationSettingsIgnored - && locationRequests.equals(that.locationRequests) && mWorkSource.equals(that.mWorkSource); } } @Override public int hashCode() { - return Objects.hash(interval, mWorkSource); + return Objects.hash(interval, mQuality, mWorkSource); } @Override @@ -179,6 +202,13 @@ public final class ProviderRequest implements Parcelable { if (interval != INTERVAL_DISABLED) { s.append("@"); TimeUtils.formatDuration(interval, s); + if (mQuality != QUALITY_BALANCED_POWER_ACCURACY) { + if (mQuality == QUALITY_HIGH_ACCURACY) { + s.append(", HIGH_ACCURACY"); + } else if (mQuality == QUALITY_LOW_POWER) { + s.append(", LOW_POWER"); + } + } if (mLowPower) { s.append(", lowPower"); } @@ -200,9 +230,9 @@ public final class ProviderRequest implements Parcelable { */ public static class Builder { private long mIntervalMillis = INTERVAL_DISABLED; + private int mQuality = QUALITY_BALANCED_POWER_ACCURACY; private boolean mLowPower; private boolean mLocationSettingsIgnored; - private List mLocationRequests = Collections.emptyList(); private WorkSource mWorkSource = new WorkSource(); /** @@ -215,6 +245,20 @@ public final class ProviderRequest implements Parcelable { return this; } + /** + * Sets the request quality. The quality is a hint to providers on how they should weigh + * power vs accuracy tradeoffs. High accuracy locations may cost more power to produce, and + * lower accuracy locations may cost less power to produce. Defaults to + * {@link LocationRequest#QUALITY_BALANCED_POWER_ACCURACY}. + */ + public @NonNull Builder setQuality(@Quality int quality) { + Preconditions.checkArgument( + quality == QUALITY_LOW_POWER || quality == QUALITY_BALANCED_POWER_ACCURACY + || quality == QUALITY_HIGH_ACCURACY); + mQuality = quality; + return this; + } + /** * Sets whether hardware low power mode should be used. False by default. */ @@ -231,15 +275,6 @@ public final class ProviderRequest implements Parcelable { return this; } - /** - * Sets the {@link LocationRequest}s associated with this request. Empty by default. - */ - public @NonNull Builder setLocationRequests( - @NonNull List locationRequests) { - this.mLocationRequests = Objects.requireNonNull(locationRequests); - return this; - } - /** * Sets the work source for power blame. Empty by default. */ @@ -255,8 +290,8 @@ public final class ProviderRequest implements Parcelable { if (mIntervalMillis == INTERVAL_DISABLED) { return EMPTY_REQUEST; } else { - return new ProviderRequest(mIntervalMillis, mLowPower, mLocationSettingsIgnored, - mLocationRequests, mWorkSource); + return new ProviderRequest(mIntervalMillis, mQuality, mLowPower, + mLocationSettingsIgnored, mWorkSource); } } } diff --git a/location/lib/api/current.txt b/location/lib/api/current.txt index f43eb639ee23f..80636c665a1a3 100644 --- a/location/lib/api/current.txt +++ b/location/lib/api/current.txt @@ -29,18 +29,18 @@ package com.android.location.provider { field public static final String FUSED_PROVIDER = "fused"; } - public final class LocationRequestUnbundled { - method public long getFastestInterval(); - method public long getInterval(); - method public int getQuality(); - method public float getSmallestDisplacement(); - method public boolean isLocationSettingsIgnored(); - field public static final int ACCURACY_BLOCK = 102; // 0x66 - field public static final int ACCURACY_CITY = 104; // 0x68 - field public static final int ACCURACY_FINE = 100; // 0x64 - field public static final int POWER_HIGH = 203; // 0xcb - field public static final int POWER_LOW = 201; // 0xc9 - field public static final int POWER_NONE = 200; // 0xc8 + @Deprecated public final class LocationRequestUnbundled { + method @Deprecated public long getFastestInterval(); + method @Deprecated public long getInterval(); + method @Deprecated @android.location.LocationRequest.Quality public int getQuality(); + method @Deprecated public float getSmallestDisplacement(); + method @Deprecated public boolean isLocationSettingsIgnored(); + field @Deprecated public static final int ACCURACY_BLOCK = 102; // 0x66 + field @Deprecated public static final int ACCURACY_CITY = 104; // 0x68 + field @Deprecated public static final int ACCURACY_FINE = 100; // 0x64 + field @Deprecated public static final int POWER_HIGH = 203; // 0xcb + field @Deprecated public static final int POWER_LOW = 201; // 0xc9 + field @Deprecated public static final int POWER_NONE = 200; // 0xc8 } public final class ProviderPropertiesUnbundled { @@ -49,7 +49,8 @@ package com.android.location.provider { public final class ProviderRequestUnbundled { method public long getInterval(); - method @NonNull public java.util.List getLocationRequests(); + method @Deprecated @NonNull public java.util.List getLocationRequests(); + method @android.location.LocationRequest.Quality @RequiresApi(android.os.Build.VERSION_CODES.S) public int getQuality(); method public boolean getReportLocation(); method @NonNull @RequiresApi(android.os.Build.VERSION_CODES.S) public android.os.WorkSource getWorkSource(); method @RequiresApi(android.os.Build.VERSION_CODES.Q) public boolean isLocationSettingsIgnored(); diff --git a/location/lib/java/com/android/location/provider/LocationRequestUnbundled.java b/location/lib/java/com/android/location/provider/LocationRequestUnbundled.java index 92e05ef68e3b9..0e7c633eb5fba 100644 --- a/location/lib/java/com/android/location/provider/LocationRequestUnbundled.java +++ b/location/lib/java/com/android/location/provider/LocationRequestUnbundled.java @@ -17,6 +17,7 @@ package com.android.location.provider; import android.location.LocationRequest; +import android.location.LocationRequest.Quality; /** * This class is an interface to LocationRequests for unbundled applications. @@ -24,55 +25,50 @@ import android.location.LocationRequest; *

IMPORTANT: This class is effectively a public API for unbundled * applications, and must remain API stable. See README.txt in the root * of this package for more information. + * + * @deprecated Do not use. */ +@Deprecated public final class LocationRequestUnbundled { + /** - * Returned by {@link #getQuality} when requesting the most accurate locations available. - * - *

This may be up to 1 meter accuracy, although this is implementation dependent. + * @deprecated Use {@link LocationRequest#QUALITY_HIGH_ACCURACY} instead. */ + @Deprecated public static final int ACCURACY_FINE = LocationRequest.ACCURACY_FINE; /** - * Returned by {@link #getQuality} when requesting "block" level accuracy. - * - *

Block level accuracy is considered to be about 100 meter accuracy, - * although this is implementation dependent. Using a coarse accuracy - * such as this often consumes less power. + * @deprecated Use {@link LocationRequest#QUALITY_BALANCED_POWER_ACCURACY} instead. */ + @Deprecated public static final int ACCURACY_BLOCK = LocationRequest.ACCURACY_BLOCK; + /** - * Returned by {@link #getQuality} when requesting "city" level accuracy. - * - *

City level accuracy is considered to be about 10km accuracy, - * although this is implementation dependent. Using a coarse accuracy - * such as this often consumes less power. + * @deprecated Use {@link LocationRequest#QUALITY_LOW_POWER} instead. */ + @Deprecated public static final int ACCURACY_CITY = LocationRequest.ACCURACY_CITY; + /** - * Returned by {@link #getQuality} when requiring no direct power impact (passive locations). - * - *

This location request will not trigger any active location requests, - * but will receive locations triggered by other applications. Your application - * will not receive any direct power blame for location work. + * @deprecated Do not use. */ + @Deprecated public static final int POWER_NONE = LocationRequest.POWER_NONE; - /** - * Returned by {@link #getQuality} when requesting low power impact. - * - *

This location request will avoid high power location work where - * possible. - */ - public static final int POWER_LOW = LocationRequest.POWER_LOW; /** - * Returned by {@link #getQuality} when allowing high power consumption for location. - * - *

This location request will allow high power location work. + * @deprecated Use {@link LocationRequest#QUALITY_LOW_POWER} instead. */ + @Deprecated + public static final int POWER_LOW = LocationRequest.POWER_LOW; + + + /** + * @deprecated Use {@link LocationRequest#QUALITY_BALANCED_POWER_ACCURACY} instead. + */ + @Deprecated public static final int POWER_HIGH = LocationRequest.POWER_HIGH; private final LocationRequest delegate; @@ -102,9 +98,9 @@ public final class LocationRequestUnbundled { /** * Get the quality of the request. * - * @return an accuracy or power constant + * @return a {@link LocationRequest} QUALITY_* constant */ - public int getQuality() { + public @Quality int getQuality() { return delegate.getQuality(); } diff --git a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java index 6f5fcc7bfc8e8..f7bac74bf92d5 100644 --- a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java +++ b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java @@ -25,7 +25,7 @@ import androidx.annotation.RequiresApi; import com.android.internal.location.ProviderRequest; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -56,6 +56,16 @@ public final class ProviderRequestUnbundled { return mRequest.isActive(); } + /** + * The quality hint for this location request. The quality hint informs the provider how it + * should attempt to manage any accuracy vs power tradeoffs while attempting to satisfy this + * provider request. + */ + @RequiresApi(Build.VERSION_CODES.S) + public @LocationRequest.Quality int getQuality() { + return mRequest.getQuality(); + } + /** * The interval at which a provider should report location. Will return * {@link #INTERVAL_DISABLED} for an inactive request. @@ -84,14 +94,22 @@ public final class ProviderRequestUnbundled { /** * The full list of location requests contributing to this provider request. + * + * @deprecated Do not use. */ + @Deprecated public @NonNull List getLocationRequests() { - List result = new ArrayList<>( - mRequest.getLocationRequests().size()); - for (LocationRequest r : mRequest.getLocationRequests()) { - result.add(new LocationRequestUnbundled(r)); + if (!mRequest.isActive()) { + return Collections.emptyList(); } - return result; + + return Collections.singletonList(new LocationRequestUnbundled( + new LocationRequest.Builder(mRequest.getIntervalMillis()) + .setQuality(mRequest.getQuality()) + .setLowPower(mRequest.isLowPower()) + .setLocationSettingsIgnored(mRequest.isLocationSettingsIgnored()) + .setWorkSource(mRequest.getWorkSource()) + .build())); } /** diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 648ad56307238..e3718c9cd554d 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -24081,9 +24081,13 @@ package android.location { method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates(); method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters(); method @IntRange(from=0) public long getMinUpdateIntervalMillis(); + method public int getQuality(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL + field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66 + field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64 + field public static final int QUALITY_LOW_POWER = 104; // 0x68 } public static final class LocationRequest.Builder { @@ -24096,6 +24100,7 @@ package android.location { method @NonNull public android.location.LocationRequest.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int); method @NonNull public android.location.LocationRequest.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float); method @NonNull public android.location.LocationRequest.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long); + method @NonNull public android.location.LocationRequest.Builder setQuality(int); } public interface OnNmeaMessageListener { diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index e0395d45a1b0c..b49eeef955b53 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -4114,7 +4114,6 @@ package android.location { method @Deprecated public long getInterval(); method @Deprecated public int getNumUpdates(); method @Deprecated @NonNull public String getProvider(); - method public int getQuality(); method @Deprecated public float getSmallestDisplacement(); method @NonNull public android.os.WorkSource getWorkSource(); method public boolean isHiddenFromAppOps(); @@ -4133,11 +4132,11 @@ package android.location { method @Deprecated @NonNull public android.location.LocationRequest setQuality(int); method @Deprecated @NonNull public android.location.LocationRequest setSmallestDisplacement(float); method @Deprecated public void setWorkSource(@Nullable android.os.WorkSource); - field public static final int ACCURACY_BLOCK = 102; // 0x66 - field public static final int ACCURACY_CITY = 104; // 0x68 - field public static final int ACCURACY_FINE = 100; // 0x64 - field public static final int POWER_HIGH = 203; // 0xcb - field public static final int POWER_LOW = 201; // 0xc9 + field @Deprecated public static final int ACCURACY_BLOCK = 102; // 0x66 + field @Deprecated public static final int ACCURACY_CITY = 104; // 0x68 + field @Deprecated public static final int ACCURACY_FINE = 100; // 0x64 + field @Deprecated public static final int POWER_HIGH = 203; // 0xcb + field @Deprecated public static final int POWER_LOW = 201; // 0xc9 field @Deprecated public static final int POWER_NONE = 200; // 0xc8 } @@ -4145,7 +4144,6 @@ package android.location { method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS) public android.location.LocationRequest.Builder setHiddenFromAppOps(boolean); method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest.Builder setLocationSettingsIgnored(boolean); method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.location.LocationRequest.Builder setLowPower(boolean); - method @NonNull public android.location.LocationRequest.Builder setQuality(int); method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.LocationRequest.Builder setWorkSource(@Nullable android.os.WorkSource); } diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java index 900e68d36c325..6827d6eb01804 100644 --- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java +++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java @@ -19,6 +19,9 @@ package com.android.location.fused; import static android.content.Intent.ACTION_USER_SWITCHED; import static android.location.LocationManager.GPS_PROVIDER; import static android.location.LocationManager.NETWORK_PROVIDER; +import static android.location.LocationRequest.QUALITY_LOW_POWER; + +import static com.android.location.provider.ProviderRequestUnbundled.INTERVAL_DISABLED; import android.annotation.Nullable; import android.content.BroadcastReceiver; @@ -35,7 +38,6 @@ import android.os.WorkSource; import com.android.internal.annotations.GuardedBy; import com.android.internal.location.ProviderRequest; import com.android.location.provider.LocationProviderBase; -import com.android.location.provider.LocationRequestUnbundled; import com.android.location.provider.ProviderPropertiesUnbundled; import com.android.location.provider.ProviderRequestUnbundled; @@ -147,8 +149,8 @@ public class FusedLocationProvider extends LocationProviderBase { mRequest = new ProviderRequestUnbundled(ProviderRequest.EMPTY_REQUEST); mWorkSource = new WorkSource(); - mGpsInterval = Long.MAX_VALUE; - mNetworkInterval = Long.MAX_VALUE; + mGpsInterval = INTERVAL_DISABLED; + mNetworkInterval = INTERVAL_DISABLED; } void start() { @@ -175,30 +177,9 @@ public class FusedLocationProvider extends LocationProviderBase { @GuardedBy("mLock") private void updateRequirementsLocked() { - long gpsInterval = Long.MAX_VALUE; - long networkInterval = Long.MAX_VALUE; - if (mRequest.getReportLocation()) { - for (LocationRequestUnbundled request : mRequest.getLocationRequests()) { - switch (request.getQuality()) { - case LocationRequestUnbundled.ACCURACY_FINE: - case LocationRequestUnbundled.ACCURACY_BLOCK: - case LocationRequestUnbundled.POWER_HIGH: - if (request.getInterval() < gpsInterval) { - gpsInterval = request.getInterval(); - } - if (request.getInterval() < networkInterval) { - networkInterval = request.getInterval(); - } - break; - case LocationRequestUnbundled.ACCURACY_CITY: - case LocationRequestUnbundled.POWER_LOW: - if (request.getInterval() < networkInterval) { - networkInterval = request.getInterval(); - } - break; - } - } - } + long gpsInterval = mRequest.getQuality() < QUALITY_LOW_POWER ? mRequest.getInterval() + : INTERVAL_DISABLED; + long networkInterval = mRequest.getInterval(); if (gpsInterval != mGpsInterval) { resetProviderRequestLocked(GPS_PROVIDER, mGpsInterval, gpsInterval, mGpsListener); @@ -214,11 +195,12 @@ public class FusedLocationProvider extends LocationProviderBase { @GuardedBy("mLock") private void resetProviderRequestLocked(String provider, long oldInterval, long newInterval, LocationListener listener) { - if (oldInterval != Long.MAX_VALUE) { + if (oldInterval != INTERVAL_DISABLED && newInterval == INTERVAL_DISABLED) { mLocationManager.removeUpdates(listener); } - if (newInterval != Long.MAX_VALUE) { + if (newInterval != INTERVAL_DISABLED) { LocationRequest request = new LocationRequest.Builder(newInterval) + .setQuality(mRequest.getQuality()) .setLocationSettingsIgnored(mRequest.isLocationSettingsIgnored()) .setWorkSource(mWorkSource) .build(); @@ -254,10 +236,10 @@ public class FusedLocationProvider extends LocationProviderBase { void dump(PrintWriter writer) { synchronized (mLock) { writer.println("request: " + mRequest); - if (mGpsInterval != Long.MAX_VALUE) { + if (mGpsInterval != INTERVAL_DISABLED) { writer.println(" gps interval: " + mGpsInterval); } - if (mNetworkInterval != Long.MAX_VALUE) { + if (mNetworkInterval != INTERVAL_DISABLED) { writer.println(" network interval: " + mNetworkInterval); } if (mGpsLocation != null) { diff --git a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java index d3aa977f85b1a..61349d9bb8e8d 100644 --- a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java +++ b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java @@ -48,7 +48,6 @@ import org.junit.runner.RunWith; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; -import java.util.Collections; import java.util.Random; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -60,7 +59,6 @@ public class FusedLocationServiceTest { private static final long TIMEOUT_MS = 5000; - private Context mContext; private Random mRandom; private LocationManager mLocationManager; @@ -72,15 +70,15 @@ public class FusedLocationServiceTest { long seed = System.currentTimeMillis(); Log.i(TAG, "location seed: " + seed); - mContext = InstrumentationRegistry.getTargetContext(); + Context context = InstrumentationRegistry.getTargetContext(); mRandom = new Random(seed); - mLocationManager = mContext.getSystemService(LocationManager.class); + mLocationManager = context.getSystemService(LocationManager.class); setMockLocation(true); mManager = new LocationProviderManagerCapture(); mProvider = ILocationProvider.Stub.asInterface( - new FusedLocationProvider(mContext).getBinder()); + new FusedLocationProvider(context).getBinder()); mProvider.setLocationProviderManager(mManager); mLocationManager.addTestProvider(NETWORK_PROVIDER, @@ -118,12 +116,9 @@ public class FusedLocationServiceTest { @Test public void testNetworkRequest() throws Exception { - LocationRequest request = new LocationRequest.Builder(1000).build(); - mProvider.setRequest( new ProviderRequest.Builder() .setIntervalMillis(1000) - .setLocationRequests(Collections.singletonList(request)) .build(), new WorkSource()); @@ -135,14 +130,10 @@ public class FusedLocationServiceTest { @Test public void testGpsRequest() throws Exception { - LocationRequest request = new LocationRequest.Builder(1000) - .setQuality(LocationRequest.POWER_HIGH) - .build(); - mProvider.setRequest( new ProviderRequest.Builder() + .setQuality(LocationRequest.QUALITY_HIGH_ACCURACY) .setIntervalMillis(1000) - .setLocationRequests(Collections.singletonList(request)) .build(), new WorkSource()); diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java index 8e140ca279719..83974afd083f1 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java @@ -254,7 +254,7 @@ public final class FusedPrintersProvider extends Loader> mLocationManager.requestLocationUpdates( LocationManager.FUSED_PROVIDER, new LocationRequest.Builder(LOCATION_UPDATE_MS) - .setQuality(LocationRequest.POWER_LOW) + .setQuality(LocationRequest.QUALITY_LOW_POWER) .build(), new HandlerExecutor(new Handler(Looper.getMainLooper())), this); diff --git a/services/core/java/com/android/server/location/LocationProviderManager.java b/services/core/java/com/android/server/location/LocationProviderManager.java index 52065710f38ef..179fb7d2f7236 100644 --- a/services/core/java/com/android/server/location/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/LocationProviderManager.java @@ -23,15 +23,12 @@ import static android.location.LocationManager.GPS_PROVIDER; import static android.location.LocationManager.KEY_LOCATION_CHANGED; import static android.location.LocationManager.KEY_PROVIDER_ENABLED; import static android.location.LocationManager.PASSIVE_PROVIDER; -import static android.location.LocationRequest.PASSIVE_INTERVAL; import static android.os.IPowerManager.LOCATION_MODE_NO_CHANGE; import static android.os.PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF; import static android.os.PowerManager.LOCATION_MODE_FOREGROUND_ONLY; import static android.os.PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF; import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; -import static com.android.internal.location.ProviderRequest.EMPTY_REQUEST; -import static com.android.internal.location.ProviderRequest.INTERVAL_DISABLED; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; import static com.android.server.location.LocationPermissions.PERMISSION_COARSE; @@ -503,14 +500,7 @@ class LocationProviderManager extends LocationRequest.Builder builder = new LocationRequest.Builder(baseRequest); if (mPermissionLevel < PERMISSION_FINE) { - switch (baseRequest.getQuality()) { - case LocationRequest.ACCURACY_FINE: - builder.setQuality(LocationRequest.ACCURACY_BLOCK); - break; - case LocationRequest.POWER_HIGH: - builder.setQuality(LocationRequest.POWER_LOW); - break; - } + builder.setQuality(LocationRequest.QUALITY_LOW_POWER); if (baseRequest.getIntervalMillis() < MIN_COARSE_INTERVAL_MS) { builder.setIntervalMillis(MIN_COARSE_INTERVAL_MS); } @@ -1709,7 +1699,7 @@ class LocationProviderManager extends @Override protected boolean registerWithService(ProviderRequest request, Collection registrations) { - return reregisterWithService(EMPTY_REQUEST, request, registrations); + return reregisterWithService(ProviderRequest.EMPTY_REQUEST, request, registrations); } @GuardedBy("mLock") @@ -1778,8 +1768,8 @@ class LocationProviderManager extends Preconditions.checkState(Thread.holdsLock(mLock)); } - mLocationEventLog.logProviderUpdateRequest(mName, EMPTY_REQUEST); - mProvider.setRequest(EMPTY_REQUEST); + mLocationEventLog.logProviderUpdateRequest(mName, ProviderRequest.EMPTY_REQUEST); + mProvider.setRequest(ProviderRequest.EMPTY_REQUEST); } @GuardedBy("mLock") @@ -1839,27 +1829,27 @@ class LocationProviderManager extends Preconditions.checkState(Thread.holdsLock(mLock)); } - long intervalMs = INTERVAL_DISABLED; + long intervalMs = ProviderRequest.INTERVAL_DISABLED; + int quality = LocationRequest.QUALITY_LOW_POWER; boolean locationSettingsIgnored = false; boolean lowPower = true; - ArrayList locationRequests = new ArrayList<>(registrations.size()); for (Registration registration : registrations) { LocationRequest request = registration.getRequest(); // passive requests do not contribute to the provider request - if (request.getIntervalMillis() == PASSIVE_INTERVAL) { + if (request.getIntervalMillis() == LocationRequest.PASSIVE_INTERVAL) { continue; } intervalMs = min(request.getIntervalMillis(), intervalMs); + quality = min(request.getQuality(), quality); locationSettingsIgnored |= request.isLocationSettingsIgnored(); lowPower &= request.isLowPower(); - locationRequests.add(request); } - if (intervalMs == INTERVAL_DISABLED) { - return EMPTY_REQUEST; + if (intervalMs == ProviderRequest.INTERVAL_DISABLED) { + return ProviderRequest.EMPTY_REQUEST; } // calculate who to blame for power in a somewhat arbitrary fashion. we pick a threshold @@ -1872,7 +1862,7 @@ class LocationProviderManager extends } catch (ArithmeticException e) { // check for and handle overflow by setting to one below the passive interval so passive // requests are automatically skipped - thresholdIntervalMs = PASSIVE_INTERVAL - 1; + thresholdIntervalMs = LocationRequest.PASSIVE_INTERVAL - 1; } WorkSource workSource = new WorkSource(); @@ -1884,9 +1874,9 @@ class LocationProviderManager extends return new ProviderRequest.Builder() .setIntervalMillis(intervalMs) + .setQuality(quality) .setLocationSettingsIgnored(locationSettingsIgnored) .setLowPower(lowPower) - .setLocationRequests(locationRequests) .setWorkSource(workSource) .build(); } diff --git a/services/core/java/com/android/server/location/PassiveLocationProviderManager.java b/services/core/java/com/android/server/location/PassiveLocationProviderManager.java index fc10d5fcf1b71..b7718611cffc5 100644 --- a/services/core/java/com/android/server/location/PassiveLocationProviderManager.java +++ b/services/core/java/com/android/server/location/PassiveLocationProviderManager.java @@ -63,15 +63,7 @@ class PassiveLocationProviderManager extends LocationProviderManager { @Override protected ProviderRequest mergeRegistrations(Collection registrations) { - boolean locationSettingsIgnored = false; - for (Registration registration : registrations) { - locationSettingsIgnored |= registration.getRequest().isLocationSettingsIgnored(); - } - - return new ProviderRequest.Builder() - .setIntervalMillis(0) - .setLocationSettingsIgnored(locationSettingsIgnored) - .build(); + return new ProviderRequest.Builder().setIntervalMillis(0).build(); } @Override @@ -79,4 +71,9 @@ class PassiveLocationProviderManager extends LocationProviderManager { Collection registrations) { return 0; } + + @Override + protected String getServiceState() { + return mProvider.getCurrentRequest().isActive() ? "registered" : "unregistered"; + } } diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index e144b403240c3..e25e605cf7d2c 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -708,12 +708,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // For fast GNSS TTFF provider = LocationManager.NETWORK_PROVIDER; locationListener = mNetworkLocationListener; - locationRequest.setQuality(LocationRequest.POWER_LOW); + locationRequest.setQuality(LocationRequest.QUALITY_LOW_POWER); } else { // For Device-Based Hybrid (E911) provider = LocationManager.FUSED_PROVIDER; locationListener = mFusedLocationListener; - locationRequest.setQuality(LocationRequest.ACCURACY_FINE); + locationRequest.setQuality(LocationRequest.QUALITY_HIGH_ACCURACY); } // Ignore location settings if in emergency mode. This is only allowed for diff --git a/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java index 31ec4a53908cc..3aedd3c7d753a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java @@ -710,7 +710,6 @@ public class LocationProviderManagerTest { @Test public void testProviderRequest() { assertThat(mProvider.getRequest().isActive()).isFalse(); - assertThat(mProvider.getRequest().getLocationRequests()).isEmpty(); ILocationListener listener1 = createMockLocationListener(); LocationRequest request1 = new LocationRequest.Builder(5).setWorkSource( @@ -718,7 +717,6 @@ public class LocationProviderManagerTest { mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); assertThat(mProvider.getRequest().isActive()).isTrue(); - assertThat(mProvider.getRequest().getLocationRequests()).containsExactly(request1); assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); assertThat(mProvider.getRequest().isLowPower()).isFalse(); @@ -732,8 +730,6 @@ public class LocationProviderManagerTest { mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); assertThat(mProvider.getRequest().isActive()).isTrue(); - assertThat(mProvider.getRequest().getLocationRequests()).containsExactly(request1, - request2); assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); assertThat(mProvider.getRequest().isLowPower()).isFalse(); @@ -742,7 +738,6 @@ public class LocationProviderManagerTest { mManager.unregisterLocationRequest(listener1); assertThat(mProvider.getRequest().isActive()).isTrue(); - assertThat(mProvider.getRequest().getLocationRequests()).containsExactly(request2); assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); assertThat(mProvider.getRequest().isLowPower()).isTrue(); @@ -751,7 +746,6 @@ public class LocationProviderManagerTest { mManager.unregisterLocationRequest(listener2); assertThat(mProvider.getRequest().isActive()).isFalse(); - assertThat(mProvider.getRequest().getLocationRequests()).isEmpty(); } @Test @@ -855,7 +849,6 @@ public class LocationProviderManagerTest { mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId()); assertThat(mProvider.getRequest().isActive()).isTrue(); - assertThat(mProvider.getRequest().getLocationRequests()).containsExactly(request2); assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue(); }