Merge "Add basebandCn0DbHz to GnssStatus"
diff --git a/api/current.txt b/api/current.txt
index c3b8d26..d6a49e0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23063,6 +23063,7 @@
 
   public final class GnssStatus {
     method @FloatRange(from=0, to=360) public float getAzimuthDegrees(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public float getBasebandCn0DbHz(@IntRange(from=0) int);
     method @FloatRange(from=0) public float getCarrierFrequencyHz(@IntRange(from=0) int);
     method @FloatRange(from=0, to=63) public float getCn0DbHz(@IntRange(from=0) int);
     method public int getConstellationType(@IntRange(from=0) int);
@@ -23070,6 +23071,7 @@
     method @IntRange(from=0) public int getSatelliteCount();
     method @IntRange(from=1, to=200) public int getSvid(@IntRange(from=0) int);
     method public boolean hasAlmanacData(@IntRange(from=0) int);
+    method public boolean hasBasebandCn0DbHz(@IntRange(from=0) int);
     method public boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
     method public boolean hasEphemerisData(@IntRange(from=0) int);
     method public boolean usedInFix(@IntRange(from=0) int);
@@ -23085,7 +23087,7 @@
 
   public static final class GnssStatus.Builder {
     ctor public GnssStatus.Builder();
-    method @NonNull public android.location.GnssStatus.Builder addSatellite(int, @IntRange(from=1, to=200) int, @FloatRange(from=0, to=63) float, @FloatRange(from=0xffffffa6, to=90) float, @FloatRange(from=0, to=360) float, boolean, boolean, boolean, boolean, @FloatRange(from=0) float);
+    method @NonNull public android.location.GnssStatus.Builder addSatellite(int, @IntRange(from=1, to=200) int, @FloatRange(from=0, to=63) float, @FloatRange(from=0xffffffa6, to=90) float, @FloatRange(from=0, to=360) float, boolean, boolean, boolean, boolean, @FloatRange(from=0) float, boolean, @FloatRange(from=0, to=63) float);
     method @NonNull public android.location.GnssStatus build();
     method @NonNull public android.location.GnssStatus.Builder clearSatellites();
   }
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index 2f1eeda..89a3bc0 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -34,7 +34,7 @@
  */
 public final class GnssStatus {
 
-    // these must match the definitions in gps.h
+    // These must match the definitions in GNSS HAL.
     //
     // Note: these constants are also duplicated in GnssStatusCompat.java in the androidx support
     // library. if adding a constellation, please update that file as well.
@@ -63,9 +63,10 @@
     private static final int SVID_FLAGS_HAS_ALMANAC_DATA = (1 << 1);
     private static final int SVID_FLAGS_USED_IN_FIX = (1 << 2);
     private static final int SVID_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3);
+    private static final int SVID_FLAGS_HAS_BASEBAND_CN0 = (1 << 4);
 
-    private static final int SVID_SHIFT_WIDTH = 8;
-    private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
+    private static final int SVID_SHIFT_WIDTH = 12;
+    private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 8;
     private static final int CONSTELLATION_TYPE_MASK = 0xf;
 
     /**
@@ -123,9 +124,10 @@
      */
     @NonNull
     public static GnssStatus wrap(int svCount, int[] svidWithFlags, float[] cn0DbHzs,
-            float[] elevations, float[] azimuths, float[] carrierFrequencies) {
+            float[] elevations, float[] azimuths, float[] carrierFrequencies,
+            float[] basebandCn0DbHzs) {
         return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths,
-                carrierFrequencies);
+                carrierFrequencies, basebandCn0DbHzs);
     }
 
     private final int mSvCount;
@@ -134,15 +136,17 @@
     private final float[] mElevations;
     private final float[] mAzimuths;
     private final float[] mCarrierFrequencies;
+    private final float[] mBasebandCn0DbHzs;
 
     private GnssStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations,
-            float[] azimuths, float[] carrierFrequencies) {
+            float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs) {
         mSvCount = svCount;
         mSvidWithFlags = svidWithFlags;
         mCn0DbHzs = cn0DbHzs;
         mElevations = elevations;
         mAzimuths = azimuths;
         mCarrierFrequencies = carrierFrequencies;
+        mBasebandCn0DbHzs = basebandCn0DbHzs;
     }
 
     /**
@@ -284,6 +288,26 @@
     }
 
     /**
+     * Reports whether a valid {@link #getBasebandCn0DbHz(int satelliteIndex)} is available.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    public boolean hasBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_BASEBAND_CN0) != 0;
+    }
+
+    /**
+     * Retrieves the baseband carrier-to-noise density of the satellite at the specified index in
+     * dB-Hz.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @FloatRange(from = 0, to = 63)
+    public float getBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
+        return mBasebandCn0DbHzs[satelliteIndex];
+    }
+
+    /**
      * Returns the string representation of a constellation type.
      *
      * @param constellationType the constellation type.
@@ -334,6 +358,8 @@
          * @param usedInFix whether the satellite was used in the most recent location fix
          * @param hasCarrierFrequency whether carrier frequency data is available
          * @param carrierFrequency satellite carrier frequency in Hz
+         * @param hasBasebandCn0DbHz whether baseband carrier-to-noise density is available
+         * @param basebandCn0DbHz baseband carrier-to-noise density in dB-Hz
          */
         @NonNull
         public Builder addSatellite(@ConstellationType int constellationType,
@@ -345,9 +371,12 @@
                 boolean hasAlmanac,
                 boolean usedInFix,
                 boolean hasCarrierFrequency,
-                @FloatRange(from = 0) float carrierFrequency) {
+                @FloatRange(from = 0) float carrierFrequency,
+                boolean hasBasebandCn0DbHz,
+                @FloatRange(from = 0, to = 63) float basebandCn0DbHz) {
             mSatellites.add(new GnssSvInfo(constellationType, svid, cn0DbHz, elevation, azimuth,
-                    hasEphemeris, hasAlmanac, usedInFix, hasCarrierFrequency, carrierFrequency));
+                    hasEphemeris, hasAlmanac, usedInFix, hasCarrierFrequency, carrierFrequency,
+                    hasBasebandCn0DbHz, basebandCn0DbHz));
             return this;
         }
 
@@ -371,6 +400,7 @@
             float[] elevations = new float[svCount];
             float[] azimuths = new float[svCount];
             float[] carrierFrequencies = new float[svCount];
+            float[] basebandCn0DbHzs = new float[svCount];
 
             for (int i = 0; i < svidWithFlags.length; i++) {
                 svidWithFlags[i] = mSatellites.get(i).mSvidWithFlags;
@@ -387,9 +417,12 @@
             for (int i = 0; i < carrierFrequencies.length; i++) {
                 carrierFrequencies[i] = mSatellites.get(i).mCarrierFrequency;
             }
+            for (int i = 0; i < basebandCn0DbHzs.length; i++) {
+                basebandCn0DbHzs[i] = mSatellites.get(i).mBasebandCn0DbHz;
+            }
 
             return wrap(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths,
-                    carrierFrequencies);
+                    carrierFrequencies, basebandCn0DbHzs);
         }
     }
 
@@ -400,21 +433,25 @@
         private final float mElevation;
         private final float mAzimuth;
         private final float mCarrierFrequency;
+        private final float mBasebandCn0DbHz;
 
         private GnssSvInfo(int constellationType, int svid, float cn0DbHz,
                 float elevation, float azimuth, boolean hasEphemeris, boolean hasAlmanac,
-                boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency) {
+                boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency,
+                boolean hasBasebandCn0DbHz, float basebandCn0DbHz) {
             mSvidWithFlags = (svid << SVID_SHIFT_WIDTH)
                     | ((constellationType & CONSTELLATION_TYPE_MASK)
                     << CONSTELLATION_TYPE_SHIFT_WIDTH)
                     | (hasEphemeris ? SVID_FLAGS_HAS_EPHEMERIS_DATA : SVID_FLAGS_NONE)
                     | (hasAlmanac ? SVID_FLAGS_HAS_ALMANAC_DATA : SVID_FLAGS_NONE)
                     | (usedInFix ? SVID_FLAGS_USED_IN_FIX : SVID_FLAGS_NONE)
-                    | (hasCarrierFrequency ? SVID_FLAGS_HAS_CARRIER_FREQUENCY : SVID_FLAGS_NONE);
+                    | (hasCarrierFrequency ? SVID_FLAGS_HAS_CARRIER_FREQUENCY : SVID_FLAGS_NONE)
+                    | (hasBasebandCn0DbHz ? SVID_FLAGS_HAS_BASEBAND_CN0 : SVID_FLAGS_NONE);
             mCn0DbHz = cn0DbHz;
             mElevation = elevation;
             mAzimuth = azimuth;
             mCarrierFrequency = carrierFrequency;
+            mBasebandCn0DbHz = basebandCn0DbHz;
         }
     }
 }
diff --git a/location/java/android/location/IGnssStatusListener.aidl b/location/java/android/location/IGnssStatusListener.aidl
index d824cb1..1931a00 100644
--- a/location/java/android/location/IGnssStatusListener.aidl
+++ b/location/java/android/location/IGnssStatusListener.aidl
@@ -28,6 +28,6 @@
     void onFirstFix(int ttff);
     void onSvStatusChanged(int svCount, in int[] svidWithFlags, in float[] cn0s,
             in float[] elevations, in float[] azimuths,
-            in float[] carrierFreqs);
+            in float[] carrierFreqs, in float[] basebandCn0s);
     void onNmeaReceived(long timestamp, String nmea);
 }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 75e1cd4..c004172 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -2818,9 +2818,10 @@
 
             @Override
             public void onSvStatusChanged(int svCount, int[] svidWithFlags, float[] cn0s,
-                    float[] elevations, float[] azimuths, float[] carrierFreqs) {
+                    float[] elevations, float[] azimuths, float[] carrierFreqs,
+                    float[] basebandCn0s) {
                 GnssStatus localStatus = GnssStatus.wrap(svCount, svidWithFlags, cn0s,
-                        elevations, azimuths, carrierFreqs);
+                        elevations, azimuths, carrierFreqs, basebandCn0s);
                 mGnssStatus = localStatus;
                 execute((callback) -> callback.onSatelliteStatusChanged(localStatus));
             }
diff --git a/location/tests/locationtests/src/android/location/GnssStatusTest.java b/location/tests/locationtests/src/android/location/GnssStatusTest.java
deleted file mode 100644
index 79ea0d6..0000000
--- a/location/tests/locationtests/src/android/location/GnssStatusTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.location;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.List;
-import junit.framework.TestCase;
-
-/**
- * Unit tests for {@link GnssStatus}.
- */
-@SmallTest
-public class GnssStatusTest extends TestCase {
-
-  private static final String TAG = GnssStatusTest.class.getSimpleName();
-  public void setUp() throws Exception {
-    super.setUp();
-  }
-
-  /*
-   * Create {@link GnssStatus} with default value, verify whether its fields are set correctly.
-   *
-   */
-  public void testEmptyGnssStatus() throws Exception {
-    Log.i(TAG, "testEmptyGnssStatus");
-    List<SatelliteInfo> svInfos = new ArrayList<>();
-    GnssStatus gnssStatus = createGnssStatus(svInfos);
-    verifyGnssStatus(svInfos, gnssStatus);
-  }
-
-  /*
-   * Create {@link GnssStatus} with only one satellite info, verify whether its fields are set
-   * correctly.
-   */
-  public void testOneSatelliteGnssStatus() throws Exception {
-    Log.i(TAG, "testOneSatelliteGnssStatus");
-    List<SatelliteInfo> svInfos = new ArrayList<>();
-    SatelliteInfo svInfo =
-        new SatelliteInfo(100,1, true, true, true, true, 100f, 20.3f, 45.5f, 100.23f);
-    svInfos.add(svInfo);
-    GnssStatus gnssStatus = createGnssStatus(svInfos);
-    verifyGnssStatus(svInfos, gnssStatus);
-  }
-
-  /*
-   * Create {@link GnssStatus} with multiple satellite info, verify whether its fields are set
-   * correctly.
-   */
-  public void testMultipleSatellitesGnssStatus() throws Exception {
-    Log.i(TAG, "testMultipleSatellitesGnssStatus");
-    List<SatelliteInfo> svInfos = new ArrayList<>();
-    SatelliteInfo svInfo1 =
-        new SatelliteInfo(20, 1,true, true, true, true, 10.1f, 20.3f, 45.5f, 111.23f);
-    SatelliteInfo svInfo2 =
-        new SatelliteInfo(50, 2, true, false, true, false, 20.2f, 21.3f, 46.5f, 222.23f);
-    SatelliteInfo svInfo3 =
-        new SatelliteInfo(192, 3, false, true, false, true, 30.3f, 22.3f, 47.5f, 333.23f);
-    SatelliteInfo svInfo4 =
-        new SatelliteInfo(250, 4, false, false, false, false, 40.4f, 23.3f, 48.5f, 444.23f);
-    svInfos.add(svInfo1);
-    svInfos.add(svInfo2);
-    svInfos.add(svInfo3);
-    svInfos.add(svInfo4);
-    GnssStatus gnssStatus = createGnssStatus(svInfos);
-    verifyGnssStatus(svInfos, gnssStatus);
-  }
-
-  private void verifyGnssStatus(List<SatelliteInfo> svInfos, GnssStatus gnssStatus) {
-    Log.i(TAG, String.format("Verifing {0} satellites info.",svInfos.size()));
-    assertEquals(TAG + "::SatelliteCount", svInfos.size(),
-        gnssStatus.getSatelliteCount());
-    for (int i = 0; i< svInfos.size(); i++) {
-      SatelliteInfo svInfo = svInfos.get(i);
-      assertEquals(TAG + "::Svid", svInfo.mSvid, gnssStatus.getSvid(i));
-      assertEquals(TAG + "::ConstellationType", svInfo.mConstellationType,
-          gnssStatus.getConstellationType(i));
-      assertEquals(TAG + "::Cn0DbHz", svInfo.mCn0DbHz, gnssStatus.getCn0DbHz(i));
-      assertEquals(TAG + "::Elevation", svInfo.mElevation,
-          gnssStatus.getElevationDegrees(i));
-      assertEquals(TAG + "::Azimuth", svInfo.mAzimuth, gnssStatus.getAzimuthDegrees(i));
-      assertEquals(TAG + "::CarrierFrequencyHz", svInfo.mCarrierFrequency,
-          gnssStatus.getCarrierFrequencyHz(i));
-      assertEquals(TAG + "::hasEphemerisData", svInfo.mHasEphemris,
-          gnssStatus.hasEphemerisData(i));
-      assertEquals(TAG + "::HasAlmanacData", svInfo.mHasAlmanac,
-          gnssStatus.hasAlmanacData(i));
-      assertEquals(TAG + "::UsedInFix", svInfo.mUsedInFix, gnssStatus.usedInFix(i));
-      assertEquals(TAG + "::HasCarrierFrequencyHz", svInfo.mHasCarriesFrequency,
-          gnssStatus.hasCarrierFrequencyHz(i));
-    }
-  }
-
-  private static GnssStatus createGnssStatus(List<SatelliteInfo> svInfos) throws Exception {
-    Class<?> intClass = Integer.TYPE;
-    Class<?> floatArrayClass = Class.forName("[F");
-    Class<?> intArrayClass = Class.forName("[I");
-    Class[] cArg = new Class[6];
-    cArg[0] = intClass;
-    cArg[1] = intArrayClass;
-    cArg[2] = floatArrayClass;
-    cArg[3] = floatArrayClass;
-    cArg[4] = floatArrayClass;
-    cArg[5] = floatArrayClass;
-    Constructor<GnssStatus>  ctor = GnssStatus.class.getDeclaredConstructor(cArg);
-    ctor.setAccessible(true);
-    return ctor.newInstance(svInfos.size(),
-        SatelliteInfo.getSvidWithFlagsArray(svInfos),
-        SatelliteInfo.getCn0sArray(svInfos),
-        SatelliteInfo.getElevationsArray(svInfos),
-        SatelliteInfo.getAzimuthsArray(svInfos),
-        SatelliteInfo.getCarrierFrequencyArray(svInfos));
-  }
-}
diff --git a/location/tests/locationtests/src/android/location/SatelliteInfo.java b/location/tests/locationtests/src/android/location/SatelliteInfo.java
deleted file mode 100644
index b6453ef..0000000
--- a/location/tests/locationtests/src/android/location/SatelliteInfo.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.location;
-
-import java.util.List;
-
-/*
- * Helper class to store single Satellite info, only used it in the unit test.
- */
-public class SatelliteInfo {
-  private static final int SVID_MAX_BIT_INDEX = 32;
-  private static final int SVID_SHIFT_WIDTH = 8;
-  private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
-
-  // Index for the bits in mSvidWithFlag
-  private static final int GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA_BIT_INDEX = 0;
-  private static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA_BIT_INDEX = 1;
-  private static final int GNSS_SV_FLAGS_USED_IN_FIX_BIT_INDEX = 2;
-  private static final int GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY_BIT_INDEX = 3;
-  public int mSvid;
-  public int mSvidWithFlag;
-  public float mCn0DbHz;
-  public float mElevation;
-  public float mAzimuth;
-  public float mCarrierFrequency;
-
-  /*
-   * Flag fields, it stores the same information as svidWithFlag, but in different format, easy for
-   * the unit test.
-   */
-  public int mConstellationType;
-  public boolean mHasEphemris;
-  public boolean mHasAlmanac;
-  public boolean mUsedInFix;
-  public boolean mHasCarriesFrequency;
-
-  public SatelliteInfo(int svid, int constellationType, boolean hasEphemris, boolean hasAlmanac,
-      boolean usedInFix, boolean hasCarriesFrequency, float cn0, float elevation, float azimuth,
-      float carrierFrequency) {
-    mSvidWithFlag =
-        setRange(mSvidWithFlag, constellationType, CONSTELLATION_TYPE_SHIFT_WIDTH, SVID_SHIFT_WIDTH);
-    mSvidWithFlag = setRange(mSvidWithFlag, svid, SVID_SHIFT_WIDTH, SVID_MAX_BIT_INDEX);
-    mSvidWithFlag = setBit(mSvidWithFlag, hasEphemris, GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA_BIT_INDEX);
-    mSvidWithFlag = setBit(mSvidWithFlag, hasAlmanac, GNSS_SV_FLAGS_HAS_ALMANAC_DATA_BIT_INDEX);
-    mSvidWithFlag = setBit(mSvidWithFlag, usedInFix, GNSS_SV_FLAGS_USED_IN_FIX_BIT_INDEX);
-    mSvidWithFlag =
-        setBit(mSvidWithFlag, hasCarriesFrequency, GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY_BIT_INDEX);
-    this.mSvid = svid;
-    this.mConstellationType = constellationType;
-    this.mCn0DbHz = cn0;
-    this.mElevation = elevation;
-    this.mAzimuth = azimuth;
-    this.mCarrierFrequency = carrierFrequency;
-    this.mHasEphemris = hasEphemris;
-    this.mHasAlmanac = hasAlmanac;
-    this.mUsedInFix = usedInFix;
-    this.mHasCarriesFrequency = hasCarriesFrequency;
-  }
-
-  /*
-   * Gernerate svidWithFlags array from svInfos
-   */
-  public static int[] getSvidWithFlagsArray(List<SatelliteInfo> svInfos) {
-    int[] svidWithFlags = new int[svInfos.size()];
-    for (int i = 0; i< svInfos.size(); i++) {
-      svidWithFlags[i] = svInfos.get(i).mSvidWithFlag;
-    }
-    return svidWithFlags;
-  }
-
-  /*
-   * Gernerate cn0s array from svInfos
-   */
-  public static float[] getCn0sArray(List<SatelliteInfo> svInfos) {
-    float[] cn0s = new float[svInfos.size()];
-    for (int i = 0; i< svInfos.size(); i++) {
-      cn0s[i] = svInfos.get(i).mCn0DbHz;
-    }
-    return cn0s;
-  }
-
-  /*
-   * Gernerate elevations array from svInfos
-   */
-  public static float[] getElevationsArray(List<SatelliteInfo> svInfos) {
-    float[] elevations = new float[svInfos.size()];
-    for (int i = 0; i< svInfos.size(); i++) {
-      elevations[i] = svInfos.get(i).mElevation;
-    }
-    return elevations;
-  }
-
-  /*
-   * Gernerate azimuths array from svInfos
-   */
-  public static float[] getAzimuthsArray(List<SatelliteInfo> svInfos) {
-    float[] azimuths = new float[svInfos.size()];
-    for (int i = 0; i< svInfos.size(); i++) {
-      azimuths[i] = svInfos.get(i).mAzimuth;
-    }
-    return azimuths;
-  }
-
-  /*
-   * Gernerate carrierFrequency array from svInfos
-   */
-  public static float[] getCarrierFrequencyArray(List<SatelliteInfo> svInfos) {
-    float[] carrierFrequencies = new float[svInfos.size()];
-    for (int i = 0; i< svInfos.size(); i++) {
-      carrierFrequencies[i] = svInfos.get(i).mCarrierFrequency;
-    }
-    return carrierFrequencies;
-  }
-
-  private int setBit(int targetValue, boolean value, int index) {
-    if (value) {
-      targetValue = targetValue | (1 << index);
-    } else {
-      targetValue = targetValue & ~(1 << index);
-    }
-    return targetValue;
-  }
-
-  /*
-   * Set the bit in the range [fromIndex, toIndex), index start from the lowest bit.
-   * value -> 1 1 0 1 1 0 1 0
-   * index -> 7 6 5 4 3 2 1 0
-   * This function will set the bit in the range to the lowest X bits of the value.
-   */
-  private int setRange(int targetValue, int value, int fromIndex, int toIndex) {
-    int rangeLen = toIndex - fromIndex;
-    int valueMask = (1 << rangeLen) -1;
-    value &= valueMask;
-    value = value << fromIndex;
-    valueMask = valueMask << fromIndex;
-    targetValue &= (~valueMask);
-    targetValue |= value;
-    return targetValue;
-  }
-
-}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index c84745e..557ba54 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1447,11 +1447,13 @@
         private float[] mSvElevations;
         private float[] mSvAzimuths;
         private float[] mSvCarrierFreqs;
+        private float[] mBasebandCn0s;
     }
 
     @NativeEntryPoint
     private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
-            float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
+            float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs,
+            float[] basebandCn0s) {
         SvStatusInfo svStatusInfo = new SvStatusInfo();
         svStatusInfo.mSvCount = svCount;
         svStatusInfo.mSvidWithFlags = svidWithFlags;
@@ -1459,6 +1461,7 @@
         svStatusInfo.mSvElevations = svElevations;
         svStatusInfo.mSvAzimuths = svAzimuths;
         svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
+        svStatusInfo.mBasebandCn0s = basebandCn0s;
 
         sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
     }
@@ -1470,7 +1473,8 @@
                 info.mCn0s,
                 info.mSvElevations,
                 info.mSvAzimuths,
-                info.mSvCarrierFreqs);
+                info.mSvCarrierFreqs,
+                info.mBasebandCn0s);
 
         // Log CN0 as part of GNSS metrics
         mGnssMetrics.logCn0(info.mCn0s, info.mSvCount, info.mSvCarrierFreqs);
@@ -1485,7 +1489,8 @@
                 info.mCn0s,
                 info.mSvElevations,
                 info.mSvAzimuths,
-                info.mSvCarrierFreqs);
+                info.mSvCarrierFreqs,
+                info.mBasebandCn0s);
         int usedInFixCount = 0;
         int maxCn0 = 0;
         int meanCn0 = 0;
@@ -1501,13 +1506,15 @@
             if (VERBOSE) {
                 Log.v(TAG, "svid: " + gnssStatus.getSvid(i)
                         + " cn0: " + gnssStatus.getCn0DbHz(i)
+                        + " basebandCn0: " + gnssStatus.getBasebandCn0DbHz(i)
                         + " elev: " + gnssStatus.getElevationDegrees(i)
                         + " azimuth: " + gnssStatus.getAzimuthDegrees(i)
                         + " carrier frequency: " + gnssStatus.getCn0DbHz(i)
                         + (gnssStatus.hasEphemerisData(i) ? " E" : "  ")
                         + (gnssStatus.hasAlmanacData(i) ? " A" : "  ")
                         + (gnssStatus.usedInFix(i) ? "U" : "")
-                        + (gnssStatus.hasCarrierFrequencyHz(i) ? "F" : ""));
+                        + (gnssStatus.hasCarrierFrequencyHz(i) ? "F" : "")
+                        + (gnssStatus.hasBasebandCn0DbHz(i) ? "B" : ""));
             }
         }
         if (usedInFixCount > 0) {
diff --git a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
index d67d0c5..eaf63c8 100644
--- a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
+++ b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
@@ -71,7 +71,8 @@
             final float[] cn0s,
             final float[] elevations,
             final float[] azimuths,
-            final float[] carrierFreqs) {
+            final float[] carrierFreqs,
+            final float[] basebandCn0s) {
         foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {
             if (!hasPermission(mContext, callerIdentity)) {
                 logPermissionDisabledEventNotReported(TAG, callerIdentity.mPackageName,
@@ -79,7 +80,7 @@
                 return;
             }
             listener.onSvStatusChanged(svCount, prnWithFlags, cn0s, elevations, azimuths,
-                    carrierFreqs);
+                    carrierFreqs, basebandCn0s);
         });
     }
 
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 3bc2838..a0f5628 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -704,20 +704,22 @@
     jfloatArray elevArray = env->NewFloatArray(listSize);
     jfloatArray azimArray = env->NewFloatArray(listSize);
     jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
+    jfloatArray basebandCn0Array = env->NewFloatArray(listSize);
 
     jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
     jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
     jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
     jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
     jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
+    jfloat* basebandCn0s = env->GetFloatArrayElements(basebandCn0Array, 0);
 
     /*
      * Read GNSS SV info.
      */
     for (size_t i = 0; i < listSize; ++i) {
         enum ShiftWidth: uint8_t {
-            SVID_SHIFT_WIDTH = 8,
-            CONSTELLATION_TYPE_SHIFT_WIDTH = 4
+            SVID_SHIFT_WIDTH = 12,
+            CONSTELLATION_TYPE_SHIFT_WIDTH = 8
         };
 
         const IGnssCallback_V1_0::GnssSvInfo& info = getGnssSvInfoOfIndex(svStatus, i);
@@ -728,6 +730,8 @@
         elev[i] = info.elevationDegrees;
         azim[i] = info.azimuthDegrees;
         carrierFreq[i] = info.carrierFrequencyHz;
+        // TODO(b/144850155): fill svidWithFlags with hasBasebandCn0DbHz based on HAL versions
+        basebandCn0s[i] = 0.0;
     }
 
     env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
@@ -735,10 +739,11 @@
     env->ReleaseFloatArrayElements(elevArray, elev, 0);
     env->ReleaseFloatArrayElements(azimArray, azim, 0);
     env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
+    env->ReleaseFloatArrayElements(basebandCn0Array, basebandCn0s, 0);
 
     env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
             static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
-            carrierFreqArray);
+            carrierFreqArray, basebandCn0Array);
 
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
     return Void();
@@ -1545,7 +1550,7 @@
     method_reportLocation = env->GetMethodID(clazz, "reportLocation",
             "(ZLandroid/location/Location;)V");
     method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
-    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
+    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V");
     method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
     method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
     method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V");