Add inter-signal bias fields to GnssMeasurement and GnssClock

Bug: 147500886

Test: atest GnssMeasurementTest
      atest GnssClockTest

Change-Id: I8adaf1c1b0f6478695ca9b4768568af0ebfb11d4
diff --git a/Android.bp b/Android.bp
index 5fcefa6..abd0b7c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -330,6 +330,7 @@
         "android.hardware.cas-V1.0-java",
         "android.hardware.contexthub-V1.0-java",
         "android.hardware.gnss-V1.0-java",
+        "android.hardware.gnss-V2.1-java",
         "android.hardware.health-V1.0-java-constants",
         "android.hardware.radio-V1.0-java",
         "android.hardware.radio-V1.1-java",
diff --git a/api/current.txt b/api/current.txt
index e662783..4e94bb9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23296,6 +23296,9 @@
     method public long getFullBiasNanos();
     method public int getHardwareClockDiscontinuityCount();
     method public int getLeapSecond();
+    method @FloatRange(from=0.0) public double getReferenceCarrierFrequencyHzForIsb();
+    method @NonNull public String getReferenceCodeTypeForIsb();
+    method public int getReferenceConstellationTypeForIsb();
     method public long getTimeNanos();
     method @FloatRange(from=0.0f) public double getTimeUncertaintyNanos();
     method public boolean hasBiasNanos();
@@ -23306,6 +23309,9 @@
     method public boolean hasElapsedRealtimeUncertaintyNanos();
     method public boolean hasFullBiasNanos();
     method public boolean hasLeapSecond();
+    method public boolean hasReferenceCarrierFrequencyHzForIsb();
+    method public boolean hasReferenceCodeTypeForIsb();
+    method public boolean hasReferenceConstellationTypeForIsb();
     method public boolean hasTimeUncertaintyNanos();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssClock> CREATOR;
@@ -23330,6 +23336,10 @@
     method public double getPseudorangeRateUncertaintyMetersPerSecond();
     method public long getReceivedSvTimeNanos();
     method public long getReceivedSvTimeUncertaintyNanos();
+    method public double getReceiverInterSignalBiasNanos();
+    method @FloatRange(from=0.0) public double getReceiverInterSignalBiasUncertaintyNanos();
+    method public double getSatelliteInterSignalBiasNanos();
+    method @FloatRange(from=0.0) public double getSatelliteInterSignalBiasUncertaintyNanos();
     method public double getSnrInDb();
     method public int getState();
     method public int getSvid();
@@ -23341,6 +23351,10 @@
     method @Deprecated public boolean hasCarrierPhase();
     method @Deprecated public boolean hasCarrierPhaseUncertainty();
     method public boolean hasCodeType();
+    method public boolean hasReceiverInterSignalBiasNanos();
+    method public boolean hasReceiverInterSignalBiasUncertaintyNanos();
+    method public boolean hasSatelliteInterSignalBiasNanos();
+    method public boolean hasSatelliteInterSignalBiasUncertaintyNanos();
     method public boolean hasSnrInDb();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4
diff --git a/api/test-current.txt b/api/test-current.txt
index 190f9fe..5ae2e49 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1137,6 +1137,9 @@
     method public void resetElapsedRealtimeUncertaintyNanos();
     method public void resetFullBiasNanos();
     method public void resetLeapSecond();
+    method public void resetReferenceCarrierFrequencyHzForIsb();
+    method public void resetReferenceCodeTypeForIsb();
+    method public void resetReferenceConstellationTypeForIsb();
     method public void resetTimeUncertaintyNanos();
     method public void set(android.location.GnssClock);
     method public void setBiasNanos(double);
@@ -1148,6 +1151,9 @@
     method public void setFullBiasNanos(long);
     method public void setHardwareClockDiscontinuityCount(int);
     method public void setLeapSecond(int);
+    method public void setReferenceCarrierFrequencyHzForIsb(@FloatRange(from=0.0) double);
+    method public void setReferenceCodeTypeForIsb(@NonNull String);
+    method public void setReferenceConstellationTypeForIsb(int);
     method public void setTimeNanos(long);
     method public void setTimeUncertaintyNanos(@FloatRange(from=0.0f) double);
   }
@@ -1162,6 +1168,10 @@
     method @Deprecated public void resetCarrierPhase();
     method @Deprecated public void resetCarrierPhaseUncertainty();
     method public void resetCodeType();
+    method public void resetReceiverInterSignalBiasNanos();
+    method public void resetReceiverInterSignalBiasUncertaintyNanos();
+    method public void resetSatelliteInterSignalBiasNanos();
+    method public void resetSatelliteInterSignalBiasUncertaintyNanos();
     method public void resetSnrInDb();
     method public void set(android.location.GnssMeasurement);
     method public void setAccumulatedDeltaRangeMeters(double);
@@ -1181,6 +1191,10 @@
     method public void setPseudorangeRateUncertaintyMetersPerSecond(double);
     method public void setReceivedSvTimeNanos(long);
     method public void setReceivedSvTimeUncertaintyNanos(long);
+    method public void setReceiverInterSignalBiasNanos(double);
+    method public void setReceiverInterSignalBiasUncertaintyNanos(@FloatRange(from=0.0) double);
+    method public void setSatelliteInterSignalBiasNanos(double);
+    method public void setSatelliteInterSignalBiasUncertaintyNanos(@FloatRange(from=0.0) double);
     method public void setSnrInDb(double);
     method public void setState(int);
     method public void setSvid(int);
diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt
index 603f7a2..5669b64 100644
--- a/api/test-lint-baseline.txt
+++ b/api/test-lint-baseline.txt
@@ -396,7 +396,13 @@
 GetterSetterNames: android.location.GnssClock#setFullBiasNanos(long):
     
 GetterSetterNames: android.location.GnssClock#setLeapSecond(int):
-    
+
+GetterSetterNames: android.location.GnssClock#setReferenceConstellationTypeForIsb(int):
+
+GetterSetterNames: android.location.GnssClock#setReferenceCarrierFrequencyHzForIsb(double):
+
+GetterSetterNames: android.location.GnssClock#setReferenceCodeTypeForIsb(String):
+
 GetterSetterNames: android.location.GnssClock#setTimeUncertaintyNanos(double):
     
 GetterSetterNames: android.location.GnssMeasurement#setBasebandCn0DbHz(double):
@@ -404,7 +410,15 @@
 GetterSetterNames: android.location.GnssMeasurement#setCarrierFrequencyHz(float):
     
 GetterSetterNames: android.location.GnssMeasurement#setCodeType(String):
-    
+
+GetterSetterNames: android.location.GnssMeasurement#setReceiverInterSignalBiasNanos(double):
+
+GetterSetterNames: android.location.GnssMeasurement#setReceiverInterSignalBiasUncertaintyNanos(double):
+
+GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasNanos(double):
+
+GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasUncertaintyNanos(double):
+
 GetterSetterNames: android.location.GnssMeasurement#setSnrInDb(double):
     
 GetterSetterNames: android.location.LocationRequest#isLocationSettingsIgnored():
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index 8a7878b..ed4bf1b 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -17,6 +17,7 @@
 package android.location;
 
 import android.annotation.FloatRange;
+import android.annotation.NonNull;
 import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -39,6 +40,9 @@
     private static final int HAS_DRIFT_UNCERTAINTY = (1<<6);
     private static final int HAS_ELAPSED_REALTIME_NANOS = (1 << 7);
     private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS = (1 << 8);
+    private static final int HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB = (1 << 9);
+    private static final int HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB = (1 << 10);
+    private static final int HAS_REFERENCE_CODE_TYPE_FOR_ISB = (1 << 11);
 
     // End enumerations in sync with gps.h
 
@@ -54,6 +58,9 @@
     private int mHardwareClockDiscontinuityCount;
     private long mElapsedRealtimeNanos;
     private double mElapsedRealtimeUncertaintyNanos;
+    private int mReferenceConstellationTypeForIsb;
+    private double mReferenceCarrierFrequencyHzForIsb;
+    private String mReferenceCodeTypeForIsb;
 
     /**
      * @hide
@@ -81,6 +88,9 @@
         mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount;
         mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos;
         mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos;
+        mReferenceConstellationTypeForIsb = clock.mReferenceConstellationTypeForIsb;
+        mReferenceCarrierFrequencyHzForIsb = clock.mReferenceCarrierFrequencyHzForIsb;
+        mReferenceCodeTypeForIsb = clock.mReferenceCodeTypeForIsb;
     }
 
     /**
@@ -196,7 +206,6 @@
     @TestApi
     public void resetTimeUncertaintyNanos() {
         resetFlag(HAS_TIME_UNCERTAINTY);
-        mTimeUncertaintyNanos = Double.NaN;
     }
 
     /**
@@ -286,7 +295,6 @@
     @TestApi
     public void resetBiasNanos() {
         resetFlag(HAS_BIAS);
-        mBiasNanos = Double.NaN;
     }
 
     /**
@@ -327,7 +335,6 @@
     @TestApi
     public void resetBiasUncertaintyNanos() {
         resetFlag(HAS_BIAS_UNCERTAINTY);
-        mBiasUncertaintyNanos = Double.NaN;
     }
 
     /**
@@ -371,7 +378,6 @@
     @TestApi
     public void resetDriftNanosPerSecond() {
         resetFlag(HAS_DRIFT);
-        mDriftNanosPerSecond = Double.NaN;
     }
 
     /**
@@ -411,7 +417,6 @@
     @TestApi
     public void resetDriftUncertaintyNanosPerSecond() {
         resetFlag(HAS_DRIFT_UNCERTAINTY);
-        mDriftUncertaintyNanosPerSecond = Double.NaN;
     }
 
     /**
@@ -495,7 +500,128 @@
     @TestApi
     public void resetElapsedRealtimeUncertaintyNanos() {
         resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
-        mElapsedRealtimeUncertaintyNanos = Double.NaN;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getReferenceConstellationTypeForIsb()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasReferenceConstellationTypeForIsb() {
+        return isFlagSet(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB);
+    }
+
+    /**
+     * Returns the reference constellation type for inter-signal bias.
+     *
+     * <p>The value is only available if {@link #hasReferenceConstellationTypeForIsb()} is
+     * {@code true}.
+     *
+     * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
+     * {@link GnssStatus}.
+     */
+    @GnssStatus.ConstellationType
+    public int getReferenceConstellationTypeForIsb() {
+        return mReferenceConstellationTypeForIsb;
+    }
+
+    /**
+     * Sets the reference constellation type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void setReferenceConstellationTypeForIsb(@GnssStatus.ConstellationType int value) {
+        setFlag(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB);
+        mReferenceConstellationTypeForIsb = value;
+    }
+
+    /**
+     * Resets the reference constellation type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void resetReferenceConstellationTypeForIsb() {
+        resetFlag(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB);
+        mReferenceConstellationTypeForIsb = GnssStatus.CONSTELLATION_UNKNOWN;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getReferenceCarrierFrequencyHzForIsb()} is available, {@code
+     * false} otherwise.
+     */
+    public boolean hasReferenceCarrierFrequencyHzForIsb() {
+        return isFlagSet(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB);
+    }
+
+    /**
+     * Returns the reference carrier frequency in Hz for inter-signal bias.
+     *
+     * <p>The value is only available if {@link #hasReferenceCarrierFrequencyHzForIsb()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0)
+    public double getReferenceCarrierFrequencyHzForIsb() {
+        return mReferenceCarrierFrequencyHzForIsb;
+    }
+
+    /**
+     * Sets the reference carrier frequency in Hz for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void setReferenceCarrierFrequencyHzForIsb(@FloatRange(from = 0.0) double value) {
+        setFlag(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB);
+        mReferenceCarrierFrequencyHzForIsb = value;
+    }
+
+    /**
+     * Resets the reference carrier frequency in Hz for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void resetReferenceCarrierFrequencyHzForIsb() {
+        resetFlag(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getReferenceCodeTypeForIsb()} is available, {@code
+     * false} otherwise.
+     */
+    public boolean hasReferenceCodeTypeForIsb() {
+        return isFlagSet(HAS_REFERENCE_CODE_TYPE_FOR_ISB);
+    }
+
+    /**
+     * Returns the reference code type for inter-signal bias.
+     *
+     * <p>The value is only available if {@link #hasReferenceCodeTypeForIsb()} is
+     * {@code true}.
+     *
+     * <p>The return value is one of those constants defined in
+     * {@link GnssMeasurement#getCodeType()}.
+     */
+    @NonNull
+    public String getReferenceCodeTypeForIsb() {
+        return mReferenceCodeTypeForIsb;
+    }
+
+    /**
+     * Sets the reference code type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void setReferenceCodeTypeForIsb(@NonNull String codeType) {
+        setFlag(HAS_REFERENCE_CODE_TYPE_FOR_ISB);
+        mReferenceCodeTypeForIsb = codeType;
+    }
+
+    /**
+     * Resets the reference code type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void resetReferenceCodeTypeForIsb() {
+        resetFlag(HAS_REFERENCE_CODE_TYPE_FOR_ISB);
+        mReferenceCodeTypeForIsb = "UNKNOWN";
     }
 
     /**
@@ -543,6 +669,9 @@
             gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt();
             gpsClock.mElapsedRealtimeNanos = parcel.readLong();
             gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readDouble();
+            gpsClock.mReferenceConstellationTypeForIsb = parcel.readInt();
+            gpsClock.mReferenceCarrierFrequencyHzForIsb = parcel.readDouble();
+            gpsClock.mReferenceCodeTypeForIsb = parcel.readString();
 
             return gpsClock;
         }
@@ -567,6 +696,9 @@
         parcel.writeInt(mHardwareClockDiscontinuityCount);
         parcel.writeLong(mElapsedRealtimeNanos);
         parcel.writeDouble(mElapsedRealtimeUncertaintyNanos);
+        parcel.writeInt(mReferenceConstellationTypeForIsb);
+        parcel.writeDouble(mReferenceCarrierFrequencyHzForIsb);
+        parcel.writeString(mReferenceCodeTypeForIsb);
     }
 
     @Override
@@ -580,7 +712,9 @@
         final String formatWithUncertainty = "   %-15s = %-25s   %-26s = %s\n";
         StringBuilder builder = new StringBuilder("GnssClock:\n");
 
-        builder.append(String.format(format, "LeapSecond", hasLeapSecond() ? mLeapSecond : null));
+        if (hasLeapSecond()) {
+            builder.append(String.format(format, "LeapSecond", mLeapSecond));
+        }
 
         builder.append(String.format(
                 formatWithUncertainty,
@@ -589,39 +723,57 @@
                 "TimeUncertaintyNanos",
                 hasTimeUncertaintyNanos() ? mTimeUncertaintyNanos : null));
 
-        builder.append(String.format(
-                format,
-                "FullBiasNanos",
-                hasFullBiasNanos() ? mFullBiasNanos : null));
+        if (hasFullBiasNanos()) {
+            builder.append(String.format(format, "FullBiasNanos", mFullBiasNanos));
+        }
 
-        builder.append(String.format(
-                formatWithUncertainty,
-                "BiasNanos",
-                hasBiasNanos() ? mBiasNanos : null,
-                "BiasUncertaintyNanos",
-                hasBiasUncertaintyNanos() ? mBiasUncertaintyNanos : null));
+        if (hasBiasNanos() || hasBiasUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "BiasNanos",
+                    hasBiasNanos() ? mBiasNanos : null,
+                    "BiasUncertaintyNanos",
+                    hasBiasUncertaintyNanos() ? mBiasUncertaintyNanos : null));
+        }
 
-        builder.append(String.format(
-                formatWithUncertainty,
-                "DriftNanosPerSecond",
-                hasDriftNanosPerSecond() ? mDriftNanosPerSecond : null,
-                "DriftUncertaintyNanosPerSecond",
-                hasDriftUncertaintyNanosPerSecond() ? mDriftUncertaintyNanosPerSecond : null));
+        if (hasDriftNanosPerSecond() || hasDriftUncertaintyNanosPerSecond()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "DriftNanosPerSecond",
+                    hasDriftNanosPerSecond() ? mDriftNanosPerSecond : null,
+                    "DriftUncertaintyNanosPerSecond",
+                    hasDriftUncertaintyNanosPerSecond() ? mDriftUncertaintyNanosPerSecond : null));
+        }
 
         builder.append(String.format(
                 format,
                 "HardwareClockDiscontinuityCount",
                 mHardwareClockDiscontinuityCount));
 
-        builder.append(String.format(
-                format,
-                "ElapsedRealtimeNanos",
-                hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null));
+        if (hasElapsedRealtimeNanos() || hasElapsedRealtimeUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "ElapsedRealtimeNanos",
+                    hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null,
+                    "ElapsedRealtimeUncertaintyNanos",
+                    hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos
+                            : null));
+        }
 
-        builder.append(String.format(
-                format,
-                "ElapsedRealtimeUncertaintyNanos",
-                hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos : null));
+        if (hasReferenceConstellationTypeForIsb()) {
+            builder.append(String.format(format, "ReferenceConstellationTypeForIsb",
+                    mReferenceConstellationTypeForIsb));
+        }
+
+        if (hasReferenceCarrierFrequencyHzForIsb()) {
+            builder.append(String.format(format, "ReferenceCarrierFrequencyHzForIsb",
+                    mReferenceCarrierFrequencyHzForIsb));
+        }
+
+        if (hasReferenceCodeTypeForIsb()) {
+            builder.append(
+                    String.format(format, "ReferenceCodeTypeForIsb", mReferenceCodeTypeForIsb));
+        }
 
         return builder.toString();
     }
@@ -639,6 +791,9 @@
         setHardwareClockDiscontinuityCount(Integer.MIN_VALUE);
         resetElapsedRealtimeNanos();
         resetElapsedRealtimeUncertaintyNanos();
+        resetReferenceConstellationTypeForIsb();
+        resetReferenceCarrierFrequencyHzForIsb();
+        resetReferenceCodeTypeForIsb();
     }
 
     private void setFlag(int flag) {
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 70abbb3..75097f9 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -16,11 +16,21 @@
 
 package android.location;
 
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_AUTOMATIC_GAIN_CONTROL;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_CYCLES;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_FREQUENCY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_PHASE;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_PHASE_UNCERTAINTY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_RECEIVER_ISB;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_RECEIVER_ISB_UNCERTAINTY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SATELLITE_ISB;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SATELLITE_ISB_UNCERTAINTY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SNR;
+
 import android.annotation.FloatRange;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.TestApi;
-import android.hardware.gnss.V1_0.IGnssMeasurementCallback.GnssMeasurementFlags;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -53,19 +63,14 @@
     private double mSnrInDb;
     private double mAutomaticGainControlLevelInDb;
     @NonNull private String mCodeType;
+    private double mReceiverInterSignalBiasNanos;
+    private double mReceiverInterSignalBiasUncertaintyNanos;
+    private double mSatelliteInterSignalBiasNanos;
+    private double mSatelliteInterSignalBiasUncertaintyNanos;
 
     // The following enumerations must be in sync with the values declared in GNSS HAL.
 
     private static final int HAS_NO_FLAGS = 0;
-    private static final int HAS_SNR = GnssMeasurementFlags.HAS_SNR;
-    private static final int HAS_CARRIER_FREQUENCY = GnssMeasurementFlags.HAS_CARRIER_FREQUENCY;
-    private static final int HAS_CARRIER_CYCLES = GnssMeasurementFlags.HAS_CARRIER_CYCLES;
-    private static final int HAS_CARRIER_PHASE = GnssMeasurementFlags.HAS_CARRIER_PHASE;
-    private static final int HAS_CARRIER_PHASE_UNCERTAINTY =
-            GnssMeasurementFlags.HAS_CARRIER_PHASE_UNCERTAINTY;
-    private static final int HAS_AUTOMATIC_GAIN_CONTROL =
-            GnssMeasurementFlags.HAS_AUTOMATIC_GAIN_CONTROL;
-
     private static final int HAS_CODE_TYPE = (1 << 14);
     private static final int HAS_BASEBAND_CN0 = (1 << 15);
 
@@ -263,6 +268,12 @@
         mSnrInDb = measurement.mSnrInDb;
         mAutomaticGainControlLevelInDb = measurement.mAutomaticGainControlLevelInDb;
         mCodeType = measurement.mCodeType;
+        mReceiverInterSignalBiasNanos = measurement.mReceiverInterSignalBiasNanos;
+        mReceiverInterSignalBiasUncertaintyNanos =
+                measurement.mReceiverInterSignalBiasUncertaintyNanos;
+        mSatelliteInterSignalBiasNanos = measurement.mSatelliteInterSignalBiasNanos;
+        mSatelliteInterSignalBiasUncertaintyNanos =
+                measurement.mSatelliteInterSignalBiasUncertaintyNanos;
     }
 
     /**
@@ -835,7 +846,6 @@
     @TestApi
     public void resetBasebandCn0DbHz() {
         resetFlag(HAS_BASEBAND_CN0);
-        mBasebandCn0DbHz = Double.NaN;
     }
 
     /**
@@ -1166,7 +1176,6 @@
     @Deprecated
     public void resetCarrierPhase() {
         resetFlag(HAS_CARRIER_PHASE);
-        mCarrierPhase = Double.NaN;
     }
 
     /**
@@ -1221,7 +1230,6 @@
     @Deprecated
     public void resetCarrierPhaseUncertainty() {
         resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
-        mCarrierPhaseUncertainty = Double.NaN;
     }
 
     /**
@@ -1292,7 +1300,6 @@
     @TestApi
     public void resetSnrInDb() {
         resetFlag(HAS_SNR);
-        mSnrInDb = Double.NaN;
     }
 
     /**
@@ -1340,7 +1347,6 @@
     @TestApi
     public void resetAutomaticGainControlLevel() {
         resetFlag(HAS_AUTOMATIC_GAIN_CONTROL);
-        mAutomaticGainControlLevelInDb = Double.NaN;
     }
 
     /**
@@ -1425,7 +1431,200 @@
         mCodeType = "UNKNOWN";
     }
 
-    public static final @android.annotation.NonNull Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
+    /**
+     * Returns {@code true} if {@link #getReceiverInterSignalBiasNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasReceiverInterSignalBiasNanos() {
+        return isFlagSet(HAS_RECEIVER_ISB);
+    }
+
+    /**
+     * Gets the GNSS measurement's receiver inter-signal bias in nanoseconds with sub-nanosecond
+     * accuracy.
+     *
+     * <p>This value is the estimated receiver-side inter-system (different from the
+     * constellation in {@link GnssClock#getReferenceConstellationTypeForIsb()} bias and
+     * inter-frequency (different from the carrier frequency in
+     * {@link GnssClock#getReferenceCarrierFrequencyHzForIsb()}) bias. The reported receiver
+     * inter-signal bias must include signal delays caused by:
+     *
+     * <ul>
+     * <li>Receiver inter-constellation bias</li>
+     * <li>Receiver inter-frequency bias</li>
+     * <li>Receiver inter-code bias</li>
+     * </ul>
+     *
+     * <p>The value does not include the inter-frequency Ionospheric bias.
+     *
+     * <p>The value is only available if {@link #hasReceiverInterSignalBiasNanos()} is {@code true}.
+     */
+    public double getReceiverInterSignalBiasNanos() {
+        return mReceiverInterSignalBiasNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's receiver inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setReceiverInterSignalBiasNanos(double receiverInterSignalBiasNanos) {
+        setFlag(HAS_RECEIVER_ISB);
+        mReceiverInterSignalBiasNanos = receiverInterSignalBiasNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's receiver inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetReceiverInterSignalBiasNanos() {
+        resetFlag(HAS_RECEIVER_ISB);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getReceiverInterSignalBiasUncertaintyNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasReceiverInterSignalBiasUncertaintyNanos() {
+        return isFlagSet(HAS_RECEIVER_ISB_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the GNSS measurement's receiver inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds with sub-nanosecond accuracy.
+     *
+     * <p>The value is only available if {@link #hasReceiverInterSignalBiasUncertaintyNanos()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0)
+    public double getReceiverInterSignalBiasUncertaintyNanos() {
+        return mReceiverInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's receiver inter-signal bias uncertainty (1 sigma) in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setReceiverInterSignalBiasUncertaintyNanos(@FloatRange(from = 0.0)
+            double receiverInterSignalBiasUncertaintyNanos) {
+        setFlag(HAS_RECEIVER_ISB_UNCERTAINTY);
+        mReceiverInterSignalBiasUncertaintyNanos = receiverInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's receiver inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetReceiverInterSignalBiasUncertaintyNanos() {
+        resetFlag(HAS_RECEIVER_ISB_UNCERTAINTY);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getSatelliteInterSignalBiasNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasSatelliteInterSignalBiasNanos() {
+        return isFlagSet(HAS_SATELLITE_ISB);
+    }
+
+    /**
+     * Gets the GNSS measurement's satellite inter-signal bias in nanoseconds with sub-nanosecond
+     * accuracy.
+     *
+     * <p>This value is the satellite-and-control-segment-side inter-system (different from the
+     * constellation in {@link GnssClock#getReferenceConstellationTypeForIsb()}) bias and
+     * inter-frequency (different from the carrier frequency in
+     * {@link GnssClock#getReferenceCarrierFrequencyHzForIsb()}) bias, including:
+     *
+     * <ul>
+     * <li>Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPT-UTC Time Offset (TauGps),
+     * BDS-GLO Time Offset (BGTO))</li>
+     * <li>Group delay (e.g., Total Group Delay (TGD))</li>
+     * <li>Satellite inter-signal bias, which includes satellite inter-frequency bias (GLO only),
+     * and satellite inter-code bias (e.g., Differential Code Bias (DCB)).</li>
+     * </ul>
+     *
+     * <p>The value is only available if {@link #hasSatelliteInterSignalBiasNanos()} is {@code
+     * true}.
+     */
+    public double getSatelliteInterSignalBiasNanos() {
+        return mSatelliteInterSignalBiasNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's satellite inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setSatelliteInterSignalBiasNanos(double satelliteInterSignalBiasNanos) {
+        setFlag(HAS_SATELLITE_ISB);
+        mSatelliteInterSignalBiasNanos = satelliteInterSignalBiasNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's satellite inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetSatelliteInterSignalBiasNanos() {
+        resetFlag(HAS_SATELLITE_ISB);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getSatelliteInterSignalBiasUncertaintyNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasSatelliteInterSignalBiasUncertaintyNanos() {
+        return isFlagSet(HAS_SATELLITE_ISB_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the GNSS measurement's satellite inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds with sub-nanosecond accuracy.
+     *
+     * <p>The value is only available if {@link #hasSatelliteInterSignalBiasUncertaintyNanos()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0)
+    public double getSatelliteInterSignalBiasUncertaintyNanos() {
+        return mSatelliteInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's satellite inter-signal bias uncertainty (1 sigma) in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setSatelliteInterSignalBiasUncertaintyNanos(@FloatRange(from = 0.0)
+            double satelliteInterSignalBiasUncertaintyNanos) {
+        setFlag(HAS_SATELLITE_ISB_UNCERTAINTY);
+        mSatelliteInterSignalBiasUncertaintyNanos = satelliteInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's satellite inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetSatelliteInterSignalBiasUncertaintyNanos() {
+        resetFlag(HAS_SATELLITE_ISB_UNCERTAINTY);
+    }
+
+
+    public static final @NonNull Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
         @Override
         public GnssMeasurement createFromParcel(Parcel parcel) {
             GnssMeasurement gnssMeasurement = new GnssMeasurement();
@@ -1452,6 +1651,10 @@
             gnssMeasurement.mAutomaticGainControlLevelInDb = parcel.readDouble();
             gnssMeasurement.mCodeType = parcel.readString();
             gnssMeasurement.mBasebandCn0DbHz = parcel.readDouble();
+            gnssMeasurement.mReceiverInterSignalBiasNanos = parcel.readDouble();
+            gnssMeasurement.mReceiverInterSignalBiasUncertaintyNanos = parcel.readDouble();
+            gnssMeasurement.mSatelliteInterSignalBiasNanos = parcel.readDouble();
+            gnssMeasurement.mSatelliteInterSignalBiasUncertaintyNanos = parcel.readDouble();
 
             return gnssMeasurement;
         }
@@ -1486,6 +1689,10 @@
         parcel.writeDouble(mAutomaticGainControlLevelInDb);
         parcel.writeString(mCodeType);
         parcel.writeDouble(mBasebandCn0DbHz);
+        parcel.writeDouble(mReceiverInterSignalBiasNanos);
+        parcel.writeDouble(mReceiverInterSignalBiasUncertaintyNanos);
+        parcel.writeDouble(mSatelliteInterSignalBiasNanos);
+        parcel.writeDouble(mSatelliteInterSignalBiasUncertaintyNanos);
     }
 
     @Override
@@ -1514,8 +1721,9 @@
 
         builder.append(String.format(format, "Cn0DbHz", mCn0DbHz));
 
-        builder.append(String.format(format, "BasebandCn0DbHz",
-                hasBasebandCn0DbHz() ? mBasebandCn0DbHz : null));
+        if (hasBasebandCn0DbHz()) {
+            builder.append(String.format(format, "BasebandCn0DbHz", mBasebandCn0DbHz));
+        }
 
         builder.append(String.format(
                 formatWithUncertainty,
@@ -1536,37 +1744,57 @@
                 "AccumulatedDeltaRangeUncertaintyMeters",
                 mAccumulatedDeltaRangeUncertaintyMeters));
 
-        builder.append(String.format(
-                format,
-                "CarrierFrequencyHz",
-                hasCarrierFrequencyHz() ? mCarrierFrequencyHz : null));
+        if (hasCarrierFrequencyHz()) {
+            builder.append(String.format(format, "CarrierFrequencyHz", mCarrierFrequencyHz));
+        }
 
-        builder.append(String.format(
-                format,
-                "CarrierCycles",
-                hasCarrierCycles() ? mCarrierCycles : null));
+        if (hasCarrierCycles()) {
+            builder.append(String.format(format, "CarrierCycles", mCarrierCycles));
+        }
 
-        builder.append(String.format(
-                formatWithUncertainty,
-                "CarrierPhase",
-                hasCarrierPhase() ? mCarrierPhase : null,
-                "CarrierPhaseUncertainty",
-                hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
+        if (hasCarrierPhase() || hasCarrierPhaseUncertainty()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "CarrierPhase",
+                    hasCarrierPhase() ? mCarrierPhase : null,
+                    "CarrierPhaseUncertainty",
+                    hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
+        }
 
         builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
 
-        builder.append(String.format(
-                format,
-                "SnrInDb",
-                hasSnrInDb() ? mSnrInDb : null));
-        builder.append(String.format(
-                format,
-                "AgcLevelDb",
-                hasAutomaticGainControlLevelDb() ? mAutomaticGainControlLevelInDb : null));
-        builder.append(String.format(
-                format,
-                "CodeType",
-                hasCodeType() ? mCodeType : null));
+        if (hasSnrInDb()) {
+            builder.append(String.format(format, "SnrInDb", mSnrInDb));
+        }
+
+        if (hasAutomaticGainControlLevelDb()) {
+            builder.append(String.format(format, "AgcLevelDb", mAutomaticGainControlLevelInDb));
+        }
+
+        if (hasCodeType()) {
+            builder.append(String.format(format, "CodeType", mCodeType));
+        }
+
+        if (hasReceiverInterSignalBiasNanos() || hasReceiverInterSignalBiasUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "ReceiverInterSignalBiasNs",
+                    hasReceiverInterSignalBiasNanos() ? mReceiverInterSignalBiasNanos : null,
+                    "ReceiverInterSignalBiasUncertaintyNs",
+                    hasReceiverInterSignalBiasUncertaintyNanos()
+                            ? mReceiverInterSignalBiasUncertaintyNanos : null));
+        }
+
+        if (hasSatelliteInterSignalBiasNanos() || hasSatelliteInterSignalBiasUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "SatelliteInterSignalBiasNs",
+                    hasSatelliteInterSignalBiasNanos() ? mSatelliteInterSignalBiasNanos : null,
+                    "SatelliteInterSignalBiasUncertaintyNs",
+                    hasSatelliteInterSignalBiasUncertaintyNanos()
+                            ? mSatelliteInterSignalBiasUncertaintyNanos
+                            : null));
+        }
 
         return builder.toString();
     }
@@ -1593,6 +1821,10 @@
         resetAutomaticGainControlLevel();
         resetCodeType();
         resetBasebandCn0DbHz();
+        resetReceiverInterSignalBiasNanos();
+        resetReceiverInterSignalBiasUncertaintyNanos();
+        resetSatelliteInterSignalBiasNanos();
+        resetSatelliteInterSignalBiasUncertaintyNanos();
     }
 
     private void setFlag(int flag) {
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 00436bb..08a7592 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1208,6 +1208,22 @@
     translateSingleGnssMeasurement(&(measurement_V2_1->v2_0), object);
 
     SET(BasebandCn0DbHz, measurement_V2_1->basebandCN0DbHz);
+
+    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_RECEIVER_ISB) {
+        SET(ReceiverInterSignalBiasNs, measurement_V2_1->receiverInterSignalBiasNs);
+    }
+
+    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_RECEIVER_ISB_UNCERTAINTY) {
+        SET(ReceiverInterSignalBiasUncertaintyNs, measurement_V2_1->receiverInterSignalBiasUncertaintyNs);
+    }
+
+    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_SATELLITE_ISB) {
+        SET(SatelliteInterSignalBiasNs, measurement_V2_1->satelliteInterSignalBiasNs);
+    }
+
+    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_SATELLITE_ISB_UNCERTAINTY) {
+        SET(SatelliteInterSignalBiasUncertaintyNs, measurement_V2_1->satelliteInterSignalBiasUncertaintyNs);
+    }
 }
 
 template<class T>
@@ -1253,6 +1269,19 @@
 
 template<>
 void GnssMeasurementCallback::translateGnssClock(
+       JavaObject& object, const IGnssMeasurementCallback_V2_1::GnssClock& clock) {
+    JNIEnv* env = getJniEnv();
+    SET(ReferenceConstellationTypeForIsb,
+            static_cast<int32_t>(clock.referenceSignalTypeForIsb.constellation));
+    SET(ReferenceCarrierFrequencyHzForIsb, clock.referenceSignalTypeForIsb.carrierFrequencyHz);
+    SET(ReferenceCodeTypeForIsb,
+            env->NewStringUTF(clock.referenceSignalTypeForIsb.codeType.c_str()));
+
+    translateGnssClock(object, clock.v1_0);
+}
+
+template<>
+void GnssMeasurementCallback::translateGnssClock(
        JavaObject& object, const IGnssMeasurementCallback_V2_0::GnssData& data) {
     auto elapsedRealtime = data.elapsedRealtime;
     uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
@@ -1265,6 +1294,20 @@
     translateGnssClock(object, data.clock);
 }
 
+template<>
+void GnssMeasurementCallback::translateGnssClock(
+       JavaObject& object, const IGnssMeasurementCallback_V2_1::GnssData& data) {
+    auto elapsedRealtime = data.elapsedRealtime;
+    uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
+    if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+        SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
+    }
+    if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
+        SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(elapsedRealtime.timeUncertaintyNs));
+    }
+    translateGnssClock(object, data.clock);
+}
+
 template<class T>
 jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env,
         const T* measurements,