Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17e3e9e5 authored by Victoria Lease's avatar Victoria Lease Committed by Android (Google) Code Review
Browse files

Merge "Do not use passive GPS data for COARSE only apps." into jb-mr1-dev

parents e3f2ac9e 09016ab4
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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.
+4 −0
Original line number Diff line number Diff line
@@ -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);
+75 −36
Original line number Diff line number Diff line
@@ -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);
@@ -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,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,
@@ -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,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) &&
+4 −16
Original line number Diff line number Diff line
@@ -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;
    }

Loading