diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java index 70339005581fe..d2873e968e33b 100644 --- a/location/java/android/location/GnssMeasurement.java +++ b/location/java/android/location/GnssMeasurement.java @@ -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 + * TOW decoded : [ 0 1week ] : STATE_TOW_DECODED is set + * TOW Known : [ 0 1week ] : STATE_TOW_KNOWN set + * + * 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. * *
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. * *
This value must be populated if 'state' != {@code STATE_UNKNOWN}. * @@ -371,12 +398,17 @@ public final class GnssMeasurement implements Parcelable { *
Given the highest sync state that can be achieved, per each satellite, valid range for * this field can be: *
- * Searching : [ 0 ] : STATE_UNKNOWN - * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set - * 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+ * Searching : [ 0 ] : STATE_UNKNOWN + * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set + * 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 decoded : [ 0 1day ] : STATE_GLO_TOD_DECODED is set + * Time of day known : [ 0 1day ] : STATE_GLO_TOD_KNOWN set + * + * 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. * *
For Beidou, this is: *
Given the highest sync state that can be achieved, per each satellite, valid range for * this field can be: *
- * Searching : [ 0 ] : STATE_UNKNOWN - * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set - * Bit sync (D2) : [ 0 2ms ] : STATE_BDS_D2_BIT_SYNC is set - * 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+ * Searching : [ 0 ] : STATE_UNKNOWN + * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK is set + * Bit sync (D2) : [ 0 2ms ] : STATE_BDS_D2_BIT_SYNC is set + * 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 decoded : [ 0 1week ] : STATE_TOW_DECODED is set + * Time of week known : [ 0 1week ] : STATE_TOW_KNOWN set + * + * 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. * *
For Galileo, this is: *
- * 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+ * 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 decoded : [ 0 1week ] : STATE_GAL_TOW_DECODED is set + * Time of week known : [ 0 1week ] : STATE_GAL_TOW_KNOWN set + * + * 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. * *
For SBAS, this is: *
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. + *
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. * *
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. + * + *
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. + *
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. + *
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 The value is only available if {@link #hasCarrierFrequency(int satIndex)} is {@code true}.
+ * @hide
+ */
+ public float getCarrierFrequencyHz(int satIndex) {
+ return mCarrierFrequencies[satIndex];
+ }
}
diff --git a/location/java/android/location/IGnssStatusListener.aidl b/location/java/android/location/IGnssStatusListener.aidl
index d84614f1b8943..d824cb18765ac 100644
--- a/location/java/android/location/IGnssStatusListener.aidl
+++ b/location/java/android/location/IGnssStatusListener.aidl
@@ -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);
}
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 50f0badf6ac1f..f5f437e0bbe58 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -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.
*
- * All locations generated by the {@link LocationManager} have an
- * accuracy.
+ * 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.
*
- * We define accuracy as the radius of 68% confidence. In other
+ * 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.
*
- * If this location does not have an accuracy, then 0.0 is returned.
- * All locations generated by the {@link LocationManager} include
- * an accuracy.
+ * 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.
*
- * See {@link #getAccuracy} for the definition of accuracy.
+ * See {@link #getAccuracy} for the definition of horizontal accuracy.
*
* 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.
*
* 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * See {@link #getVerticalAccuracyMeters} for the definition of vertical accuracy.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * See {@link #getSpeedAccuracyMetersPerSecond} for the definition of speed accuracy.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * See {@link #getBearingAccuracyDegrees} for the definition of bearing accuracy.
+ *
+ * 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.
+ *
+ * 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);
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 087e74f54006c..4e146268b2564 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1554,9 +1554,10 @@ public class LocationManager {
@Override
public void onSvStatusChanged(int svCount, int[] prnWithFlags,
- float[] cn0s, float[] elevations, float[] azimuths) {
+ float[] cn0s, float[] elevations, float[] azimuths, float[] carrierFreqs) {
if (mGnssCallback != null) {
- mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths);
+ mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths,
+ carrierFreqs);
Message msg = Message.obtain();
msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 24b204165ea33..eb8f8fc9af96d 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -100,7 +100,7 @@ import java.util.HashMap;
import libcore.io.IoUtils;
/**
- * A GPS implementation of LocationProvider used by LocationManager.
+ * A GNSS implementation of LocationProvider used by LocationManager.
*
* {@hide}
*/
@@ -115,23 +115,23 @@ public class GnssLocationProvider implements LocationProviderInterface {
true, true, false, false, true, true, true,
Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
- // these need to match GpsPositionMode enum in gps.h
+ // these need to match GnssPositionMode enum in IGnss.hal
private static final int GPS_POSITION_MODE_STANDALONE = 0;
private static final int GPS_POSITION_MODE_MS_BASED = 1;
private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
- // these need to match GpsPositionRecurrence enum in gps.h
+ // these need to match GnssPositionRecurrence enum in IGnss.hal
private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
- // these need to match GpsStatusValue defines in gps.h
+ // these need to match GnssStatusValue enum in IGnssCallback.hal
private static final int GPS_STATUS_NONE = 0;
private static final int GPS_STATUS_SESSION_BEGIN = 1;
private static final int GPS_STATUS_SESSION_END = 2;
private static final int GPS_STATUS_ENGINE_ON = 3;
private static final int GPS_STATUS_ENGINE_OFF = 4;
- // these need to match GpsApgsStatusValue defines in gps.h
+ // these need to match AGnssStatusValue enum in IAGnssCallback.hal
/** AGPS status event values. */
private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
@@ -139,15 +139,19 @@ public class GnssLocationProvider implements LocationProviderInterface {
private static final int GPS_AGPS_DATA_CONN_DONE = 4;
private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
- // these need to match GpsLocationFlags enum in gps.h
+ // these need to match GnssLocationFlags enum in types.hal
private static final int LOCATION_INVALID = 0;
private static final int LOCATION_HAS_LAT_LONG = 1;
private static final int LOCATION_HAS_ALTITUDE = 2;
private static final int LOCATION_HAS_SPEED = 4;
private static final int LOCATION_HAS_BEARING = 8;
- private static final int LOCATION_HAS_ACCURACY = 16;
+ private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
+ private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
+ private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
+ private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
- // IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h
+
+ // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
private static final int GPS_DELETE_EPHEMERIS = 0x0001;
private static final int GPS_DELETE_ALMANAC = 0x0002;
private static final int GPS_DELETE_POSITION = 0x0004;
@@ -162,7 +166,7 @@ public class GnssLocationProvider implements LocationProviderInterface {
private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
private static final int GPS_DELETE_ALL = 0xFFFF;
- // The GPS_CAPABILITY_* flags must match the values in gps.h
+ // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
private static final int GPS_CAPABILITY_MSB = 0x0000002;
private static final int GPS_CAPABILITY_MSA = 0x0000004;
@@ -176,11 +180,11 @@ public class GnssLocationProvider implements LocationProviderInterface {
private static final int AGPS_SUPL_MODE_MSA = 0x02;
private static final int AGPS_SUPL_MODE_MSB = 0x01;
- // these need to match AGpsType enum in gps.h
+ // these need to match AGnssType enum in IAGnssCallback.hal
private static final int AGPS_TYPE_SUPL = 1;
private static final int AGPS_TYPE_C2K = 2;
- // these must match the definitions in gps.h
+ // these must match the ApnIpType enum in IAGnss.hal
private static final int APN_INVALID = 0;
private static final int APN_IPV4 = 1;
private static final int APN_IPV6 = 2;
@@ -227,7 +231,7 @@ public class GnssLocationProvider implements LocationProviderInterface {
private static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
private static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
- // GPS Geofence errors. Should match gps.h constants.
+ // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
@@ -1479,7 +1483,9 @@ public class GnssLocationProvider implements LocationProviderInterface {
* called from native code to update our position.
*/
private void reportLocation(int flags, double latitude, double longitude, double altitude,
- float speedMetersPerSecond, float bearing, float accuracy, long timestamp) {
+ float speedMetersPerSecond, float bearing, float horizontalAccuracyMeters,
+ float verticalAccuracyMeters, float speedAccuracyMetersPerSeconds,
+ float bearingAccuracyDegrees, long timestamp) {
if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
mItarSpeedLimitExceeded = speedMetersPerSecond > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
}
@@ -1491,7 +1497,7 @@ public class GnssLocationProvider implements LocationProviderInterface {
}
if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude +
- " timestamp: " + timestamp);
+ " timestamp: " + timestamp + " flags: " + flags);
synchronized (mLocation) {
mLocationFlags = flags;
@@ -1518,11 +1524,26 @@ public class GnssLocationProvider implements LocationProviderInterface {
} else {
mLocation.removeBearing();
}
- if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
- mLocation.setAccuracy(accuracy);
+ if ((flags & LOCATION_HAS_HORIZONTAL_ACCURACY) == LOCATION_HAS_HORIZONTAL_ACCURACY) {
+ mLocation.setAccuracy(horizontalAccuracyMeters);
} else {
mLocation.removeAccuracy();
}
+ if ((flags & LOCATION_HAS_VERTICAL_ACCURACY) == LOCATION_HAS_VERTICAL_ACCURACY) {
+ mLocation.setVerticalAccuracyMeters(verticalAccuracyMeters);
+ } else {
+ mLocation.removeVerticalAccuracy();
+ }
+ if((flags & LOCATION_HAS_SPEED_ACCURACY) == LOCATION_HAS_SPEED_ACCURACY) {
+ mLocation.setSpeedAccuracyMetersPerSecond(speedAccuracyMetersPerSeconds);
+ } else {
+ mLocation.removeSpeedAccuracy();
+ }
+ if((flags & LOCATION_HAS_BEARING_ACCURACY) == LOCATION_HAS_BEARING_ACCURACY) {
+ mLocation.setBearingAccuracyDegrees(bearingAccuracyDegrees);
+ } else {
+ mLocation.removeBearingAccuracy();
+ }
mLocation.setExtras(mLocationExtras);
try {
@@ -1605,13 +1626,18 @@ public class GnssLocationProvider implements LocationProviderInterface {
* called from native code to update SV info
*/
private void reportSvStatus() {
- int svCount = native_read_sv_status(mSvidWithFlags, mCn0s, mSvElevations, mSvAzimuths);
+ int svCount = native_read_sv_status(mSvidWithFlags,
+ mCn0s,
+ mSvElevations,
+ mSvAzimuths,
+ mSvCarrierFreqs);
mListenerHelper.onSvStatusChanged(
svCount,
mSvidWithFlags,
mCn0s,
mSvElevations,
- mSvAzimuths);
+ mSvAzimuths,
+ mSvCarrierFreqs);
if (VERBOSE) {
Log.v(TAG, "SV count: " + svCount);
@@ -1627,12 +1653,15 @@ public class GnssLocationProvider implements LocationProviderInterface {
" cn0: " + mCn0s[i]/10 +
" elev: " + mSvElevations[i] +
" azimuth: " + mSvAzimuths[i] +
+ " carrier frequency: " + mSvCarrierFreqs[i] +
((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
? " " : " E") +
((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
? " " : " A") +
((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
- ? "" : "U"));
+ ? "" : "U") +
+ ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
+ ? "" : "F"));
}
}
// return number of sets used in fix instead of total
@@ -1780,7 +1809,10 @@ public class GnssLocationProvider implements LocationProviderInterface {
double altitude,
float speed,
float bearing,
- float accuracy,
+ float horizontalAccuracy,
+ float verticalAccuracy,
+ float speedAccuracy,
+ float bearingAccuracy,
long timestamp) {
Location location = new Location(LocationManager.GPS_PROVIDER);
if((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
@@ -1798,8 +1830,17 @@ public class GnssLocationProvider implements LocationProviderInterface {
if((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
location.setBearing(bearing);
}
- if((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
- location.setAccuracy(accuracy);
+ if((flags & LOCATION_HAS_HORIZONTAL_ACCURACY) == LOCATION_HAS_HORIZONTAL_ACCURACY) {
+ location.setAccuracy(horizontalAccuracy);
+ }
+ if((flags & LOCATION_HAS_VERTICAL_ACCURACY) == LOCATION_HAS_VERTICAL_ACCURACY) {
+ location.setVerticalAccuracyMeters(verticalAccuracy);
+ }
+ if((flags & LOCATION_HAS_SPEED_ACCURACY) == LOCATION_HAS_SPEED_ACCURACY) {
+ location.setSpeedAccuracyMetersPerSecond(speedAccuracy);
+ }
+ if((flags & LOCATION_HAS_BEARING_ACCURACY) == LOCATION_HAS_BEARING_ACCURACY) {
+ location.setBearingAccuracyDegrees(bearingAccuracy);
}
return location;
}
@@ -1831,8 +1872,9 @@ public class GnssLocationProvider implements LocationProviderInterface {
* All geofence callbacks are called on the same thread
*/
private void reportGeofenceTransition(int geofenceId, int flags, double latitude,
- double longitude, double altitude, float speed, float bearing, float accuracy,
- long timestamp, int transition, long transitionTimestamp) {
+ double longitude, double altitude, float speed, float bearing, float horizontalAccuracy,
+ float verticalAccuracy, float speedAccuracy, float bearingAccuracy, long timestamp,
+ int transition, long transitionTimestamp) {
if (mGeofenceHardwareImpl == null) {
mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
}
@@ -1843,7 +1885,10 @@ public class GnssLocationProvider implements LocationProviderInterface {
altitude,
speed,
bearing,
- accuracy,
+ horizontalAccuracy,
+ verticalAccuracy,
+ speedAccuracy,
+ bearingAccuracy,
timestamp);
mGeofenceHardwareImpl.reportGeofenceTransition(
geofenceId,
@@ -1858,8 +1903,8 @@ public class GnssLocationProvider implements LocationProviderInterface {
* called from native code to report GPS status change.
*/
private void reportGeofenceStatus(int status, int flags, double latitude,
- double longitude, double altitude, float speed, float bearing, float accuracy,
- long timestamp) {
+ double longitude, double altitude, float speed, float bearing, float horizontalAccuracy,
+ float verticalAccuracy, float speedAccuracy, float bearingAccuracy, long timestamp) {
if (mGeofenceHardwareImpl == null) {
mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
}
@@ -1870,7 +1915,10 @@ public class GnssLocationProvider implements LocationProviderInterface {
altitude,
speed,
bearing,
- accuracy,
+ horizontalAccuracy,
+ verticalAccuracy,
+ speedAccuracy,
+ bearingAccuracy,
timestamp);
int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
if(status == GPS_GEOFENCE_AVAILABLE) {
@@ -2069,10 +2117,7 @@ public class GnssLocationProvider implements LocationProviderInterface {
// note that this assumes the message will not be removed from the queue before
// it is handled (otherwise the wake lock would be leaked).
mWakeLock.acquire();
- if (Log.isLoggable(TAG, Log.INFO)) {
- Log.i(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
- + ", " + obj + ")");
- }
+ Log.i(TAG, "WakeLock acquired by sendMessage(" + message + ", " + arg + ", " + obj + ")");
mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
}
@@ -2130,10 +2175,8 @@ public class GnssLocationProvider implements LocationProviderInterface {
if (msg.arg2 == 1) {
// wakelock was taken for this message, release it
mWakeLock.release();
- if (Log.isLoggable(TAG, Log.INFO)) {
- Log.i(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
- + ", " + msg.arg1 + ", " + msg.obj + ")");
- }
+ Log.i(TAG, "WakeLock released by handleMessage(" + message + ", " + msg.arg1 + ", "
+ + msg.obj + ")");
}
}
@@ -2381,40 +2424,6 @@ public class GnssLocationProvider implements LocationProviderInterface {
}
}
- /**
- * @return A string representing the given message ID.
- */
- private String messageIdAsString(int message) {
- switch (message) {
- case ENABLE:
- return "ENABLE";
- case SET_REQUEST:
- return "SET_REQUEST";
- case UPDATE_NETWORK_STATE:
- return "UPDATE_NETWORK_STATE";
- case REQUEST_SUPL_CONNECTION:
- return "REQUEST_SUPL_CONNECTION";
- case RELEASE_SUPL_CONNECTION:
- return "RELEASE_SUPL_CONNECTION";
- case INJECT_NTP_TIME:
- return "INJECT_NTP_TIME";
- case DOWNLOAD_XTRA_DATA:
- return "DOWNLOAD_XTRA_DATA";
- case INJECT_NTP_TIME_FINISHED:
- return "INJECT_NTP_TIME_FINISHED";
- case DOWNLOAD_XTRA_DATA_FINISHED:
- return "DOWNLOAD_XTRA_DATA_FINISHED";
- case UPDATE_LOCATION:
- return "UPDATE_LOCATION";
- case SUBSCRIPTION_OR_SIM_CHANGED:
- return "SUBSCRIPTION_OR_SIM_CHANGED";
- case INITIALIZE_HANDLER:
- return "INITIALIZE_HANDLER";
- default:
- return "