Loading location/java/android/location/Location.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } location/java/android/location/LocationRequest.java +1 −1 Original line number Diff line number Diff line Loading @@ -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. Loading packages/FusedLocation/src/com/android/location/fused/FusionEngine.java +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/java/com/android/server/LocationManagerService.java +75 −36 Original line number Diff line number Diff line Loading @@ -900,10 +900,26 @@ 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)) { if (!isProviderAllowedByCoarsePermission(request.getProvider())) { throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); } switch (request.getQuality()) { case LocationRequest.ACCURACY_FINE: request.setQuality(LocationRequest.ACCURACY_BLOCK); Loading Loading @@ -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); Loading Loading @@ -1094,13 +1112,20 @@ 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 public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent, Loading Loading @@ -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(); Loading @@ -1361,25 +1398,27 @@ 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 notifyLocation = coarseLocation; // use coarse location if available } if (notifyLocation != null) { Location lastLoc = r.mLastFixBroadcast; if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) { if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r)) { if (lastLoc == null) { lastLoc = new Location(location); lastLoc = new Location(notifyLocation); r.mLastFixBroadcast = lastLoc; } else { lastLoc.set(location); lastLoc.set(notifyLocation); } if (!receiver.callLocationChangedLocked(location)) { if (!receiver.callLocationChangedLocked(notifyLocation)) { Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); receiverDead = true; } } } long prevStatusUpdateTime = r.mLastStatusBroadcast; if ((newStatusUpdateTime > prevStatusUpdateTime) && Loading services/java/com/android/server/location/LocationFudger.java +4 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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); } Loading @@ -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; } Loading Loading
location/java/android/location/Location.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }
location/java/android/location/LocationRequest.java +1 −1 Original line number Diff line number Diff line Loading @@ -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. Loading
packages/FusedLocation/src/com/android/location/fused/FusionEngine.java +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/java/com/android/server/LocationManagerService.java +75 −36 Original line number Diff line number Diff line Loading @@ -900,10 +900,26 @@ 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)) { if (!isProviderAllowedByCoarsePermission(request.getProvider())) { throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); } switch (request.getQuality()) { case LocationRequest.ACCURACY_FINE: request.setQuality(LocationRequest.ACCURACY_BLOCK); Loading Loading @@ -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); Loading Loading @@ -1094,13 +1112,20 @@ 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 public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent, Loading Loading @@ -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(); Loading @@ -1361,25 +1398,27 @@ 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 notifyLocation = coarseLocation; // use coarse location if available } if (notifyLocation != null) { Location lastLoc = r.mLastFixBroadcast; if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) { if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r)) { if (lastLoc == null) { lastLoc = new Location(location); lastLoc = new Location(notifyLocation); r.mLastFixBroadcast = lastLoc; } else { lastLoc.set(location); lastLoc.set(notifyLocation); } if (!receiver.callLocationChangedLocked(location)) { if (!receiver.callLocationChangedLocked(notifyLocation)) { Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); receiverDead = true; } } } long prevStatusUpdateTime = r.mLastStatusBroadcast; if ((newStatusUpdateTime > prevStatusUpdateTime) && Loading
services/java/com/android/server/location/LocationFudger.java +4 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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); } Loading @@ -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; } Loading