Add expireIn implementation to LocationRequest
Clients should no longer need to reset expireIn every time they make a location request. Also allow clients of getCurrentLocation() to set their own timeout if desired, and enforce a timeout for requestSingleUpdate(). Bug: 133356925 Bug: 142956404 Test: atest LocationManagerTest Change-Id: I1b3a4d8d6ef249a2395b0d30bf7b92a8d4cfe933
This commit is contained in:
@@ -3478,7 +3478,8 @@ package android.location {
|
||||
method @NonNull public static android.location.LocationRequest createFromDeprecatedCriteria(@NonNull android.location.Criteria, long, float, boolean);
|
||||
method @NonNull public static android.location.LocationRequest createFromDeprecatedProvider(@NonNull String, long, float, boolean);
|
||||
method public int describeContents();
|
||||
method public long getExpireAt();
|
||||
method @Deprecated public long getExpireAt();
|
||||
method public long getExpireIn();
|
||||
method public long getFastestInterval();
|
||||
method public boolean getHideFromAppOps();
|
||||
method public long getInterval();
|
||||
@@ -3489,7 +3490,7 @@ package android.location {
|
||||
method @Nullable public android.os.WorkSource getWorkSource();
|
||||
method public boolean isLocationSettingsIgnored();
|
||||
method public boolean isLowPowerMode();
|
||||
method @NonNull public android.location.LocationRequest setExpireAt(long);
|
||||
method @Deprecated @NonNull public android.location.LocationRequest setExpireAt(long);
|
||||
method @NonNull public android.location.LocationRequest setExpireIn(long);
|
||||
method @NonNull public android.location.LocationRequest setFastestInterval(long);
|
||||
method public void setHideFromAppOps(boolean);
|
||||
|
||||
@@ -1136,17 +1136,20 @@ package android.location {
|
||||
public final class LocationRequest implements android.os.Parcelable {
|
||||
method @NonNull public static android.location.LocationRequest create();
|
||||
method public int describeContents();
|
||||
method public long getExpireAt();
|
||||
method @Deprecated public long getExpireAt();
|
||||
method public long getExpireIn();
|
||||
method public long getFastestInterval();
|
||||
method public long getInterval();
|
||||
method public int getNumUpdates();
|
||||
method public int getQuality();
|
||||
method public boolean isLocationSettingsIgnored();
|
||||
method @NonNull public android.location.LocationRequest setExpireAt(long);
|
||||
method public boolean isLowPowerMode();
|
||||
method @Deprecated @NonNull public android.location.LocationRequest setExpireAt(long);
|
||||
method @NonNull public android.location.LocationRequest setExpireIn(long);
|
||||
method @NonNull public android.location.LocationRequest setFastestInterval(long);
|
||||
method @NonNull public android.location.LocationRequest setInterval(long);
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @NonNull public android.location.LocationRequest setLocationSettingsIgnored(boolean);
|
||||
method @NonNull public android.location.LocationRequest setLowPowerMode(boolean);
|
||||
method @NonNull public android.location.LocationRequest setNumUpdates(int);
|
||||
method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
|
||||
method @NonNull public android.location.LocationRequest setQuality(int);
|
||||
|
||||
@@ -230,7 +230,7 @@ public class LocationManager {
|
||||
public static final String METADATA_SETTINGS_FOOTER_STRING =
|
||||
"com.android.settings.location.FOOTER_STRING";
|
||||
|
||||
private static final long GET_CURRENT_LOCATION_TIMEOUT_MS = 30 * 1000;
|
||||
private static final long GET_CURRENT_LOCATION_MAX_TIMEOUT_MS = 30 * 1000;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
@@ -628,7 +628,10 @@ public class LocationManager {
|
||||
@Nullable CancellationSignal cancellationSignal,
|
||||
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) {
|
||||
LocationRequest currentLocationRequest = new LocationRequest(locationRequest)
|
||||
.setNumUpdates(1).setExpireIn(GET_CURRENT_LOCATION_TIMEOUT_MS);
|
||||
.setNumUpdates(1);
|
||||
if (currentLocationRequest.getExpireIn() > GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) {
|
||||
currentLocationRequest.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
GetCurrentLocationTransport listenerTransport = new GetCurrentLocationTransport(executor,
|
||||
consumer);
|
||||
@@ -682,6 +685,7 @@ public class LocationManager {
|
||||
|
||||
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
|
||||
provider, 0, 0, true);
|
||||
request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
|
||||
requestLocationUpdates(request, listener, looper);
|
||||
}
|
||||
|
||||
@@ -712,6 +716,7 @@ public class LocationManager {
|
||||
|
||||
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
|
||||
criteria, 0, 0, true);
|
||||
request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
|
||||
requestLocationUpdates(request, listener, looper);
|
||||
}
|
||||
|
||||
@@ -738,6 +743,7 @@ public class LocationManager {
|
||||
|
||||
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
|
||||
provider, 0, 0, true);
|
||||
request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
|
||||
requestLocationUpdates(request, pendingIntent);
|
||||
}
|
||||
|
||||
@@ -765,6 +771,7 @@ public class LocationManager {
|
||||
|
||||
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
|
||||
criteria, 0, 0, true);
|
||||
request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
|
||||
requestLocationUpdates(request, pendingIntent);
|
||||
}
|
||||
|
||||
@@ -2418,7 +2425,7 @@ public class LocationManager {
|
||||
mAlarmManager = alarmManager;
|
||||
mAlarmManager.set(
|
||||
ELAPSED_REALTIME,
|
||||
SystemClock.elapsedRealtime() + GET_CURRENT_LOCATION_TIMEOUT_MS,
|
||||
SystemClock.elapsedRealtime() + GET_CURRENT_LOCATION_MAX_TIMEOUT_MS,
|
||||
"GetCurrentLocation",
|
||||
this,
|
||||
null);
|
||||
|
||||
@@ -30,6 +30,8 @@ import android.os.SystemClock;
|
||||
import android.os.WorkSource;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
|
||||
/**
|
||||
* A data object that contains quality of service parameters for requests
|
||||
@@ -159,6 +161,7 @@ public final class LocationRequest implements Parcelable {
|
||||
private boolean mExplicitFastestInterval = false;
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
private long mExpireAt = Long.MAX_VALUE; // no expiry
|
||||
private long mExpireIn = Long.MAX_VALUE; // no expiry
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
private int mNumUpdates = Integer.MAX_VALUE; // no expiry
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
@@ -262,6 +265,7 @@ public final class LocationRequest implements Parcelable {
|
||||
mFastestInterval = src.mFastestInterval;
|
||||
mExplicitFastestInterval = src.mExplicitFastestInterval;
|
||||
mExpireAt = src.mExpireAt;
|
||||
mExpireIn = src.mExpireIn;
|
||||
mNumUpdates = src.mNumUpdates;
|
||||
mSmallestDisplacement = src.mSmallestDisplacement;
|
||||
mProvider = src.mProvider;
|
||||
@@ -336,7 +340,7 @@ public final class LocationRequest implements Parcelable {
|
||||
* @throws IllegalArgumentException if the interval is less than zero
|
||||
*/
|
||||
public @NonNull LocationRequest setInterval(long millis) {
|
||||
checkInterval(millis);
|
||||
Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
|
||||
mInterval = millis;
|
||||
if (!mExplicitFastestInterval) {
|
||||
mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR);
|
||||
@@ -364,9 +368,7 @@ public final class LocationRequest implements Parcelable {
|
||||
*
|
||||
* @param enabled Enable or disable low power mode
|
||||
* @return the same object, so that setters can be chained
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
|
||||
mLowPowerMode = enabled;
|
||||
return this;
|
||||
@@ -374,10 +376,7 @@ public final class LocationRequest implements Parcelable {
|
||||
|
||||
/**
|
||||
* Returns true if low power mode is enabled.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public boolean isLowPowerMode() {
|
||||
return mLowPowerMode;
|
||||
}
|
||||
@@ -425,93 +424,80 @@ public final class LocationRequest implements Parcelable {
|
||||
* <p>An interval of 0 is allowed, but not recommended, since
|
||||
* location updates may be extremely fast on future implementations.
|
||||
*
|
||||
* <p>If {@link #setFastestInterval} is set slower than {@link #setInterval},
|
||||
* <p>If the fastest interval set is slower than {@link #setInterval},
|
||||
* then your effective fastest interval is {@link #setInterval}.
|
||||
*
|
||||
* @param millis fastest interval for updates in milliseconds, exact
|
||||
* @param millis fastest interval for updates in milliseconds
|
||||
* @return the same object, so that setters can be chained
|
||||
* @throws IllegalArgumentException if the interval is less than zero
|
||||
*/
|
||||
public @NonNull LocationRequest setFastestInterval(long millis) {
|
||||
checkInterval(millis);
|
||||
Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
|
||||
mExplicitFastestInterval = true;
|
||||
mFastestInterval = millis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fastest interval of this request, in milliseconds.
|
||||
* Get the fastest interval of this request in milliseconds. The system will never provide
|
||||
* location updates faster than the minimum of the fastest interval and {@link #getInterval}.
|
||||
*
|
||||
* <p>The system will never provide location updates faster
|
||||
* than the minimum of {@link #getFastestInterval} and
|
||||
* {@link #getInterval}.
|
||||
*
|
||||
* @return fastest interval in milliseconds, exact
|
||||
* @return fastest interval in milliseconds
|
||||
*/
|
||||
public long getFastestInterval() {
|
||||
return mFastestInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the duration of this request, in milliseconds.
|
||||
* Set the expiration time of this request in milliseconds of realtime since boot. Values in the
|
||||
* past are allowed, but indicate that the request has already expired. The location manager
|
||||
* will automatically stop updates after the request expires.
|
||||
*
|
||||
* <p>The duration begins immediately (and not when the request
|
||||
* is passed to the location manager), so call this method again
|
||||
* if the request is re-used at a later time.
|
||||
* @param millis expiration time of request in milliseconds since boot
|
||||
* @return the same object, so that setters can be chained
|
||||
* @see SystemClock#elapsedRealtime()
|
||||
* @deprecated Prefer {@link #setExpireIn(long)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public @NonNull LocationRequest setExpireAt(long millis) {
|
||||
mExpireAt = Math.max(millis, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request expiration time in milliseconds of realtime since boot.
|
||||
*
|
||||
* <p>The location manager will automatically stop updates after
|
||||
* the request expires.
|
||||
*
|
||||
* <p>The duration includes suspend time. Values less than 0
|
||||
* are allowed, but indicate that the request has already expired.
|
||||
* @return request expiration time in milliseconds since boot
|
||||
* @see SystemClock#elapsedRealtime()
|
||||
* @deprecated Prefer {@link #getExpireIn()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public long getExpireAt() {
|
||||
return mExpireAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the duration of this request in milliseconds of realtime. Values less than 0 are allowed,
|
||||
* but indicate that the request has already expired. The location manager will automatically
|
||||
* stop updates after the request expires.
|
||||
*
|
||||
* @param millis duration of request in milliseconds
|
||||
* @return the same object, so that setters can be chained
|
||||
* @see SystemClock#elapsedRealtime()
|
||||
*/
|
||||
public @NonNull LocationRequest setExpireIn(long millis) {
|
||||
long elapsedRealtime = SystemClock.elapsedRealtime();
|
||||
|
||||
// Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
|
||||
if (millis > Long.MAX_VALUE - elapsedRealtime) {
|
||||
mExpireAt = Long.MAX_VALUE;
|
||||
} else {
|
||||
mExpireAt = millis + elapsedRealtime;
|
||||
}
|
||||
|
||||
if (mExpireAt < 0) mExpireAt = 0;
|
||||
mExpireIn = millis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the request expiration time, in millisecond since boot.
|
||||
* Get the request expiration duration in milliseconds of realtime.
|
||||
*
|
||||
* <p>This expiration time uses the same time base as {@link SystemClock#elapsedRealtime}.
|
||||
*
|
||||
* <p>The location manager will automatically stop updates after
|
||||
* the request expires.
|
||||
*
|
||||
* <p>The duration includes suspend time. Values before {@link SystemClock#elapsedRealtime}
|
||||
* are allowed, but indicate that the request has already expired.
|
||||
*
|
||||
* @param millis expiration time of request, in milliseconds since boot including suspend
|
||||
* @return the same object, so that setters can be chained
|
||||
* @return request expiration duration in milliseconds
|
||||
* @see SystemClock#elapsedRealtime()
|
||||
*/
|
||||
public @NonNull LocationRequest setExpireAt(long millis) {
|
||||
mExpireAt = millis;
|
||||
if (mExpireAt < 0) mExpireAt = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request expiration time, in milliseconds since boot.
|
||||
*
|
||||
* <p>This value can be compared to {@link SystemClock#elapsedRealtime} to determine
|
||||
* the time until expiration.
|
||||
*
|
||||
* @return expiration time of request, in milliseconds since boot including suspend
|
||||
*/
|
||||
public long getExpireAt() {
|
||||
return mExpireAt;
|
||||
public long getExpireIn() {
|
||||
return mExpireIn;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -631,13 +617,6 @@ public final class LocationRequest implements Parcelable {
|
||||
return mHideFromAppOps;
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
private static void checkInterval(long millis) {
|
||||
if (millis < 0) {
|
||||
throw new IllegalArgumentException("invalid interval: " + millis);
|
||||
}
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
private static void checkQuality(int quality) {
|
||||
switch (quality) {
|
||||
@@ -676,6 +655,7 @@ public final class LocationRequest implements Parcelable {
|
||||
request.setFastestInterval(in.readLong());
|
||||
request.setInterval(in.readLong());
|
||||
request.setExpireAt(in.readLong());
|
||||
request.setExpireIn(in.readLong());
|
||||
request.setNumUpdates(in.readInt());
|
||||
request.setSmallestDisplacement(in.readFloat());
|
||||
request.setHideFromAppOps(in.readInt() != 0);
|
||||
@@ -705,6 +685,7 @@ public final class LocationRequest implements Parcelable {
|
||||
parcel.writeLong(mFastestInterval);
|
||||
parcel.writeLong(mInterval);
|
||||
parcel.writeLong(mExpireAt);
|
||||
parcel.writeLong(mExpireIn);
|
||||
parcel.writeInt(mNumUpdates);
|
||||
parcel.writeFloat(mSmallestDisplacement);
|
||||
parcel.writeInt(mHideFromAppOps ? 1 : 0);
|
||||
@@ -747,9 +728,11 @@ public final class LocationRequest implements Parcelable {
|
||||
s.append(" fastest=");
|
||||
TimeUtils.formatDuration(mFastestInterval, s);
|
||||
if (mExpireAt != Long.MAX_VALUE) {
|
||||
long expireIn = mExpireAt - SystemClock.elapsedRealtime();
|
||||
s.append(" expireAt=").append(TimeUtils.formatUptime(mExpireAt));
|
||||
}
|
||||
if (mExpireIn != Long.MAX_VALUE) {
|
||||
s.append(" expireIn=");
|
||||
TimeUtils.formatDuration(expireIn, s);
|
||||
TimeUtils.formatDuration(mExpireIn, s);
|
||||
}
|
||||
if (mNumUpdates != Integer.MAX_VALUE) {
|
||||
s.append(" num=").append(mNumUpdates);
|
||||
|
||||
@@ -2044,6 +2044,18 @@ public class LocationManagerService extends ILocationManager.Stub {
|
||||
* Note: must be constructed with lock held.
|
||||
*/
|
||||
private UpdateRecord(String provider, LocationRequest request, Receiver receiver) {
|
||||
// translate expireIn value into expireAt
|
||||
long elapsedRealtime = SystemClock.elapsedRealtime();
|
||||
long expireAt;
|
||||
// Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
|
||||
if (request.getExpireIn() > Long.MAX_VALUE - elapsedRealtime) {
|
||||
expireAt = Long.MAX_VALUE;
|
||||
} else {
|
||||
expireAt = Math.max(request.getExpireIn() + elapsedRealtime, 0);
|
||||
}
|
||||
request.setExpireAt(Math.min(request.getExpireAt(), expireAt));
|
||||
request.setExpireIn(Long.MAX_VALUE);
|
||||
|
||||
mProvider = provider;
|
||||
mRealRequest = request;
|
||||
mRequest = request;
|
||||
|
||||
Reference in New Issue
Block a user