Improve Location object.

Add getElapsedRealtimeNano():

Currently Location just has getTime() and setTime() based on UTC time.
This is entirely unreliable since it is not guaranteed monotonic.
There is a lot of code that compares fix age based on deltas -
and it is all broken in the case of a system clock change. System
clock can change when switching cellular networks (and in some
cases when switching towers).

Document the meaning of getAccuracy():
It is the horizontal, 95% confidence radius.

Make some fields mandatory if they are reported by a LocationProvider:

All Locations returned by a LocationProvider must include at the
minimum a lat, long, timestamps, and accuracy. This is necessary
to perform fused location. There are no public API's for applications
to feed locations into a location provider so this should not cause
any breakage.

If a LocationProvider does not fill in enough fields on a Location
object then it is dropped, and logged.

Bug: 4305998
Change-Id: I7df77125d8a64e174d7bc8c2708661b4f33461ea
This commit is contained in:
Nick Pelly
2012-07-18 13:13:37 -07:00
parent b8acd060d4
commit 2eeeec248a
7 changed files with 137 additions and 14 deletions

View File

@@ -19,11 +19,13 @@ package android.location;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.os.RemoteException;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import com.android.internal.location.DummyLocationProvider;
@@ -1220,8 +1222,11 @@ public class LocationManager {
}
/**
* Sets a mock location for the given provider. This location will be used in place
* of any actual location from the provider.
* Sets a mock location for the given provider.
* <p>This location will be used in place of any actual location from the provider.
* The location object must have a minimum number of fields set to be
* considered a valid LocationProvider Location, as per documentation
* on {@link Location} class.
*
* @param provider the provider name
* @param loc the mock location
@@ -1230,8 +1235,20 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
* @throws IllegalArgumentException if the location is incomplete
*/
public void setTestProviderLocation(String provider, Location loc) {
if (!loc.isComplete()) {
if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN) {
// for backwards compatibility, allow mock locations that are incomplete
Log.w(TAG, "Incomplete Location object", new Throwable());
loc.makeComplete();
} else {
throw new IllegalArgumentException(
"Location object not complete. Missing timestamps or accuracy?");
}
}
try {
mService.setTestProviderLocation(provider, loc);
} catch (RemoteException ex) {