diff options
author | Victoria Lease <violets@google.com> | 2012-09-23 15:06:58 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-09-23 15:06:59 -0700 |
commit | 17e3e9e53c5fb9c92c8972a8d92659c6bef85831 (patch) | |
tree | e7d429e36069f950f9c2b47ed66b55acf4fb0a87 | |
parent | e3f2ac9e526e5b4de4d2ae113e644c1cb14b1ce6 (diff) | |
parent | 09016ab4dd056a16809419d612cb865a14980880 (diff) | |
download | frameworks_base-17e3e9e53c5fb9c92c8972a8d92659c6bef85831.zip frameworks_base-17e3e9e53c5fb9c92c8972a8d92659c6bef85831.tar.gz frameworks_base-17e3e9e53c5fb9c92c8972a8d92659c6bef85831.tar.bz2 |
Merge "Do not use passive GPS data for COARSE only apps." into jb-mr1-dev
6 files changed, 127 insertions, 54 deletions
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 2d94ddc..672e378 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -59,6 +59,16 @@ public class Location implements Parcelable { */ public static final int FORMAT_SECONDS = 2; + /** + * @hide + */ + public static final String EXTRA_COARSE_LOCATION = "coarseLocation"; + + /** + * @hide + */ + public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation"; + private String mProvider; private long mTime = 0; private long mElapsedRealtimeNano = 0; @@ -893,4 +903,36 @@ public class Location implements Parcelable { parcel.writeFloat(mAccuracy); parcel.writeBundle(mExtras); } + + /** + * Returns one of the optional extra {@link Location}s that can be attached + * to this Location. + * + * @param key the key associated with the desired extra Location + * @return the extra Location, or null if unavailable + * @hide + */ + public Location getExtraLocation(String key) { + if (mExtras != null) { + Parcelable value = mExtras.getParcelable(key); + if (value instanceof Location) { + return (Location) value; + } + } + return null; + } + + /** + * Attaches an extra {@link Location} to this Location. + * + * @param key the key associated with the Location extra + * @param location the Location to attach + * @hide + */ + public void setExtraLocation(String key, Location value) { + if (mExtras == null) { + mExtras = new Bundle(); + } + mExtras.putParcelable(key, value); + } } diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index b1863b8..f4f7b09 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -144,7 +144,7 @@ public final class LocationRequest implements Parcelable { private int mNumUpdates = Integer.MAX_VALUE; // no expiry private float mSmallestDisplacement = 0.0f; // meters - private String mProvider = null; // for deprecated API's that explicitly request a provider + private String mProvider = LocationManager.FUSED_PROVIDER; // for deprecated APIs that explicitly request a provider /** * Create a location request with default parameters. diff --git a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java index 1c22c7a..b83521a 100644 --- a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java +++ b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java @@ -302,6 +302,10 @@ public class FusionEngine implements LocationListener { 0.0, 360.0)); } + if (mNetworkLocation != null) { + fused.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, mNetworkLocation); + } + mFusedLocation = fused; mCallback.reportLocation(mFusedLocation); diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 197f6ab..840d432 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -900,25 +900,41 @@ public class LocationManagerService extends ILocationManager.Stub implements Run return receiver; } + private boolean isProviderAllowedByCoarsePermission(String provider) { + if (LocationManager.FUSED_PROVIDER.equals(provider)) { + return true; + } + if (LocationManager.PASSIVE_PROVIDER.equals(provider)) { + return true; + } + if (LocationManager.NETWORK_PROVIDER.equals(provider)) { + return true; + } + return false; + } + private String checkPermissionAndRequest(LocationRequest request) { String perm = checkPermission(); if (ACCESS_COARSE_LOCATION.equals(perm)) { - switch (request.getQuality()) { - case LocationRequest.ACCURACY_FINE: - request.setQuality(LocationRequest.ACCURACY_BLOCK); - break; - case LocationRequest.POWER_HIGH: - request.setQuality(LocationRequest.POWER_LOW); - break; - } - // throttle - if (request.getInterval() < LocationFudger.FASTEST_INTERVAL_MS) { - request.setInterval(LocationFudger.FASTEST_INTERVAL_MS); - } - if (request.getFastestInterval() < LocationFudger.FASTEST_INTERVAL_MS) { - request.setFastestInterval(LocationFudger.FASTEST_INTERVAL_MS); - } + if (!isProviderAllowedByCoarsePermission(request.getProvider())) { + throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); + } + switch (request.getQuality()) { + case LocationRequest.ACCURACY_FINE: + request.setQuality(LocationRequest.ACCURACY_BLOCK); + break; + case LocationRequest.POWER_HIGH: + request.setQuality(LocationRequest.POWER_LOW); + break; + } + // throttle + if (request.getInterval() < LocationFudger.FASTEST_INTERVAL_MS) { + request.setInterval(LocationFudger.FASTEST_INTERVAL_MS); + } + if (request.getFastestInterval() < LocationFudger.FASTEST_INTERVAL_MS) { + request.setFastestInterval(LocationFudger.FASTEST_INTERVAL_MS); + } } // make getFastestInterval() the minimum of interval and fastest interval if (request.getFastestInterval() > request.getInterval()) { @@ -990,7 +1006,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run // use the fused provider if (request == null) request = DEFAULT_LOCATION_REQUEST; String name = request.getProvider(); - if (name == null) name = LocationManager.FUSED_PROVIDER; + if (name == null) { + throw new IllegalArgumentException("provider name must not be null"); + } LocationProviderInterface provider = mProvidersByName.get(name); if (provider == null) { throw new IllegalArgumentException("provider doesn't exisit: " + provider); @@ -1094,12 +1112,19 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (!isAllowedBySettingsLocked(name)) return null; Location location = mLastLocation.get(name); + if (location == null) { + return null; + } if (ACCESS_FINE_LOCATION.equals(perm)) { return location; } else { - return mLocationFudger.getOrCreate(location); + Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); + if (noGPSLocation != null) { + return mLocationFudger.getOrCreate(noGPSLocation); + } } } + return null; } @Override @@ -1329,17 +1354,29 @@ public class LocationManagerService extends ILocationManager.Stub implements Run LocationProviderInterface p = mProvidersByName.get(provider); if (p == null) return; - // Add the coarse location as an extra - Location coarse = mLocationFudger.getOrCreate(location); - // Update last known locations + Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); + Location lastNoGPSLocation = null; Location lastLocation = mLastLocation.get(provider); if (lastLocation == null) { lastLocation = new Location(provider); mLastLocation.put(provider, lastLocation); + } else { + lastNoGPSLocation = lastLocation.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); + if (noGPSLocation == null && lastNoGPSLocation != null) { + // New location has no no-GPS location: adopt last no-GPS location. This is set + // directly into location because we do not want to notify COARSE clients. + location.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, lastNoGPSLocation); + } } lastLocation.set(location); + // Fetch coarse location + Location coarseLocation = null; + if (noGPSLocation != null && !noGPSLocation.equals(lastNoGPSLocation)) { + coarseLocation = mLocationFudger.getOrCreate(noGPSLocation); + } + // Fetch latest status update time long newStatusUpdateTime = p.getStatusUpdateTime(); @@ -1361,29 +1398,31 @@ public class LocationManagerService extends ILocationManager.Stub implements Run continue; } + Location notifyLocation = null; if (ACCESS_FINE_LOCATION.equals(receiver.mPermission)) { - location = lastLocation; // use fine location + notifyLocation = lastLocation; // use fine location } else { - location = coarse; // use coarse location - } - - Location lastLoc = r.mLastFixBroadcast; - if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) { - if (lastLoc == null) { - lastLoc = new Location(location); - r.mLastFixBroadcast = lastLoc; - } else { - lastLoc.set(location); - } - if (!receiver.callLocationChangedLocked(location)) { - Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); - receiverDead = true; + notifyLocation = coarseLocation; // use coarse location if available + } + if (notifyLocation != null) { + Location lastLoc = r.mLastFixBroadcast; + if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r)) { + if (lastLoc == null) { + lastLoc = new Location(notifyLocation); + r.mLastFixBroadcast = lastLoc; + } else { + lastLoc.set(notifyLocation); + } + if (!receiver.callLocationChangedLocked(notifyLocation)) { + Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); + receiverDead = true; + } } } long prevStatusUpdateTime = r.mLastStatusBroadcast; if ((newStatusUpdateTime > prevStatusUpdateTime) && - (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { + (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { r.mLastStatusBroadcast = newStatusUpdateTime; if (!receiver.callStatusChangedLocked(provider, status, extras)) { diff --git a/services/java/com/android/server/location/LocationFudger.java b/services/java/com/android/server/location/LocationFudger.java index 84fd255..2a68743 100644 --- a/services/java/com/android/server/location/LocationFudger.java +++ b/services/java/com/android/server/location/LocationFudger.java @@ -22,6 +22,7 @@ import java.security.SecureRandom; import android.content.Context; import android.database.ContentObserver; import android.location.Location; +import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.os.Parcelable; @@ -40,8 +41,6 @@ public class LocationFudger { private static final boolean D = false; private static final String TAG = "LocationFudge"; - private static final String EXTRA_COARSE_LOCATION = "coarseLocation"; - /** * Default coarse accuracy in meters. */ @@ -168,18 +167,10 @@ public class LocationFudger { */ public Location getOrCreate(Location location) { synchronized (mLock) { - Bundle extras = location.getExtras(); - if (extras == null) { - return addCoarseLocationExtraLocked(location); - } - Parcelable parcel = extras.getParcelable(EXTRA_COARSE_LOCATION); - if (parcel == null) { - return addCoarseLocationExtraLocked(location); - } - if (!(parcel instanceof Location)) { + Location coarse = location.getExtraLocation(Location.EXTRA_COARSE_LOCATION); + if (coarse == null) { return addCoarseLocationExtraLocked(location); } - Location coarse = (Location) parcel; if (coarse.getAccuracy() < mAccuracyInMeters) { return addCoarseLocationExtraLocked(location); } @@ -188,11 +179,8 @@ public class LocationFudger { } private Location addCoarseLocationExtraLocked(Location location) { - Bundle extras = location.getExtras(); - if (extras == null) extras = new Bundle(); Location coarse = createCoarseLocked(location); - extras.putParcelable(EXTRA_COARSE_LOCATION, coarse); - location.setExtras(extras); + location.setExtraLocation(Location.EXTRA_COARSE_LOCATION, coarse); return coarse; } diff --git a/services/java/com/android/server/location/PassiveProvider.java b/services/java/com/android/server/location/PassiveProvider.java index 0ce21b7..71bae07 100644 --- a/services/java/com/android/server/location/PassiveProvider.java +++ b/services/java/com/android/server/location/PassiveProvider.java @@ -114,6 +114,6 @@ public class PassiveProvider implements LocationProviderInterface { @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("mReportLocaiton=" + mReportLocation); + pw.println("mReportLocation=" + mReportLocation); } } |