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

Commit 03ca216a authored by Mike Lockwood's avatar Mike Lockwood
Browse files

New Location Manager APIs for Criteria based requests and single shot mode.



Use MS-Assisted mode for single shot GPS fixes if it is supported.

Add finer grained control over accuracy to the android.location.Criteria class
and location criteria logic from LocationManager to LocationManagerService

Change-Id: I156b1f6c6a45d255c87ff917cf3e9726a6d7a75b
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 4979601f
Loading
Loading
Loading
Loading
+239 −28
Original line number Diff line number Diff line
@@ -57,9 +57,81 @@ public class Criteria implements Parcelable {
     */
    public static final int ACCURACY_COARSE = 2;

    private int mAccuracy              = NO_REQUIREMENT;
    /**
     * A constant indicating a low location accuracy requirement
     * - may be used for horizontal, altitude, speed or bearing accuracy.
     * For horizontal and vertical position this corresponds to an accuracy
     * greater than 500 meters.  For speed and bearing, this corresponds
     * to greater than 5 meters/second velocity and 10 degrees for bearing.
     * {@hide}
     */
    public static final int ACCURACY_LOW = 1;

    /**
     * A constant indicating a medium accuracy requirement
     * - may be used for horizontal, altitude, speed or bearing accuracy.
     * For horizontal position this corresponds to an accuracy of between
     * 100 and 500 meters, and between 200 and 500 meters for vertical accuracy.
     * For speed and bearing, this corresponds to 1 meter/second to 5 meters/second
     * velocity and and between 5 and 10 degrees for bearing.
     * {@hide}
     */
    public static final int ACCURACY_MEDIUM = 2;

    /**
     * a constant indicating a high accuracy requirement
     * - may be used for horizontal, altitude, speed or bearing accuracy.
     * For horizontal and vertical position this corresponds to an accuracy
     * less than 100 meters.  For speed and bearing, this corresponds
     * to less 1 meter/second velocity less than 5 degrees for bearing.
     * {@hide}
     */
    public static final int ACCURACY_HIGH = 3;

    /**
     * a constant indicating the best accuracy that is available for any
     * location provider available
     * - may be used for horizontal, altitude, speed or bearing accuracy.
     * {@hide}
     */
    public static final int ACCURACY_BEST = 4;

    /**
     * A constant indicating horizontal accuracy has the top priority
     * {@hide}
     */
    public static final int HORIZONTAL_ACCURACY_PRIORITY = 1;

    /**
     * A constant indicating altitude accuracy has the top priority
     * {@hide}
     */
    public static final int VERTICAL_ACCURACY_PRIORITY = 2;

    /**
     * A constant indicating speed accuracy has the top priority
     * {@hide}
     */
    public static final int SPEED_ACCURACY_PRIORITY = 3;

    /**
     * A constant indicating bearing accuracy has the top priority
     * {@hide}
     */
    public static final int BEARING_ACCURACY_PRIORITY = 4;

    /**
     * A constant indicating power requirement has the top priority
     * {@hide}
     */
    public static final int POWER_REQUIREMENT_PRIORITY = 5;

    private int mHorizontalAccuracy    = NO_REQUIREMENT;
    private int mVerticalAccuracy      = NO_REQUIREMENT;
    private int mSpeedAccuracy         = NO_REQUIREMENT;
    private int mBearingAccuracy       = NO_REQUIREMENT;
    private int mPriority              = HORIZONTAL_ACCURACY_PRIORITY;
    private int mPowerRequirement      = NO_REQUIREMENT;
//    private int mPreferredResponseTime = NO_REQUIREMENT;
    private boolean mAltitudeRequired  = false;
    private boolean mBearingRequired   = false;
    private boolean mSpeedRequired     = false;
@@ -77,29 +149,172 @@ public class Criteria implements Parcelable {
     * Constructs a new Criteria object that is a copy of the given criteria.
     */
    public Criteria(Criteria criteria) {
        mAccuracy = criteria.mAccuracy;
        mHorizontalAccuracy = criteria.mHorizontalAccuracy;
        mVerticalAccuracy = criteria.mVerticalAccuracy;
        mSpeedAccuracy = criteria.mSpeedAccuracy;
        mBearingAccuracy = criteria.mBearingAccuracy;
        mPriority = criteria.mPriority;
        mPowerRequirement = criteria.mPowerRequirement;
//        mPreferredResponseTime = criteria.mPreferredResponseTime;
        mAltitudeRequired = criteria.mAltitudeRequired;
        mBearingRequired = criteria.mBearingRequired;
        mSpeedRequired = criteria.mSpeedRequired;
        mCostAllowed = criteria.mCostAllowed;
    }

    /**
     * Indicates the desired horizontal accuracy (latitude and longitude).
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * More accurate location may consume more power and may take longer.
     *
     * @throws IllegalArgumentException if accuracy is not one of the supported constants
     * {@hide}
     */
    public void setHorizontalAccuracy(int accuracy) {
        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
            throw new IllegalArgumentException("accuracy=" + accuracy);
        }
        mHorizontalAccuracy = accuracy;
    }

    /**
     * Returns a constant indicating the desired horizontal accuracy (latitude and longitude).
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * {@hide}
     */
    public int getHorizontalAccuracy() {
        return mHorizontalAccuracy;
    }

    /**
     * Indicates the desired vertical accuracy (altitude).
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * More accurate location may consume more power and may take longer.
     *
     * @throws IllegalArgumentException if accuracy is not one of the supported constants
     * {@hide}
     */
    public void setVerticalAccuracy(int accuracy) {
        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
            throw new IllegalArgumentException("accuracy=" + accuracy);
        }
        mVerticalAccuracy = accuracy;
    }

    /**
     * Returns a constant indicating the desired vertical accuracy (altitude).
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * {@hide}
     */
    public int getVerticalAccuracy() {
        return mVerticalAccuracy;
    }

    /**
     * Indicates the desired speed accuracy.
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * More accurate location may consume more power and may take longer.
     *
     * @throws IllegalArgumentException if accuracy is not one of the supported constants
     * {@hide}
     */
    public void setSpeedAccuracy(int accuracy) {
        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
            throw new IllegalArgumentException("accuracy=" + accuracy);
        }
        mSpeedAccuracy = accuracy;
    }

    /**
     * Returns a constant indicating the desired speed accuracy
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * {@hide}
     */
    public int getSpeedAccuracy() {
        return mSpeedAccuracy;
    }

    /**
     * Indicates the desired bearing accuracy.
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * More accurate location may consume more power and may take longer.
     *
     * @throws IllegalArgumentException if accuracy is not one of the supported constants
     * {@hide}
     */
    public void setBearingAccuracy(int accuracy) {
        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
            throw new IllegalArgumentException("accuracy=" + accuracy);
        }
        mBearingAccuracy = accuracy;
    }

    /**
     * Returns a constant indicating the desired bearing accuracy.
     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
     * {@hide}
     */
    public int getBearingAccuracy() {
        return mBearingAccuracy;
    }

    /**
     * Indicates the top priority to optimize for if the criteria parameters are
     * found to be in conflict.
     * Since a location provider might only be able to optimize for one requirement,
     * the other requirements are considered good to have, but not guaranteed.
     * This parameter does not override the priorities communicated through the
     * preferred accuracy and power consumption parameters.
     * If this parameter is not specified and conflicts occur, the location manager
     * will use thefollowing default priority (high priority to low priority):
     * {@link #HORIZONTAL_ACCURACY_PRIORITY}, {@link #POWER_REQUIREMENT_PRIORITY},
     * {@link #VERTICAL_ACCURACY_PRIORITY}, {@link #SPEED_ACCURACY_PRIORITY},
     * {@link #BEARING_ACCURACY_PRIORITY}.
     * {@hide}
     */
    public void setPreferredPriority(int priority) {
        if (priority < HORIZONTAL_ACCURACY_PRIORITY || priority > POWER_REQUIREMENT_PRIORITY) {
            throw new IllegalArgumentException("priority=" + priority);
        }
        mPriority = priority;
    }

    /**
     * Returns a constant indicating the top priority to optimize for if the
     * criteria parameters are found to be in conflict.
     * The value can be {@link #HORIZONTAL_ACCURACY_PRIORITY},
     * {@link #VERTICAL_ACCURACY_PRIORITY}, {@link #SPEED_ACCURACY_PRIORITY},
     * {@link #BEARING_ACCURACY_PRIORITY} or {@link #POWER_REQUIREMENT_PRIORITY}.
     * {@hide}
     */
    public int getPriority() {
        return mPriority;
    }

    /**
     * Indicates the desired accuracy for latitude and longitude. Accuracy
     * may be {@link #ACCURACY_FINE} if desired location
     * is fine, else it can be {@link #ACCURACY_COARSE}.
     * More accurate location usually consumes more power and may take
     * longer.
     * More accurate location may consume more power and may take longer.
     *
     * @throws IllegalArgumentException if accuracy is negative
     * @throws IllegalArgumentException if accuracy is not one of the supported constants
     */
    public void setAccuracy(int accuracy) {
        if (accuracy < NO_REQUIREMENT && accuracy > ACCURACY_COARSE) {
        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_COARSE) {
            throw new IllegalArgumentException("accuracy=" + accuracy);
        }
        mAccuracy = accuracy;
        if (accuracy == ACCURACY_FINE) {
            mHorizontalAccuracy = ACCURACY_BEST;
        } else {
            mHorizontalAccuracy = ACCURACY_LOW;
        }
    }

    /**
@@ -108,7 +323,11 @@ public class Criteria implements Parcelable {
     * is fine, else it can be {@link #ACCURACY_COARSE}.
     */
    public int getAccuracy() {
        return mAccuracy;
        if (mHorizontalAccuracy >= ACCURACY_HIGH) {
            return ACCURACY_FINE;
        } else {
            return ACCURACY_COARSE;
        }
    }

    /**
@@ -131,20 +350,6 @@ public class Criteria implements Parcelable {
        return mPowerRequirement;
    }

//    /**
//     * Indicates the preferred response time of the provider, in milliseconds.
//     */
//    public void setPreferredResponseTime(int time) {
//        mPreferredResponseTime = time;
//    }
//
//    /**
//     * Returns the preferred response time of the provider, in milliseconds.
//     */
//    public int getPreferredResponseTime() {
//        return mPreferredResponseTime;
//    }

    /**
     * Indicates whether the provider is allowed to incur monetary cost.
     */
@@ -211,9 +416,12 @@ public class Criteria implements Parcelable {
        new Parcelable.Creator<Criteria>() {
        public Criteria createFromParcel(Parcel in) {
            Criteria c = new Criteria();
            c.mAccuracy = in.readInt();
            c.mHorizontalAccuracy = in.readInt();
            c.mVerticalAccuracy = in.readInt();
            c.mSpeedAccuracy = in.readInt();
            c.mBearingAccuracy = in.readInt();
            c.mPriority = in.readInt();
            c.mPowerRequirement = in.readInt();
//            c.mPreferredResponseTime = in.readInt();
            c.mAltitudeRequired = in.readInt() != 0;
            c.mBearingRequired = in.readInt() != 0;
            c.mSpeedRequired = in.readInt() != 0;
@@ -231,9 +439,12 @@ public class Criteria implements Parcelable {
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(mAccuracy);
        parcel.writeInt(mHorizontalAccuracy);
        parcel.writeInt(mVerticalAccuracy);
        parcel.writeInt(mSpeedAccuracy);
        parcel.writeInt(mBearingAccuracy);
        parcel.writeInt(mPriority);
        parcel.writeInt(mPowerRequirement);
//        parcel.writeInt(mPreferredResponseTime);
        parcel.writeInt(mAltitudeRequired ? 1 : 0);
        parcel.writeInt(mBearingRequired ? 1 : 0);
        parcel.writeInt(mSpeedRequired ? 1 : 0);
+9 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.location;

import android.app.PendingIntent;
import android.location.Address;
import android.location.Criteria;
import android.location.GeocoderParams;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
@@ -32,13 +33,15 @@ import android.os.Bundle;
 */
interface ILocationManager
{
    List getAllProviders();
    List getProviders(boolean enabledOnly);
    List<String> getAllProviders();
    List<String> getProviders(in Criteria criteria, boolean enabledOnly);
    String getBestProvider(in Criteria criteria, boolean enabledOnly);
    boolean providerMeetsCriteria(String provider, in Criteria criteria);

    void requestLocationUpdates(String provider, long minTime, float minDistance,
        in ILocationListener listener);
    void requestLocationUpdatesPI(String provider, long minTime, float minDistance,
        in PendingIntent intent);
    void requestLocationUpdates(String provider, in Criteria criteria, long minTime, float minDistance,
        boolean singleShot, in ILocationListener listener);
    void requestLocationUpdatesPI(String provider, in Criteria criteria, long minTime, float minDistance,
        boolean singleShot, in PendingIntent intent);
    void removeUpdates(in ILocationListener listener);
    void removeUpdatesPI(in PendingIntent intent);

+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.location;

import android.location.Criteria;
import android.location.Location;
import android.net.NetworkInfo;
import android.os.Bundle;
@@ -34,6 +35,7 @@ interface ILocationProvider {
    boolean supportsSpeed();
    boolean supportsBearing();
    int getPowerRequirement();
    boolean meetsCriteria(in Criteria criteria);
    int getAccuracy();
    void enable();
    void disable();
+289 −250

File changed.

Preview size limit exceeded, changes collapsed.

+11 −24
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package android.location;

import android.os.RemoteException;
import android.util.Log;

/**
 * An abstract superclass for location providers.  A location provider
 * provides periodic reports on the geographical location of the
@@ -36,7 +39,8 @@ public abstract class LocationProvider {
    // in the name of a LocationProvider.
    static final String BAD_CHARS_REGEX = "[^a-zA-Z0-9]";

    private String mName;
    private final String mName;
    private final ILocationManager mService;

    public static final int OUT_OF_SERVICE = 0;
    public static final int TEMPORARILY_UNAVAILABLE = 1;
@@ -50,13 +54,13 @@ public abstract class LocationProvider {
     *
     * {@hide}
     */
    public LocationProvider(String name) {
    public LocationProvider(String name, ILocationManager service) {
        if (name.matches(BAD_CHARS_REGEX)) {
            throw new IllegalArgumentException("name " + name +
                " contains an illegal character");
        }
        // Log.d(TAG, "Constructor: name = " + name);
        mName = name;
        mService = service;
    }

    /**
@@ -71,29 +75,12 @@ public abstract class LocationProvider {
     * false otherwise.
     */
    public boolean meetsCriteria(Criteria criteria) {
        // We do not want to match the special passive provider based on criteria.
        if (LocationManager.PASSIVE_PROVIDER.equals(mName)) {
            return false;
        }
        if ((criteria.getAccuracy() != Criteria.NO_REQUIREMENT) && 
            (criteria.getAccuracy() < getAccuracy())) {
            return false;
        }
        int criteriaPower = criteria.getPowerRequirement();
        if ((criteriaPower != Criteria.NO_REQUIREMENT) &&
            (criteriaPower < getPowerRequirement())) {
            return false;
        }
        if (criteria.isAltitudeRequired() && !supportsAltitude()) {
            return false;
        }
        if (criteria.isSpeedRequired() && !supportsSpeed()) {
            return false;
        }
        if (criteria.isBearingRequired() && !supportsBearing()) {
        try {
            return mService.providerMeetsCriteria(mName, criteria);
        } catch (RemoteException e) {
            Log.e(TAG, "meetsCriteria: RemoteException", e);
            return false;
        }
        return true;
    }

    /**
Loading