Update location time docs
Updates various docs around location time, and also fixes up some deprecated method usage. Bug: 184726840 Test: presubmits Change-Id: I79365e2a3608c8eaeba954b7c193775e98fb2a91
This commit is contained in:
@@ -508,15 +508,23 @@ public class Location implements Parcelable {
|
||||
/**
|
||||
* Return the UTC time of this location fix, in milliseconds since epoch (January 1, 1970).
|
||||
*
|
||||
* <p>Note that the UTC time on a device is not monotonic; it can jump forwards or backwards
|
||||
* unpredictably, so this time should not be used to calculate time deltas between locations.
|
||||
* Instead prefer {@link #getElapsedRealtimeNanos} for that purpose.
|
||||
* <p>There is no guarantee that different locations have times set from the same clock.
|
||||
* Locations derived from the {@link LocationManager#GPS_PROVIDER} are guaranteed to have their
|
||||
* time set from the clock in use by the satellite constellation that provided the fix.
|
||||
* Locations derived from other providers may use any clock to set their time, though it is most
|
||||
* common to use the device clock (which may be incorrect).
|
||||
*
|
||||
* <p>On the other hand, this method is useful for presenting a human readable time to the user,
|
||||
* or for carefully comparing location fixes across reboot or across devices.
|
||||
* <p>Note that the device clock UTC time is not monotonic; it can jump forwards or backwards
|
||||
* unpredictably and may be changed at any time by the user, so this time should not be used to
|
||||
* order or compare locations. Prefer {@link #getElapsedRealtimeNanos} for that purpose, as this
|
||||
* clock is guaranteed to be monotonic.
|
||||
*
|
||||
* <p>All locations generated by the {@link LocationManager} are guaranteed to have a UTC time,
|
||||
* however remember that the system time may have changed since the location was generated.
|
||||
* <p>On the other hand, this method may be useful for presenting a human readable time to the
|
||||
* user, or as a heuristic for comparing location fixes across reboot or across devices.
|
||||
*
|
||||
* <p>All locations generated by the {@link LocationManager} are guaranteed to have a UTC time
|
||||
* set, however remember that the device clock may have changed since the location was
|
||||
* generated.
|
||||
*
|
||||
* @return UTC time of fix, in milliseconds since January 1, 1970.
|
||||
*/
|
||||
@@ -534,53 +542,60 @@ public class Location implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time of this fix, in elapsed real-time since system boot.
|
||||
* Return the time of this fix in nanoseconds of elapsed realtime since system boot.
|
||||
*
|
||||
* <p>This value can be reliably compared to
|
||||
* {@link android.os.SystemClock#elapsedRealtimeNanos},
|
||||
* to calculate the age of a fix and to compare Location fixes. This
|
||||
* is reliable because elapsed real-time is guaranteed monotonic for
|
||||
* each system boot and continues to increment even when the system
|
||||
* is in deep sleep (unlike {@link #getTime}.
|
||||
* <p>This value can be compared with {@link android.os.SystemClock#elapsedRealtimeNanos}, to
|
||||
* reliably order or compare locations. This is reliable because elapsed realtime is guaranteed
|
||||
* to be monotonic and continues to increment even when the system is in deep sleep (unlike
|
||||
* {@link #getTime}). However, since elapsed realtime is with reference to system boot, it does
|
||||
* not make sense to use this value to order or compare locations across boot cycles.
|
||||
*
|
||||
* <p>All locations generated by the {@link LocationManager}
|
||||
* are guaranteed to have a valid elapsed real-time.
|
||||
* <p>All locations generated by the {@link LocationManager} are guaranteed to have a valid
|
||||
* elapsed realtime set.
|
||||
*
|
||||
* @return elapsed real-time of fix, in nanoseconds since system boot.
|
||||
* @return elapsed realtime of fix, in nanoseconds since system boot.
|
||||
*/
|
||||
public long getElapsedRealtimeNanos() {
|
||||
return mElapsedRealtimeNanos;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Return the time of this fix in milliseconds of elapsed realtime since system boot.
|
||||
*
|
||||
* @see #getElapsedRealtimeNanos()
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public long getElapsedRealtimeMillis() {
|
||||
return NANOSECONDS.toMillis(getElapsedRealtimeNanos());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public long getElapsedRealtimeAgeNanos(long referenceRealtimeNs) {
|
||||
return referenceRealtimeNs - mElapsedRealtimeNanos;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public long getElapsedRealtimeAgeNanos() {
|
||||
return getElapsedRealtimeAgeNanos(SystemClock.elapsedRealtimeNanos());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Returns the age of this fix with respect to the current elapsed realtime.
|
||||
*
|
||||
* @see #getElapsedRealtimeNanos()
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public long getElapsedRealtimeAgeMillis() {
|
||||
return getElapsedRealtimeAgeMillis(SystemClock.elapsedRealtime());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Returns the age of this fix with respect to the given elapsed realtime.
|
||||
*
|
||||
* @see #getElapsedRealtimeNanos()
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public long getElapsedRealtimeAgeMillis(long referenceRealtimeMs) {
|
||||
return referenceRealtimeMs - NANOSECONDS.toMillis(mElapsedRealtimeNanos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time of this fix, in elapsed real-time since system boot.
|
||||
* Set the time of this fix, in elapsed realtime since system boot.
|
||||
*
|
||||
* @param time elapsed real-time of fix, in nanoseconds since system boot.
|
||||
* @param time elapsed realtime of fix, in nanoseconds since system boot.
|
||||
*/
|
||||
public void setElapsedRealtimeNanos(long time) {
|
||||
mElapsedRealtimeNanos = time;
|
||||
@@ -1143,7 +1158,7 @@ public class Location implements Parcelable {
|
||||
s.append(" bAcc=").append(mBearingAccuracyDegrees);
|
||||
}
|
||||
}
|
||||
if (isFromMockProvider()) {
|
||||
if (isMock()) {
|
||||
s.append(" mock");
|
||||
}
|
||||
|
||||
@@ -1293,12 +1308,12 @@ public class Location implements Parcelable {
|
||||
* and {@link #bearingTo} don't duplicate work.
|
||||
*/
|
||||
private static class BearingDistanceCache {
|
||||
private double mLat1 = 0.0;
|
||||
private double mLon1 = 0.0;
|
||||
private double mLat2 = 0.0;
|
||||
private double mLon2 = 0.0;
|
||||
private float mDistance = 0.0f;
|
||||
private float mInitialBearing = 0.0f;
|
||||
private float mFinalBearing = 0.0f;
|
||||
double mLat1 = 0.0;
|
||||
double mLon1 = 0.0;
|
||||
double mLat2 = 0.0;
|
||||
double mLon2 = 0.0;
|
||||
float mDistance = 0.0f;
|
||||
float mInitialBearing = 0.0f;
|
||||
float mFinalBearing = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1953,7 +1953,7 @@ public class LocationManager {
|
||||
|
||||
/**
|
||||
* Sets a new location for the given test provider. This location will be identiable as a mock
|
||||
* location to all clients via {@link Location#isFromMockProvider()}.
|
||||
* location to all clients via {@link Location#isMock()}.
|
||||
*
|
||||
* <p>The location object must have a minimum number of fields set to be considered valid, as
|
||||
* per documentation on {@link Location} class.
|
||||
|
||||
@@ -115,7 +115,7 @@ public class SensorNotificationService extends SystemService
|
||||
"Location is (%f, %f), h %f, acc %f, mocked %b",
|
||||
location.getLatitude(), location.getLongitude(),
|
||||
location.getAltitude(), location.getAccuracy(),
|
||||
location.isFromMockProvider()));
|
||||
location.isMock()));
|
||||
|
||||
// lat long == 0 usually means invalid location
|
||||
if (location.getLatitude() == 0 && location.getLongitude() == 0) {
|
||||
@@ -130,7 +130,7 @@ public class SensorNotificationService extends SystemService
|
||||
long time = System.currentTimeMillis();
|
||||
// Mocked location should not be used. Except in test, only use mocked location
|
||||
// Wrong system clock also gives bad values so ignore as well.
|
||||
if (useMockedLocation() == location.isFromMockProvider() || time < MILLIS_2010_1_1) {
|
||||
if (useMockedLocation() == location.isMock() || time < MILLIS_2010_1_1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public class GeofenceManager extends
|
||||
private static final long WAKELOCK_TIMEOUT_MS = 30000;
|
||||
|
||||
private static final int MAX_SPEED_M_S = 100; // 360 km/hr (high speed train)
|
||||
private static final long MAX_LOCATION_AGE_NANOS = 5 * 60 * 1000000000L; // five minutes
|
||||
private static final long MAX_LOCATION_AGE_MS = 5 * 60 * 1000L; // five minutes
|
||||
private static final long MAX_LOCATION_INTERVAL_MS = 2 * 60 * 60 * 1000; // two hours
|
||||
|
||||
protected final class GeofenceRegistration extends
|
||||
@@ -472,7 +472,7 @@ public class GeofenceManager extends
|
||||
}
|
||||
|
||||
if (location != null) {
|
||||
if (location.getElapsedRealtimeAgeNanos() > MAX_LOCATION_AGE_NANOS) {
|
||||
if (location.getElapsedRealtimeAgeMillis() > MAX_LOCATION_AGE_MS) {
|
||||
location = null;
|
||||
}
|
||||
}
|
||||
@@ -480,25 +480,25 @@ public class GeofenceManager extends
|
||||
return location;
|
||||
}
|
||||
|
||||
private void onUserChanged(int userId, int change) {
|
||||
void onUserChanged(int userId, int change) {
|
||||
if (change == UserListener.CURRENT_USER_CHANGED) {
|
||||
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void onLocationEnabledChanged(int userId) {
|
||||
void onLocationEnabledChanged(int userId) {
|
||||
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
|
||||
}
|
||||
|
||||
private void onLocationPackageBlacklistChanged(int userId) {
|
||||
void onLocationPackageBlacklistChanged(int userId) {
|
||||
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
|
||||
}
|
||||
|
||||
private void onLocationPermissionsChanged(String packageName) {
|
||||
void onLocationPermissionsChanged(String packageName) {
|
||||
updateRegistrations(registration -> registration.onLocationPermissionsChanged(packageName));
|
||||
}
|
||||
|
||||
private void onLocationPermissionsChanged(int uid) {
|
||||
void onLocationPermissionsChanged(int uid) {
|
||||
updateRegistrations(registration -> registration.onLocationPermissionsChanged(uid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,7 +603,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
|
||||
Log.d(TAG, "injectBestLocation: " + location);
|
||||
}
|
||||
|
||||
if (location.isFromMockProvider()) {
|
||||
if (location.isMock()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -676,7 +676,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
|
||||
}
|
||||
|
||||
private void injectLocation(Location location) {
|
||||
if (!location.isFromMockProvider()) {
|
||||
if (!location.isMock()) {
|
||||
mGnssNative.injectLocation(location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -851,7 +851,7 @@ public class LocationProviderManager extends
|
||||
mUseWakeLock = false;
|
||||
final int size = locationResult.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (!locationResult.get(i).isFromMockProvider()) {
|
||||
if (!locationResult.get(i).isMock()) {
|
||||
mUseWakeLock = true;
|
||||
break;
|
||||
}
|
||||
@@ -2302,7 +2302,7 @@ public class LocationProviderManager extends
|
||||
LocationResult filtered;
|
||||
if (mPassiveManager != null) {
|
||||
filtered = locationResult.filter(location -> {
|
||||
if (!location.isFromMockProvider()) {
|
||||
if (!location.isMock()) {
|
||||
if (location.getLatitude() == 0 && location.getLongitude() == 0) {
|
||||
Log.w(TAG, "blocking 0,0 location from " + mName + " provider");
|
||||
return false;
|
||||
@@ -2539,16 +2539,16 @@ public class LocationProviderManager extends
|
||||
LastLocation() {}
|
||||
|
||||
public void clearMock() {
|
||||
if (mFineLocation != null && mFineLocation.isFromMockProvider()) {
|
||||
if (mFineLocation != null && mFineLocation.isMock()) {
|
||||
mFineLocation = null;
|
||||
}
|
||||
if (mCoarseLocation != null && mCoarseLocation.isFromMockProvider()) {
|
||||
if (mCoarseLocation != null && mCoarseLocation.isMock()) {
|
||||
mCoarseLocation = null;
|
||||
}
|
||||
if (mFineBypassLocation != null && mFineBypassLocation.isFromMockProvider()) {
|
||||
if (mFineBypassLocation != null && mFineBypassLocation.isMock()) {
|
||||
mFineBypassLocation = null;
|
||||
}
|
||||
if (mCoarseBypassLocation != null && mCoarseBypassLocation.isFromMockProvider()) {
|
||||
if (mCoarseBypassLocation != null && mCoarseBypassLocation.isMock()) {
|
||||
mCoarseBypassLocation = null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user