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

Commit 4402af6b authored by gomo's avatar gomo
Browse files

GNSS O Features according to go/o-gps-hal

Added "Tow Known" as a possible gnss measurement state. As well added Automatic Gain Control (AGC)
to allow jammer detection. Also added the GNSS carrier frequeny to SV status. Also added vertical
GPS position uncertainty, speed uncertainty and bearing uncertainty. Also propagate locaton new
fields to geofence engine.
Test: Existing unit tests still pass.

Change-Id: I472b2fd2516cb7614877dea4bb054a34f50844dc
parent acb1d392
Loading
Loading
Loading
Loading
+116 −24
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ public final class GnssMeasurement implements Parcelable {
    private double mCarrierPhaseUncertainty;
    private int mMultipathIndicator;
    private double mSnrInDb;
    private double mAgcLevelDb;

    // The following enumerations must be in sync with the values declared in gps.h

@@ -56,6 +57,7 @@ public final class GnssMeasurement implements Parcelable {
    private static final int HAS_CARRIER_CYCLES = (1<<10);
    private static final int HAS_CARRIER_PHASE = (1<<11);
    private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
    private static final int HAS_AUTOMATIC_GAIN_CONTROL = (1<<13);

    /**
     * The status of the multipath indicator.
@@ -111,6 +113,20 @@ public final class GnssMeasurement implements Parcelable {
    public static final int STATE_GAL_E1B_PAGE_SYNC = (1<<12);
    /** This SBAS measurement's tracking state has whole second level sync. */
    public static final int STATE_SBAS_SYNC = (1<<13);
    /**
     * This GNSS measurement's tracking state has time-of-week known, possibly not decoded
     * over the air but has been determined from other sources. If TOW decoded is set then TOW Known
     * will also be set.
     * @hide
     */
    public static final int STATE_TOW_KNOWN = (1<<14);
    /**
     * This Glonass measurement's tracking state has time-of-day known, possibly not decoded
     * over the air but has been determined from other sources. If TOD decoded is set then TOD Known
     * will also be set.
     * @hide
     */
    public static final int STATE_GLO_TOD_KNOWN = (1<<15);

    /**
     * All the GNSS receiver state flags, for bit masking purposes (not a sensible state for any
@@ -180,6 +196,7 @@ public final class GnssMeasurement implements Parcelable {
        mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
        mMultipathIndicator = measurement.mMultipathIndicator;
        mSnrInDb = measurement.mSnrInDb;
        mAgcLevelDb = measurement.mAgcLevelDb;
    }

    /**
@@ -299,6 +316,9 @@ public final class GnssMeasurement implements Parcelable {
        if ((mState & STATE_TOW_DECODED) != 0) {
            builder.append("TowDecoded|");
        }
        if ((mState & STATE_TOW_KNOWN) != 0) {
          builder.append("TowKnown|");
        }
        if ((mState & STATE_MSEC_AMBIGUOUS) != 0) {
            builder.append("MsecAmbiguous|");
        }
@@ -311,6 +331,9 @@ public final class GnssMeasurement implements Parcelable {
        if ((mState & STATE_GLO_TOD_DECODED) != 0) {
            builder.append("GloTodDecoded|");
        }
        if ((mState & STATE_GLO_TOD_KNOWN) != 0) {
          builder.append("GloTodKnown|");
        }
        if ((mState & STATE_BDS_D2_BIT_SYNC) != 0) {
            builder.append("BdsD2BitSync|");
        }
@@ -356,10 +379,14 @@ public final class GnssMeasurement implements Parcelable {
     *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
     *     Bit sync        : [ 0  20ms ]   : STATE_BIT_SYNC is set
     *     Subframe sync   : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
     *     TOW decoded     : [ 0 1week ]   : STATE_TOW_DECODED is set</pre>
     *     TOW decoded     : [ 0 1week ]   : STATE_TOW_DECODED is set
     *     TOW Known       : [ 0 1week ]   : STATE_TOW_KNOWN set</pre>
     *
     * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
     * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
     *
     * <p>Note well: if there is any ambiguity in integer millisecond, {@code STATE_MSEC_AMBIGUOUS}
     * should be set accordingly, in the 'state' field.
     * must be set accordingly, in the 'state' field.
     *
     * <p>This value must be populated if 'state' != {@code STATE_UNKNOWN}.
     *
@@ -376,7 +403,12 @@ public final class GnssMeasurement implements Parcelable {
     *     Symbol sync         : [ 0  10ms ]   : STATE_SYMBOL_SYNC is set
     *     Bit sync            : [ 0  20ms ]   : STATE_BIT_SYNC is set
     *     String sync         : [ 0    2s ]   : STATE_GLO_STRING_SYNC is set
     *     Time of day     : [ 0  1day ]   : STATE_GLO_TOD_DECODED is set</pre>
     *     Time of day decoded : [ 0  1day ]   : STATE_GLO_TOD_DECODED is set
     *     Time of day known   : [ 0  1day ]   : STATE_GLO_TOD_KNOWN set</pre>
     *
     * Note: Time of day known refers to the case where it is possibly not decoded over the air but
     * has been determined from other sources. If Time of day decoded is set then Time of day known
     * must also be set.
     *
     * <p>For Beidou, this is:
     * <ul>
@@ -392,7 +424,11 @@ public final class GnssMeasurement implements Parcelable {
     *     Bit sync (D1)          : [ 0  20ms ]   : STATE_BIT_SYNC is set
     *     Subframe (D2)          : [ 0  0.6s ]   : STATE_BDS_D2_SUBFRAME_SYNC is set
     *     Subframe (D1)          : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
     *     Time of week    : [ 0 1week ]   : STATE_TOW_DECODED is set</pre>
     *     Time of week decoded   : [ 0 1week ]   : STATE_TOW_DECODED is set
     *     Time of week known     : [ 0 1week ]   : STATE_TOW_KNOWN set</pre>
     *
     * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
     * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
     *
     * <p>For Galileo, this is:
     * <ul>
@@ -402,7 +438,11 @@ public final class GnssMeasurement implements Parcelable {
     *     E1BC code lock       : [ 0   4ms ]  : STATE_GAL_E1BC_CODE_LOCK is set
     *     E1C 2nd code lock    : [ 0 100ms ]  : STATE_GAL_E1C_2ND_CODE_LOCK is set
     *     E1B page             : [ 0    2s ]  : STATE_GAL_E1B_PAGE_SYNC is set
     *     Time of week     : [ 0 1week ]  : STATE_GAL_TOW_DECODED is set</pre>
     *     Time of week decoded : [ 0 1week ]  : STATE_GAL_TOW_DECODED is set
     *     Time of week known   : [ 0 1week ]  : STATE_GAL_TOW_KNOWN set</pre>
     *
     * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
     * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
     *
     * <p>For SBAS, this is:
     * <ul>
@@ -620,10 +660,10 @@ public final class GnssMeasurement implements Parcelable {
    }

    /**
     * Gets the carrier frequency at which codes and messages are modulated.
     * Gets the carrier frequency of the tracked signal.
     *
     * <p>For GPS, e.g., it can be L1 or L2.  If the field is not set, it is the primary common use
     * frequency, e.g. L1 for GPS.
     * <p>For example it can be the GPS L1 = 1.57542e9 Hz, or L2, L5, varying GLO channels, etc. If
     * the field is not set, it is the primary common use frequency, e.g. L1 for GPS.
     *
     * <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
     */
@@ -632,7 +672,7 @@ public final class GnssMeasurement implements Parcelable {
    }

    /**
     * Sets the Carrier frequency (L1 or L2) in Hz.
     * Sets the Carrier frequency in Hz.
     * @hide
     */
    @TestApi
@@ -642,7 +682,7 @@ public final class GnssMeasurement implements Parcelable {
    }

    /**
     * Resets the Carrier frequency (L1 or L2) in Hz.
     * Resets the Carrier frequency in Hz.
     * @hide
     */
    @TestApi
@@ -843,6 +883,51 @@ public final class GnssMeasurement implements Parcelable {
        mSnrInDb = Double.NaN;
    }

    /**
     * Returns {@code true} if {@link #getAgcLevelDb()} is available, {@code false} otherwise.
     * @hide
     */
    public boolean hasAgcLevelDb() {
        return isFlagSet(HAS_AUTOMATIC_GAIN_CONTROL);
    }

    /**
     * Gets the Automatic Gain Control level in dB.
     *
     * <p> AGC acts as a variable gain amplifier adjusting the power of the incoming signal to
     * minimize the quantization losses. The AGC level may be used to indicate potential
     * interference. When AGC is at a nominal level, this value must be set as 0.  Higher gain
     * (and/or lower input power) shall be output as a positive number. Hence in cases of strong
     * jamming, in the band of this signal, this value will go more negative.
     * <p>Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
     * components) may also affect the typical output of of this value on any given hardware design
     * in an open sky test - the important aspect of this output is that changes in this value are
     * indicative of changes on input signal power in the frequency band for this measurement.
     * <p>The value is only available if {@link #hasAgcLevelDb()} is {@code true}.
     * @hide
     */
    public double getAgcLevelDb() {
        return mAgcLevelDb;
    }

    /**
     * Sets the Automatic Gain Control level in dB.
     * @hide
     */
    public void setAgcLevelDb(double agcLevelDb) {
        setFlag(HAS_AUTOMATIC_GAIN_CONTROL);
        mAgcLevelDb = agcLevelDb;
    }

    /**
     * Resets the Automatic Gain Control level.
     * @hide
     */
    public void resetAgcLevel() {
        resetFlag(HAS_AUTOMATIC_GAIN_CONTROL);
        mAgcLevelDb = Double.NaN;
    }

    public static final Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
        @Override
        public GnssMeasurement createFromParcel(Parcel parcel) {
@@ -867,6 +952,7 @@ public final class GnssMeasurement implements Parcelable {
            gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
            gnssMeasurement.mMultipathIndicator = parcel.readInt();
            gnssMeasurement.mSnrInDb = parcel.readDouble();
            gnssMeasurement.mAgcLevelDb = parcel.readDouble();

            return gnssMeasurement;
        }
@@ -898,6 +984,7 @@ public final class GnssMeasurement implements Parcelable {
        parcel.writeDouble(mCarrierPhaseUncertainty);
        parcel.writeInt(mMultipathIndicator);
        parcel.writeDouble(mSnrInDb);
        parcel.writeDouble(mAgcLevelDb);
    }

    @Override
@@ -968,6 +1055,10 @@ public final class GnssMeasurement implements Parcelable {
                format,
                "SnrInDb",
                hasSnrInDb() ? mSnrInDb : null));
        builder.append(String.format(
            format,
            "AgcLevelDb",
            hasAgcLevelDb() ? mAgcLevelDb : null));

        return builder.toString();
    }
@@ -991,6 +1082,7 @@ public final class GnssMeasurement implements Parcelable {
        resetCarrierPhaseUncertainty();
        setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
        resetSnrInDb();
        resetAgcLevel();
    }

    private void setFlag(int flag) {
+29 −1
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ public final class GnssStatus {
    public static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA = (1 << 1);
    /** @hide */
    public static final int GNSS_SV_FLAGS_USED_IN_FIX = (1 << 2);
    /** @hide */
    public static final int GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3);

    /** @hide */
    public static final int SVID_SHIFT_WIDTH = 7;
@@ -101,14 +103,16 @@ public final class GnssStatus {
    /* package */ float[] mElevations;
    /* package */ float[] mAzimuths;
    /* package */ int mSvCount;
    /* package */ float[] mCarrierFrequencies;

    GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
            float[] azimuths) {
            float[] azimuths, float[] carrierFrequencies) {
        mSvCount = svCount;
        mSvidWithFlags = svidWithFlags;
        mCn0DbHz = cn0s;
        mElevations = elevations;
        mAzimuths = azimuths;
        mCarrierFrequencies = carrierFrequencies;
    }

    /**
@@ -213,4 +217,28 @@ public final class GnssStatus {
    public boolean usedInFix(int satIndex) {
        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_USED_IN_FIX) != 0;
    }

    /**
     * Reports whether {@link #getCarrierFrequencyHz(int satIndex)} is available (i.e. carrier
     * frequency is available for the satellite at the specified index).
     *
     * @param satIndex the index of the satellite in the list.
     * @hide
     */
    public boolean hasCarrierFrequency(int satIndex) {
        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0;
    }

    /**
     * Gets the carrier frequency of the signal tracked.
     *
     * For example it can be the GPS L1 = 1.57542e9 Hz, or L2, L5, varying GLO channels, etc. If
     * the field is not set, it is the primary common use frequency, e.g. L1 for GPS.
     *
     * <p>The value is only available if {@link #hasCarrierFrequency(int satIndex)} is {@code true}.
     * @hide
     */
    public float getCarrierFrequencyHz(int satIndex) {
        return mCarrierFrequencies[satIndex];
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ oneway interface IGnssStatusListener
    void onGnssStopped();
    void onFirstFix(int ttff);
    void onSvStatusChanged(int svCount, in int[] svidWithFlags, in float[] cn0s,
            in float[] elevations, in float[] azimuths);
            in float[] elevations, in float[] azimuths,
            in float[] carrierFreqs);
    void onNmeaReceived(long timestamp, String nmea);
}
+214 −33
Original line number Diff line number Diff line
@@ -81,23 +81,35 @@ public class Location implements Parcelable {
    /**
     * Bit mask for mFieldsMask indicating the presence of mAltitude.
     */
    private static final byte HAS_ALTITUDE_MASK = 1;
    private static final int HAS_ALTITUDE_MASK = 1;
    /**
     * Bit mask for mFieldsMask indicating the presence of mSpeed.
     */
    private static final byte HAS_SPEED_MASK = 2;
    private static final int HAS_SPEED_MASK = 2;
    /**
     * Bit mask for mFieldsMask indicating the presence of mBearing.
     */
    private static final byte HAS_BEARING_MASK = 4;
    private static final int HAS_BEARING_MASK = 4;
    /**
     * Bit mask for mFieldsMask indicating the presence of mAccuracy.
     * Bit mask for mFieldsMask indicating the presence of mHorizontalAccuracy.
     */
    private static final byte HAS_ACCURACY_MASK = 8;
    private static final int HAS_HORIZONTAL_ACCURACY_MASK = 8;
    /**
     * Bit mask for mFieldsMask indicating location is from a mock provider.
     */
    private static final byte HAS_MOCK_PROVIDER_MASK = 16;
    private static final int HAS_MOCK_PROVIDER_MASK = 16;
    /**
     * Bit mask for mFieldsMask indicating the presence of mVerticalAccuracy.
     */
    private static final int HAS_VERTICAL_ACCURACY_MASK = 32;
    /**
     * Bit mask for mFieldsMask indicating the presence of mSpeedAccuracy.
     */
    private static final int HAS_SPEED_ACCURACY_MASK = 64;
    /**
     * Bit mask for mFieldsMask indicating the presence of mBearingAccuracy.
     */
    private static final int HAS_BEARING_ACCURACY_MASK = 128;

    // Cached data to make bearing/distance computations more efficient for the case
    // where distanceTo and bearingTo are called in sequence.  Assume this typically happens
@@ -118,7 +130,11 @@ public class Location implements Parcelable {
    private double mAltitude = 0.0f;
    private float mSpeed = 0.0f;
    private float mBearing = 0.0f;
    private float mAccuracy = 0.0f;
    private float mHorizontalAccuracyMeters = 0.0f;
    private float mVerticalAccuracyMeters = 0.0f;
    private float mSpeedAccuracyMetersPerSecond = 0.0f;
    private float mBearingAccuracyDegrees = 0.0f;

    private Bundle mExtras = null;

    // A bitmask of fields present in this object (see HAS_* constants defined above).
@@ -156,7 +172,10 @@ public class Location implements Parcelable {
        mAltitude = l.mAltitude;
        mSpeed = l.mSpeed;
        mBearing = l.mBearing;
        mAccuracy = l.mAccuracy;
        mHorizontalAccuracyMeters = l.mHorizontalAccuracyMeters;
        mVerticalAccuracyMeters = l.mVerticalAccuracyMeters;
        mSpeedAccuracyMetersPerSecond = l.mSpeedAccuracyMetersPerSecond;
        mBearingAccuracyDegrees = l.mBearingAccuracyDegrees;
        mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras);
    }

@@ -173,7 +192,10 @@ public class Location implements Parcelable {
        mAltitude = 0;
        mSpeed = 0;
        mBearing = 0;
        mAccuracy = 0;
        mHorizontalAccuracyMeters = 0;
        mVerticalAccuracyMeters = 0;
        mSpeedAccuracyMetersPerSecond = 0;
        mBearingAccuracyDegrees = 0;
        mExtras = null;
    }

@@ -718,19 +740,18 @@ public class Location implements Parcelable {
    }

    /**
     * True if this location has an accuracy.
     * True if this location has a horizontal accuracy.
     *
     * <p>All locations generated by the {@link LocationManager} have an
     * accuracy.
     * <p>All locations generated by the {@link LocationManager} have an horizontal accuracy.
     */
    public boolean hasAccuracy() {
        return (mFieldsMask & HAS_ACCURACY_MASK) != 0;
        return (mFieldsMask & HAS_HORIZONTAL_ACCURACY_MASK) != 0;
    }

    /**
     * Get the estimated accuracy of this location, in meters.
     * Get the estimated horizontal accuracy of this location, radial, in meters.
     *
     * <p>We define accuracy as the radius of 68% confidence. In other
     * <p>We define horizontal accuracy as the radius of 68% confidence. In other
     * words, if you draw a circle centered at this location's
     * latitude and longitude, and with a radius equal to the accuracy,
     * then there is a 68% probability that the true location is inside
@@ -745,35 +766,183 @@ public class Location implements Parcelable {
     * accuracy, and does not indicate the accuracy of bearing,
     * velocity or altitude if those are included in this Location.
     *
     * <p>If this location does not have an accuracy, then 0.0 is returned.
     * All locations generated by the {@link LocationManager} include
     * an accuracy.
     * <p>If this location does not have a horizontal accuracy, then 0.0 is returned.
     * All locations generated by the {@link LocationManager} include horizontal accuracy.
     */
    public float getAccuracy() {
        return mAccuracy;
        return mHorizontalAccuracyMeters;
    }

    /**
     * Set the estimated accuracy of this location, meters.
     * Set the estimated horizontal accuracy of this location, meters.
     *
     * <p>See {@link #getAccuracy} for the definition of accuracy.
     * <p>See {@link #getAccuracy} for the definition of horizontal accuracy.
     *
     * <p>Following this call {@link #hasAccuracy} will return true.
     */
    public void setAccuracy(float accuracy) {
        mAccuracy = accuracy;
        mFieldsMask |= HAS_ACCURACY_MASK;
    public void setAccuracy(float horizontalAccuracy) {
        mHorizontalAccuracyMeters = horizontalAccuracy;
        mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
    }

    /**
     * Remove the accuracy from this location.
     * Remove the horizontal accuracy from this location.
     *
     * <p>Following this call {@link #hasAccuracy} will return false, and
     * {@link #getAccuracy} will return 0.0.
     */
    public void removeAccuracy() {
        mAccuracy = 0.0f;
        mFieldsMask &= ~HAS_ACCURACY_MASK;
        mHorizontalAccuracyMeters = 0.0f;
        mFieldsMask &= ~HAS_HORIZONTAL_ACCURACY_MASK;
    }

    /**
     * True if this location has a vertical accuracy.
     * @hide
     */
    public boolean hasVerticalAccuracy() {
        return (mFieldsMask & HAS_VERTICAL_ACCURACY_MASK) != 0;
    }

    /**
     * Get the estimated vertical accuracy of this location, in meters.
     *
     * <p>We define vertical accuracy as the radius of 68% confidence. In other
     * words, if you draw a circle centered at this location's altitude, and with a radius
     * equal to the vertical accuracy, then there is a 68% probability that the true altitude is
     * inside the circle.
     *
     * <p>In statistical terms, it is assumed that location errors
     * are random with a normal distribution, so the 68% confidence circle
     * represents one standard deviation. Note that in practice, location
     * errors do not always follow such a simple distribution.
     *
     * <p>If this location does not have a vertical accuracy, then 0.0 is returned.
     * @hide
     */
    public float getVerticalAccuracyMeters() {
        return mVerticalAccuracyMeters;
    }

    /**
     * Set the estimated vertical accuracy of this location, meters.
     *
     * <p>See {@link #getVerticalAccuracyMeters} for the definition of vertical accuracy.
     *
     * <p>Following this call {@link #hasVerticalAccuracy} will return true.
     * @hide
     */
    public void setVerticalAccuracyMeters(float verticalAccuracyMeters) {
        mVerticalAccuracyMeters = verticalAccuracyMeters;
        mFieldsMask |= HAS_VERTICAL_ACCURACY_MASK;
    }

    /**
     * Remove the vertical accuracy from this location.
     *
     * <p>Following this call {@link #hasVerticalAccuracy} will return false, and
     * {@link #getVerticalAccuracyMeters} will return 0.0.
     * @hide
     */
    public void removeVerticalAccuracy() {
        mVerticalAccuracyMeters = 0.0f;
        mFieldsMask &= ~HAS_VERTICAL_ACCURACY_MASK;
    }

    /**
     * True if this location has a speed accuracy.
     * @hide
     */
    public boolean hasSpeedAccuracy() {
        return (mFieldsMask & HAS_SPEED_ACCURACY_MASK) != 0;
    }

    /**
     * Get the estimated speed accuracy of this location, in meters per second.
     *
     * <p>We define speed accuracy as the radius of 68% confidence. In other
     * words, if you draw a circle centered at this location's speed, and with a radius
     * equal to the speed accuracy, then there is a 68% probability that the true speed is
     * inside the circle.
     *
     * <p>If this location does not have a speed accuracy, then 0.0 is returned.
     * @hide
     */
    public float getSpeedAccuracyMetersPerSecond() {
        return mSpeedAccuracyMetersPerSecond;
    }

    /**
     * Set the estimated speed accuracy of this location, meters per second.
     *
     * <p>See {@link #getSpeedAccuracyMetersPerSecond} for the definition of speed accuracy.
     *
     * <p>Following this call {@link #hasSpeedAccuracy} will return true.
     * @hide
     */
    public void setSpeedAccuracyMetersPerSecond(float speedAccuracyMeterPerSecond) {
        mSpeedAccuracyMetersPerSecond = speedAccuracyMeterPerSecond;
        mFieldsMask |= HAS_SPEED_ACCURACY_MASK;
    }

    /**
     * Remove the speed accuracy from this location.
     *
     * <p>Following this call {@link #hasSpeedAccuracy} will return false, and
     * {@link #getSpeedAccuracyMetersPerSecond} will return 0.0.
     * @hide
     */
    public void removeSpeedAccuracy() {
        mSpeedAccuracyMetersPerSecond = 0.0f;
        mFieldsMask &= ~HAS_SPEED_ACCURACY_MASK;
    }

    /**
     * True if this location has a bearing accuracy.
     * @hide
     */
    public boolean hasBearingAccuracy() {
        return (mFieldsMask & HAS_BEARING_ACCURACY_MASK) != 0;
    }

    /**
     * Get the estimated bearing accuracy of this location, in degrees.
     *
     * <p>We define bearing accuracy as the radius of 68% confidence. In other
     * words, if you draw a circle centered at this location's bearing, and with a radius
     * equal to the bearing accuracy, then there is a 68% probability that the true bearing is
     * inside the circle.
     *
     * <p>If this location does not have a bearing accuracy, then 0.0 is returned.
     * @hide
     */
    public float getBearingAccuracyDegrees() {
        return mBearingAccuracyDegrees;
    }

    /**
     * Set the estimated bearing accuracy of this location, degrees.
     *
     * <p>See {@link #getBearingAccuracyDegrees} for the definition of bearing accuracy.
     *
     * <p>Following this call {@link #hasBearingAccuracy} will return true.
     * @hide
     */
    public void setBearingAccuracyDegrees(float bearingAccuracyDegrees) {
        mBearingAccuracyDegrees = bearingAccuracyDegrees;
        mFieldsMask |= HAS_BEARING_ACCURACY_MASK;
    }

    /**
     * Remove the bearing accuracy from this location.
     *
     * <p>Following this call {@link #hasBearingAccuracy} will return false, and
     * {@link #getBearingAccuracyDegrees} will return 0.0.
     * @hide
     */
    public void removeBearingAccuracy() {
        mBearingAccuracyDegrees = 0.0f;
        mFieldsMask &= ~HAS_BEARING_ACCURACY_MASK;
    }

    /**
@@ -810,8 +979,8 @@ public class Location implements Parcelable {
    public void makeComplete() {
        if (mProvider == null) mProvider = "?";
        if (!hasAccuracy()) {
            mFieldsMask |= HAS_ACCURACY_MASK;
            mAccuracy = 100.0f;
            mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
            mHorizontalAccuracyMeters = 100.0f;
        }
        if (mTime == 0) mTime = System.currentTimeMillis();
        if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
@@ -849,8 +1018,8 @@ public class Location implements Parcelable {
        s.append("Location[");
        s.append(mProvider);
        s.append(String.format(" %.6f,%.6f", mLatitude, mLongitude));
        if (hasAccuracy()) s.append(String.format(" acc=%.0f", mAccuracy));
        else s.append(" acc=???");
        if (hasAccuracy()) s.append(String.format(" hAcc=%.0f", mHorizontalAccuracyMeters));
        else s.append(" hAcc=???");
        if (mTime == 0) {
            s.append(" t=?!?");
        }
@@ -863,6 +1032,12 @@ public class Location implements Parcelable {
        if (hasAltitude()) s.append(" alt=").append(mAltitude);
        if (hasSpeed()) s.append(" vel=").append(mSpeed);
        if (hasBearing()) s.append(" bear=").append(mBearing);
        if (hasVerticalAccuracy()) s.append(String.format(" vAcc=%.0f", mVerticalAccuracyMeters));
        else s.append(" vAcc=???");
        if (hasSpeedAccuracy()) s.append(String.format(" sAcc=%.0f", mSpeedAccuracyMetersPerSecond));
        else s.append(" sAcc=???");
        if (hasBearingAccuracy()) s.append(String.format(" bAcc=%.0f", mBearingAccuracyDegrees));
        else s.append(" bAcc=???");
        if (isFromMockProvider()) s.append(" mock");

        if (mExtras != null) {
@@ -890,7 +1065,10 @@ public class Location implements Parcelable {
            l.mAltitude = in.readDouble();
            l.mSpeed = in.readFloat();
            l.mBearing = in.readFloat();
            l.mAccuracy = in.readFloat();
            l.mHorizontalAccuracyMeters = in.readFloat();
            l.mVerticalAccuracyMeters = in.readFloat();
            l.mSpeedAccuracyMetersPerSecond = in.readFloat();
            l.mBearingAccuracyDegrees = in.readFloat();
            l.mExtras = Bundle.setDefusable(in.readBundle(), true);
            return l;
        }
@@ -917,7 +1095,10 @@ public class Location implements Parcelable {
        parcel.writeDouble(mAltitude);
        parcel.writeFloat(mSpeed);
        parcel.writeFloat(mBearing);
        parcel.writeFloat(mAccuracy);
        parcel.writeFloat(mHorizontalAccuracyMeters);
        parcel.writeFloat(mVerticalAccuracyMeters);
        parcel.writeFloat(mSpeedAccuracyMetersPerSecond);
        parcel.writeFloat(mBearingAccuracyDegrees);
        parcel.writeBundle(mExtras);
    }

+3 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading