diff options
Diffstat (limited to 'location/java')
| -rw-r--r-- | location/java/android/location/ILocationManager.aidl | 2 | ||||
| -rw-r--r-- | location/java/android/location/LocationManager.java | 32 | ||||
| -rw-r--r-- | location/java/android/location/LocationProvider.java | 14 | ||||
| -rw-r--r-- | location/java/android/location/provider/ILocationProvider.aidl (renamed from location/java/com/android/internal/location/ILocationProvider.aidl) | 15 | ||||
| -rw-r--r-- | location/java/android/location/provider/ILocationProviderManager.aidl (renamed from location/java/com/android/internal/location/ILocationProviderManager.aidl) | 4 | ||||
| -rw-r--r-- | location/java/android/location/provider/LocationProviderBase.java | 307 | ||||
| -rw-r--r-- | location/java/android/location/provider/ProviderProperties.aidl (renamed from location/java/android/location/ProviderProperties.aidl) | 2 | ||||
| -rw-r--r-- | location/java/android/location/provider/ProviderProperties.java (renamed from location/java/android/location/ProviderProperties.java) | 141 | ||||
| -rw-r--r-- | location/java/android/location/provider/ProviderRequest.aidl (renamed from location/java/com/android/internal/location/ProviderRequest.aidl) | 2 | ||||
| -rw-r--r-- | location/java/android/location/provider/ProviderRequest.java (renamed from location/java/com/android/internal/location/ProviderRequest.java) | 104 |
10 files changed, 520 insertions, 103 deletions
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index c50904cad4e2..afae50203cd3 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -36,7 +36,7 @@ import android.location.LastLocationRequest; import android.location.Location; import android.location.LocationRequest; import android.location.LocationTime; -import android.location.ProviderProperties; +import android.location.provider.ProviderProperties; import android.os.Bundle; import android.os.ICancellationSignal; diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 1d3e8ebaa0ab..2dc9eb44236f 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -49,6 +49,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.location.provider.ProviderProperties; import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; @@ -1803,7 +1804,6 @@ public class LocationManager { } try { - ProviderProperties properties = mService.getProviderProperties(provider); return new LocationProvider(provider, properties); } catch (IllegalArgumentException e) { @@ -1931,11 +1931,35 @@ public class LocationManager { boolean supportsSpeed, boolean supportsBearing, @ProviderProperties.PowerUsage int powerUsage, @ProviderProperties.Accuracy int accuracy) { + addTestProvider(provider, new ProviderProperties.Builder() + .setHasNetworkRequirement(requiresNetwork) + .setHasSatelliteRequirement(requiresSatellite) + .setHasCellRequirement(requiresCell) + .setHasMonetaryCost(hasMonetaryCost) + .setHasAltitudeSupport(supportsAltitude) + .setHasSpeedSupport(supportsSpeed) + .setHasBearingSupport(supportsBearing) + .setPowerUsage(powerUsage) + .setAccuracy(accuracy) + .build()); + } + + /** + * Creates a test location provider and adds it to the set of active providers. This provider + * will replace any provider with the same name that exists prior to this call. + * + * @param provider the provider name + * + * @throws IllegalArgumentException if provider is null + * @throws IllegalArgumentException if properties is null + * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION + * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED + * allowed} for your app. + */ + public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties) { Preconditions.checkArgument(provider != null, "invalid null provider"); + Preconditions.checkArgument(properties != null, "invalid null properties"); - ProviderProperties properties = new ProviderProperties(requiresNetwork, - requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed, - supportsBearing, powerUsage, accuracy); try { mService.addTestProvider(provider, properties, mContext.getOpPackageName(), mContext.getFeatureId()); diff --git a/location/java/android/location/LocationProvider.java b/location/java/android/location/LocationProvider.java index 6d2bfed99fb7..60b251ea990d 100644 --- a/location/java/android/location/LocationProvider.java +++ b/location/java/android/location/LocationProvider.java @@ -17,6 +17,7 @@ package android.location; import android.annotation.Nullable; +import android.location.provider.ProviderProperties; /** * Information about the properties of a location provider. @@ -200,10 +201,8 @@ public class LocationProvider { } /** - * Returns the power requirement for this provider. - * - * @return the power requirement for this provider, as one of the - * constants ProviderProperties.POWER_USAGE_*. + * Returns the power requirement for this provider, one of the ProviderProperties.POWER_USAGE_* + * constants. */ public int getPowerRequirement() { if (mProperties == null) { @@ -214,11 +213,8 @@ public class LocationProvider { } /** - * Returns a constant describing horizontal accuracy of this provider. - * If the provider returns finer grain or exact location, - * {@link ProviderProperties#ACCURACY_FINE} is returned, otherwise if the - * location is only approximate then {@link ProviderProperties#ACCURACY_COARSE} - * is returned. + * Returns the rough accuracy of this provider, one of the ProviderProperties.ACCURACY_* + * constants. */ public int getAccuracy() { if (mProperties == null) { diff --git a/location/java/com/android/internal/location/ILocationProvider.aidl b/location/java/android/location/provider/ILocationProvider.aidl index dac08ff77938..f9995d5cf8b8 100644 --- a/location/java/com/android/internal/location/ILocationProvider.aidl +++ b/location/java/android/location/provider/ILocationProvider.aidl @@ -14,13 +14,12 @@ * limitations under the License. */ -package com.android.internal.location; +package android.location.provider; import android.os.Bundle; -import android.os.WorkSource; -import com.android.internal.location.ILocationProviderManager; -import com.android.internal.location.ProviderRequest; +import android.location.provider.ILocationProviderManager; +import android.location.provider.ProviderRequest; /** * Binder interface for services that implement location providers. Do not implement this directly, @@ -29,14 +28,8 @@ import com.android.internal.location.ProviderRequest; */ interface ILocationProvider { - @UnsupportedAppUsage(maxTargetSdk = 30, publicAlternatives = "{@code Do not use}") oneway void setLocationProviderManager(in ILocationProviderManager manager); - - @UnsupportedAppUsage(maxTargetSdk = 30, publicAlternatives = "{@code Do not use}") - oneway void setRequest(in ProviderRequest request, in WorkSource ws); - + oneway void setRequest(in ProviderRequest request); oneway void flush(); - - @UnsupportedAppUsage(maxTargetSdk = 30, publicAlternatives = "{@code Do not use}") oneway void sendExtraCommand(String command, in Bundle extras); } diff --git a/location/java/com/android/internal/location/ILocationProviderManager.aidl b/location/java/android/location/provider/ILocationProviderManager.aidl index a5b22b2c07d3..e3f51d9a23e1 100644 --- a/location/java/com/android/internal/location/ILocationProviderManager.aidl +++ b/location/java/android/location/provider/ILocationProviderManager.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.internal.location; +package android.location.provider; import android.location.LocationResult; -import android.location.ProviderProperties; +import android.location.provider.ProviderProperties; /** * Binder interface for manager of all location providers. diff --git a/location/java/android/location/provider/LocationProviderBase.java b/location/java/android/location/provider/LocationProviderBase.java new file mode 100644 index 000000000000..1306ea2c0204 --- /dev/null +++ b/location/java/android/location/provider/LocationProviderBase.java @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.location.provider; + +import static android.location.Location.EXTRA_NO_GPS_LOCATION; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.content.Context; +import android.content.Intent; +import android.location.Location; +import android.location.LocationResult; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import java.util.Objects; + +/** + * Base class for location providers outside the system server. + * + * Location providers should be wrapped in a non-exported service which returns the result of + * {@link #getBinder()} from the service's {@link android.app.Service#onBind(Intent)} method. The + * service should not be exported so that components other than the system server cannot bind to it. + * Alternatively, the service may be guarded by a permission that only system server can obtain. The + * service may specify metadata on its capabilities: + * + * <ul> + * <li> + * "serviceVersion": An integer version code to help tie break if multiple services are + * capable of implementing the same location provider. All else equal, the service with the + * highest version code will be chosen. Assumed to be 0 if not specified. + * </li> + * <li> + * "serviceIsMultiuser": A boolean property, indicating if the service wishes to take + * responsibility for handling changes to the current user on the device. If true, the + * service will always be bound from the system user. If false, the service will always be + * bound from the current user. If the current user changes, the old binding will be + * released, and a new binding established under the new user. Assumed to be false if not + * specified. + * </li> + * </ul> + * + * <p>The service should have an intent filter in place for the location provider it wishes to + * implements. Defaults for some providers are specified as constants in this class. + * + * @hide + */ +@SystemApi +public abstract class LocationProviderBase { + + /** + * Callback to be invoked when a flush operation is complete and all flushed locations have been + * reported. + */ + public interface OnFlushCompleteCallback { + + /** + * Should be invoked once the flush is complete. + */ + void onFlushComplete(); + } + + /** + * The action the wrapping service should have in its intent filter to implement the + * {@link android.location.LocationManager#NETWORK_PROVIDER}. + */ + @SuppressLint("ActionValue") + public static final String ACTION_NETWORK_PROVIDER = + "com.android.location.service.v3.NetworkLocationProvider"; + + /** + * The action the wrapping service should have in its intent filter to implement the + * {@link android.location.LocationManager#FUSED_PROVIDER}. + */ + @SuppressLint("ActionValue") + public static final String ACTION_FUSED_PROVIDER = + "com.android.location.service.FusedLocationProvider"; + + private final String mTag; + private final @Nullable String mPackageName; + private final @Nullable String mAttributionTag; + private final IBinder mBinder; + + // write locked on mBinder, read lock is optional depending on atomicity requirements + private @Nullable volatile ILocationProviderManager mManager; + private volatile ProviderProperties mProperties; + private volatile boolean mAllowed; + + public LocationProviderBase(@NonNull Context context, @NonNull String tag, + @NonNull ProviderProperties properties) { + mTag = tag; + mPackageName = context.getPackageName(); + mAttributionTag = context.getAttributionTag(); + mBinder = new Service(); + + mManager = null; + mProperties = Objects.requireNonNull(properties); + mAllowed = true; + } + + /** + * Returns the IBinder instance that should be returned from the + * {@link android.app.Service#onBind(Intent)} method of the wrapping service. + */ + public final @Nullable IBinder getBinder() { + return mBinder; + } + + /** + * Sets whether this provider is currently allowed or not. Note that this is specific to the + * provider only, and is unrelated to global location settings. This is a hint to the location + * manager that this provider will be unable to fulfill incoming requests. Setting a provider + * as not allowed will result in the provider being disabled. Setting a provider as allowed + * means that the provider may be in either the enabled or disabled state. + * + * <p>Some guidelines: providers should set their own allowed/disallowed status based only on + * state "owned" by that provider. For instance, providers should not take into account the + * state of the location master setting when setting themselves allowed or disallowed, as this + * state is not owned by a particular provider. If a provider requires some additional user + * consent that is particular to the provider, this should be use to set the allowed/disallowed + * state. If the provider proxies to another provider, the child provider's allowed/disallowed + * state should be taken into account in the parent's allowed state. For most providers, it is + * expected that they will be always allowed. + */ + public void setAllowed(boolean allowed) { + synchronized (mBinder) { + if (mAllowed == allowed) { + return; + } + + mAllowed = allowed; + } + + ILocationProviderManager manager = mManager; + if (manager != null) { + try { + manager.onSetAllowed(mAllowed); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { + Log.w(mTag, e); + } + } + } + + /** + * Returns true if this provider is allowed. Providers start as allowed on construction. + */ + public boolean isAllowed() { + return mAllowed; + } + + /** + * Sets the provider properties that may be queried by clients. Generally speaking, providers + * should try to avoid changing their properties after construction. + */ + public void setProperties(@NonNull ProviderProperties properties) { + synchronized (mBinder) { + mProperties = Objects.requireNonNull(properties); + } + + ILocationProviderManager manager = mManager; + if (manager != null) { + try { + manager.onSetProperties(mProperties); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { + Log.w(mTag, e); + } + } + } + + /** + * Returns the currently set properties of the provider. + */ + public @NonNull ProviderProperties getProperties() { + return mProperties; + } + + /** + * Reports a new location from this provider. + */ + public void reportLocation(@NonNull Location location) { + reportLocation(LocationResult.create(location)); + } + + /** + * Reports a new location result from this provider. + * + * <p>May only be used from Android S onwards. + */ + public void reportLocation(@NonNull LocationResult locationResult) { + ILocationProviderManager manager = mManager; + if (manager != null) { + locationResult = locationResult.map(location -> { + // remove deprecated extras to save on serialization costs + Bundle extras = location.getExtras(); + if (extras != null && (extras.containsKey(EXTRA_NO_GPS_LOCATION) + || extras.containsKey("coarseLocation"))) { + location = new Location(location); + extras = location.getExtras(); + extras.remove(EXTRA_NO_GPS_LOCATION); + extras.remove("coarseLocation"); + if (extras.isEmpty()) { + location.setExtras(null); + } + } + return location; + }); + + try { + manager.onReportLocation(locationResult); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { + Log.w(mTag, e); + } + } + } + + /** + * Set the current {@link ProviderRequest} for this provider. Each call to this method overrides + * any prior ProviderRequests. The provider should immediately attempt to provide locations (or + * not provide locations) according to the parameters of the provider request. + */ + public abstract void onSetRequest(@NonNull ProviderRequest request); + + /** + * Requests a flush of any pending batched locations. The callback must always be invoked once + * per invocation, and should be invoked after {@link #reportLocation(LocationResult)} has been + * invoked with any flushed locations. The callback may be invoked immediately if no locations + * are flushed. + */ + public abstract void onFlush(@NonNull OnFlushCompleteCallback callback); + + /** + * Implements optional custom commands. + */ + public abstract void onSendExtraCommand(@NonNull String command, @Nullable Bundle extras); + + private final class Service extends ILocationProvider.Stub { + + Service() {} + + @Override + public void setLocationProviderManager(ILocationProviderManager manager) { + synchronized (mBinder) { + try { + manager.onInitialize(mAllowed, mProperties, mPackageName, mAttributionTag); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { + Log.w(mTag, e); + } + + mManager = manager; + } + } + + @Override + public void setRequest(ProviderRequest request) { + onSetRequest(request); + } + + @Override + public void flush() { + onFlush(this::onFlushComplete); + } + + private void onFlushComplete() { + ILocationProviderManager manager = mManager; + if (manager != null) { + try { + manager.onFlushComplete(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { + Log.w(mTag, e); + } + } + } + + @Override + public void sendExtraCommand(String command, Bundle extras) { + onSendExtraCommand(command, extras); + } + } +} diff --git a/location/java/android/location/ProviderProperties.aidl b/location/java/android/location/provider/ProviderProperties.aidl index 8b1d79f90233..fd5a614b4fc8 100644 --- a/location/java/android/location/ProviderProperties.aidl +++ b/location/java/android/location/provider/ProviderProperties.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.location; +package android.location.provider; parcelable ProviderProperties; diff --git a/location/java/android/location/ProviderProperties.java b/location/java/android/location/provider/ProviderProperties.java index 8fa8c984b172..793401251de8 100644 --- a/location/java/android/location/ProviderProperties.java +++ b/location/java/android/location/provider/ProviderProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.location; +package android.location.provider; import android.annotation.IntDef; import android.annotation.NonNull; @@ -78,10 +78,7 @@ public final class ProviderProperties implements Parcelable { private final @PowerUsage int mPowerUsage; private final @Accuracy int mAccuracy; - /** - * @hide - */ - public ProviderProperties(boolean hasNetworkRequirement, boolean hasSatelliteRequirement, + private ProviderProperties(boolean hasNetworkRequirement, boolean hasSatelliteRequirement, boolean hasCellRequirement, boolean hasMonetaryCost, boolean hasAltitudeSupport, boolean hasSpeedSupport, boolean hasBearingSupport, @PowerUsage int powerUsage, @Accuracy int accuracy) { @@ -92,10 +89,8 @@ public final class ProviderProperties implements Parcelable { mHasAltitudeSupport = hasAltitudeSupport; mHasSpeedSupport = hasSpeedSupport; mHasBearingSupport = hasBearingSupport; - mPowerUsage = Preconditions.checkArgumentInRange(powerUsage, POWER_USAGE_LOW, - POWER_USAGE_HIGH, "powerUsage"); - mAccuracy = Preconditions.checkArgumentInRange(accuracy, ACCURACY_FINE, - ACCURACY_COARSE, "locationAccuracy"); + mPowerUsage = powerUsage; + mAccuracy = accuracy; } /** @@ -233,7 +228,7 @@ public final class ProviderProperties implements Parcelable { @Override public String toString() { StringBuilder b = new StringBuilder("ProviderProperties["); - b.append("power=").append(powerToString(mPowerUsage)).append(", "); + b.append("powerUsage=").append(powerToString(mPowerUsage)).append(", "); b.append("accuracy=").append(accuracyToString(mAccuracy)); if (mHasNetworkRequirement || mHasSatelliteRequirement || mHasCellRequirement) { b.append(", requires="); @@ -292,4 +287,128 @@ public final class ProviderProperties implements Parcelable { throw new AssertionError(); } } + + /** + * Builder for ProviderProperties. + */ + public static final class Builder { + + private boolean mHasNetworkRequirement; + private boolean mHasSatelliteRequirement; + private boolean mHasCellRequirement; + private boolean mHasMonetaryCost; + private boolean mHasAltitudeSupport; + private boolean mHasSpeedSupport; + private boolean mHasBearingSupport; + private @PowerUsage int mPowerUsage; + private @Accuracy int mAccuracy; + + public Builder() { + mHasNetworkRequirement = false; + mHasSatelliteRequirement = false; + mHasCellRequirement = false; + mHasMonetaryCost = false; + mHasAltitudeSupport = false; + mHasSpeedSupport = false; + mHasBearingSupport = false; + mPowerUsage = POWER_USAGE_HIGH; + mAccuracy = ACCURACY_COARSE; + } + + public Builder(@NonNull ProviderProperties providerProperties) { + mHasNetworkRequirement = providerProperties.mHasNetworkRequirement; + mHasSatelliteRequirement = providerProperties.mHasSatelliteRequirement; + mHasCellRequirement = providerProperties.mHasCellRequirement; + mHasMonetaryCost = providerProperties.mHasMonetaryCost; + mHasAltitudeSupport = providerProperties.mHasAltitudeSupport; + mHasSpeedSupport = providerProperties.mHasSpeedSupport; + mHasBearingSupport = providerProperties.mHasBearingSupport; + mPowerUsage = providerProperties.mPowerUsage; + mAccuracy = providerProperties.mAccuracy; + } + + /** + * Sets whether a provider requires network access. False by default. + */ + public @NonNull Builder setHasNetworkRequirement(boolean requiresNetwork) { + mHasNetworkRequirement = requiresNetwork; + return this; + } + + /** + * Sets whether a provider requires satellite access. False by default. + */ + public @NonNull Builder setHasSatelliteRequirement(boolean requiresSatellite) { + mHasSatelliteRequirement = requiresSatellite; + return this; + } + + /** + * Sets whether a provider requires cell tower access. False by default. + */ + public @NonNull Builder setHasCellRequirement(boolean requiresCell) { + mHasCellRequirement = requiresCell; + return this; + } + + /** + * Sets whether a provider has a monetary cost. False by default. + */ + public @NonNull Builder setHasMonetaryCost(boolean monetaryCost) { + mHasMonetaryCost = monetaryCost; + return this; + } + + /** + * Sets whether a provider can provide altitude information. False by default. + */ + public @NonNull Builder setHasAltitudeSupport(boolean supportsAltitude) { + mHasAltitudeSupport = supportsAltitude; + return this; + } + + /** + * Sets whether a provider can provide speed information. False by default. + */ + public @NonNull Builder setHasSpeedSupport(boolean supportsSpeed) { + mHasSpeedSupport = supportsSpeed; + return this; + } + + /** + * Sets whether a provider can provide bearing information. False by default. + */ + public @NonNull Builder setHasBearingSupport(boolean supportsBearing) { + mHasBearingSupport = supportsBearing; + return this; + } + + /** + * Sets a very rough bucket of provider power usage. {@link #POWER_USAGE_HIGH} by default. + */ + public @NonNull Builder setPowerUsage(@PowerUsage int powerUsage) { + mPowerUsage = Preconditions.checkArgumentInRange(powerUsage, POWER_USAGE_LOW, + POWER_USAGE_HIGH, "powerUsage"); + return this; + } + + /** + * Sets a very rough bucket of provider location accuracy. {@link #ACCURACY_COARSE} by + * default. + */ + public @NonNull Builder setAccuracy(@Accuracy int accuracy) { + mAccuracy = Preconditions.checkArgumentInRange(accuracy, ACCURACY_FINE, + ACCURACY_COARSE, "accuracy"); + return this; + } + + /** + * Builds a new ProviderProperties. + */ + public @NonNull ProviderProperties build() { + return new ProviderProperties(mHasNetworkRequirement, mHasSatelliteRequirement, + mHasCellRequirement, mHasMonetaryCost, mHasAltitudeSupport, mHasSpeedSupport, + mHasBearingSupport, mPowerUsage, mAccuracy); + } + } } diff --git a/location/java/com/android/internal/location/ProviderRequest.aidl b/location/java/android/location/provider/ProviderRequest.aidl index 4e1ea955c2e5..b98f3018fe2b 100644 --- a/location/java/com/android/internal/location/ProviderRequest.aidl +++ b/location/java/android/location/provider/ProviderRequest.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.internal.location; +package android.location.provider; parcelable ProviderRequest; diff --git a/location/java/com/android/internal/location/ProviderRequest.java b/location/java/android/location/provider/ProviderRequest.java index 545ea528826b..e543b040a2d4 100644 --- a/location/java/com/android/internal/location/ProviderRequest.java +++ b/location/java/android/location/provider/ProviderRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.internal.location; +package android.location.provider; import static android.location.LocationRequest.QUALITY_BALANCED_POWER_ACCURACY; import static android.location.LocationRequest.QUALITY_HIGH_ACCURACY; @@ -22,10 +22,9 @@ import static android.location.LocationRequest.QUALITY_LOW_POWER; import android.annotation.IntRange; import android.annotation.NonNull; -import android.compat.annotation.UnsupportedAppUsage; +import android.annotation.SystemApi; import android.location.LocationRequest; import android.location.LocationRequest.Quality; -import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.WorkSource; @@ -33,34 +32,25 @@ import android.util.TimeUtils; import com.android.internal.util.Preconditions; -import java.util.Collections; -import java.util.List; import java.util.Objects; /** * Location provider request. * @hide */ +@SystemApi public final class ProviderRequest implements Parcelable { public static final long INTERVAL_DISABLED = Long.MAX_VALUE; - public static final ProviderRequest EMPTY_REQUEST = new ProviderRequest( + public static final @NonNull ProviderRequest EMPTY_REQUEST = new ProviderRequest( INTERVAL_DISABLED, QUALITY_BALANCED_POWER_ACCURACY, 0, false, false, new WorkSource()); - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link " - + "ProviderRequest}") - public final boolean reportLocation; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link " - + "ProviderRequest}") - public final long interval; + private final long mIntervalMillis; private final @Quality int mQuality; private final long mMaxUpdateDelayMillis; private final boolean mLowPower; private final boolean mLocationSettingsIgnored; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link " - + "ProviderRequest}") - public final List<LocationRequest> locationRequests; private final WorkSource mWorkSource; private ProviderRequest( @@ -70,22 +60,11 @@ public final class ProviderRequest implements Parcelable { boolean lowPower, boolean locationSettingsIgnored, @NonNull WorkSource workSource) { - reportLocation = intervalMillis != INTERVAL_DISABLED; - interval = intervalMillis; + mIntervalMillis = intervalMillis; mQuality = quality; mMaxUpdateDelayMillis = maxUpdateDelayMillis; mLowPower = lowPower; mLocationSettingsIgnored = locationSettingsIgnored; - 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); } @@ -94,7 +73,7 @@ public final class ProviderRequest implements Parcelable { * request is inactive and does not require any locations to be reported. */ public boolean isActive() { - return interval != INTERVAL_DISABLED; + return mIntervalMillis != INTERVAL_DISABLED; } /** @@ -102,7 +81,7 @@ public final class ProviderRequest implements Parcelable { * {@link #INTERVAL_DISABLED} for an inactive request. */ public @IntRange(from = 0) long getIntervalMillis() { - return interval; + return mIntervalMillis; } /** @@ -148,29 +127,28 @@ public final class ProviderRequest implements Parcelable { return mWorkSource; } - public static final Parcelable.Creator<ProviderRequest> CREATOR = - new Parcelable.Creator<ProviderRequest>() { - @Override - public ProviderRequest createFromParcel(Parcel in) { - long intervalMillis = in.readLong(); - if (intervalMillis == INTERVAL_DISABLED) { - return EMPTY_REQUEST; - } else { - return new ProviderRequest( - intervalMillis, - /* quality= */ in.readInt(), - /* maxUpdateDelayMillis= */ in.readLong(), - /* lowPower= */ in.readBoolean(), - /* locationSettingsIgnored= */ in.readBoolean(), - /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); - } - } + public static final @NonNull Creator<ProviderRequest> CREATOR = new Creator<ProviderRequest>() { + @Override + public ProviderRequest createFromParcel(Parcel in) { + long intervalMillis = in.readLong(); + if (intervalMillis == INTERVAL_DISABLED) { + return EMPTY_REQUEST; + } else { + return new ProviderRequest( + intervalMillis, + /* quality= */ in.readInt(), + /* maxUpdateDelayMillis= */ in.readLong(), + /* lowPower= */ in.readBoolean(), + /* locationSettingsIgnored= */ in.readBoolean(), + /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); + } + } - @Override - public ProviderRequest[] newArray(int size) { - return new ProviderRequest[size]; - } - }; + @Override + public ProviderRequest[] newArray(int size) { + return new ProviderRequest[size]; + } + }; @Override public int describeContents() { @@ -178,9 +156,9 @@ public final class ProviderRequest implements Parcelable { } @Override - public void writeToParcel(Parcel parcel, int flags) { - parcel.writeLong(interval); - if (interval != INTERVAL_DISABLED) { + public void writeToParcel(@NonNull Parcel parcel, int flags) { + parcel.writeLong(mIntervalMillis); + if (mIntervalMillis != INTERVAL_DISABLED) { parcel.writeInt(mQuality); parcel.writeLong(mMaxUpdateDelayMillis); parcel.writeBoolean(mLowPower); @@ -199,10 +177,10 @@ public final class ProviderRequest implements Parcelable { } ProviderRequest that = (ProviderRequest) o; - if (interval == INTERVAL_DISABLED) { - return that.interval == INTERVAL_DISABLED; + if (mIntervalMillis == INTERVAL_DISABLED) { + return that.mIntervalMillis == INTERVAL_DISABLED; } else { - return interval == that.interval + return mIntervalMillis == that.mIntervalMillis && mQuality == that.mQuality && mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis && mLowPower == that.mLowPower @@ -213,16 +191,16 @@ public final class ProviderRequest implements Parcelable { @Override public int hashCode() { - return Objects.hash(interval, mQuality, mWorkSource); + return Objects.hash(mIntervalMillis, mQuality, mWorkSource); } @Override public String toString() { StringBuilder s = new StringBuilder(); s.append("ProviderRequest["); - if (interval != INTERVAL_DISABLED) { + if (mIntervalMillis != INTERVAL_DISABLED) { s.append("@"); - TimeUtils.formatDuration(interval, s); + TimeUtils.formatDuration(mIntervalMillis, s); if (mQuality != QUALITY_BALANCED_POWER_ACCURACY) { if (mQuality == QUALITY_HIGH_ACCURACY) { s.append(", HIGH_ACCURACY"); @@ -230,7 +208,7 @@ public final class ProviderRequest implements Parcelable { s.append(", LOW_POWER"); } } - if (mMaxUpdateDelayMillis / 2 > interval) { + if (mMaxUpdateDelayMillis / 2 > mIntervalMillis) { s.append(", maxUpdateDelay="); TimeUtils.formatDuration(mMaxUpdateDelayMillis, s); } @@ -253,7 +231,7 @@ public final class ProviderRequest implements Parcelable { /** * A Builder for {@link ProviderRequest}s. */ - public static class Builder { + public static final class Builder { private long mIntervalMillis = INTERVAL_DISABLED; private int mQuality = QUALITY_BALANCED_POWER_ACCURACY; private long mMaxUpdateDelayMillis = 0; |