From 54ca7aef2e12b240caa6fb1a1e65abd234bea337 Mon Sep 17 00:00:00 2001 From: Victoria Lease Date: Tue, 8 Jan 2013 09:39:50 -0800 Subject: [PATCH] Annotate Locations coming from mock providers LocationManagerService now annotates incoming Location objects that have come from mock location providers. The new isFromMockProvider() method can be called on any Location to determine whether the provider that supplied the Location was a mock location provider. Bug: 6813235 Change-Id: Ib5140e93ea427f2e0b0036151047f87a02b4d23a --- api/current.txt | 1 + location/java/android/location/Location.java | 25 +++++++++++++++++++ .../android/location/LocationManager.java | 6 ++--- .../server/LocationManagerService.java | 22 +++++++++++++--- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/api/current.txt b/api/current.txt index d367a00bc3479..08e9e75d4bcd8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -10688,6 +10688,7 @@ package android.location { method public boolean hasAltitude(); method public boolean hasBearing(); method public boolean hasSpeed(); + method public boolean isFromMockProvider(); method public void removeAccuracy(); method public void removeAltitude(); method public void removeBearing(); diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 9b3266739f7c0..f70110cd59105 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -91,6 +91,7 @@ public class Location implements Parcelable { private boolean mHasAccuracy = false; private float mAccuracy = 0.0f; private Bundle mExtras = null; + private boolean mIsFromMockProvider = false; // Cache the inputs and outputs of computeDistanceAndBearing // so calls to distanceTo() and bearingTo() can share work @@ -140,6 +141,7 @@ public class Location implements Parcelable { mHasAccuracy = l.mHasAccuracy; mAccuracy = l.mAccuracy; mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras); + mIsFromMockProvider = l.mIsFromMockProvider; } /** @@ -160,6 +162,7 @@ public class Location implements Parcelable { mHasAccuracy = false; mAccuracy = 0; mExtras = null; + mIsFromMockProvider = false; } /** @@ -840,6 +843,7 @@ public class Location implements Parcelable { if (mHasAltitude) s.append(" alt=").append(mAltitude); if (mHasSpeed) s.append(" vel=").append(mSpeed); if (mHasBearing) s.append(" bear=").append(mBearing); + if (mIsFromMockProvider) s.append(" mock"); if (mExtras != null) { s.append(" {").append(mExtras).append('}'); @@ -871,6 +875,7 @@ public class Location implements Parcelable { l.mHasAccuracy = in.readInt() != 0; l.mAccuracy = in.readFloat(); l.mExtras = in.readBundle(); + l.mIsFromMockProvider = in.readInt() != 0; return l; } @@ -901,6 +906,7 @@ public class Location implements Parcelable { parcel.writeInt(mHasAccuracy ? 1 : 0); parcel.writeFloat(mAccuracy); parcel.writeBundle(mExtras); + parcel.writeInt(mIsFromMockProvider? 1 : 0); } /** @@ -934,4 +940,23 @@ public class Location implements Parcelable { } mExtras.putParcelable(key, value); } + + /** + * Returns true if the Location came from a mock provider. + * + * @return true if this Location came from a mock provider, false otherwise + */ + public boolean isFromMockProvider() { + return mIsFromMockProvider; + } + + /** + * Flag this Location as having come from a mock provider or not. + * + * @param isFromMockProvider true if this Location came from a mock provider, false otherwise + * @hide + */ + public void setIsFromMockProvider(boolean isFromMockProvider) { + mIsFromMockProvider = isFromMockProvider; + } } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 0b9286ed62d59..989178a86f7a3 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -1549,9 +1549,9 @@ public class LocationManager { public GpsStatus getGpsStatus(GpsStatus status) { if (status == null) { status = new GpsStatus(); - } - status.setStatus(mGpsStatus); - return status; + } + status.setStatus(mGpsStatus); + return status; } /** diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index b351fc296fbeb..7218a280e2e8c 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -1784,17 +1784,33 @@ public class LocationManagerService extends ILocationManager.Stub { } } + private boolean isMockProvider(String provider) { + synchronized (mLock) { + return mMockProviders.containsKey(provider); + } + } + private void handleLocationChanged(Location location, boolean passive) { - String provider = location.getProvider(); + // create a working copy of the incoming Location so that the service can modify it without + // disturbing the caller's copy + Location myLocation = new Location(location); + String provider = myLocation.getProvider(); + + // set "isFromMockProvider" bit if location came from a mock provider. we do not clear this + // bit if location did not come from a mock provider because passive/fused providers can + // forward locations from mock providers, and should not grant them legitimacy in doing so. + if (!myLocation.isFromMockProvider() && isMockProvider(provider)) { + myLocation.setIsFromMockProvider(true); + } if (!passive) { // notify passive provider of the new location - mPassiveProvider.updateLocation(location); + mPassiveProvider.updateLocation(myLocation); } synchronized (mLock) { if (isAllowedBySettingsLocked(provider, mCurrentUserId)) { - handleLocationChangedLocked(location, passive); + handleLocationChangedLocked(myLocation, passive); } } }