Merge "Mapping up/down of legacy Gps vs. Gnss Status" into nyc-dev
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index e834c30..e68821b 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -146,13 +146,11 @@
      * <ul>
      * <li>GPS: 1-32</li>
      * <li>SBAS: 120-151, 183-192</li>
-     * <li>GLONASS:
+     * <li>GLONASS: One of: OSN, or FCN+100
      * <ul>
-     *   <li>The least significant 8 bits, signed, are the orbital slot number (OSN) in the range
-     *   from 1-24, if known, or -127 if unknown</li>
-     *   <li>The next least signficant 8 bits, signed, are the frequency channel number (FCN) in the
-     *   range from -7 to +6, if known, and -127, if unknown</li>
-     *   <li>At least one of the two (FCN &amp; OSN) shall be set to a known value</li>
+     *   <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li>
+     *   <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100.
+     *   i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li>
      * </ul></li>
      * <li>QZSS: 193-200</li>
      * <li>Galileo: 1-36</li>
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 038247b..5561b22 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -32,6 +32,8 @@
 @Deprecated
 public final class GpsStatus {
     private static final int NUM_SATELLITES = 255;
+    private static final int GLONASS_SVID_OFFSET = 64;
+    private static final int BEIDOU_SVID_OFFSET = 200;
 
     /* These package private values are modified by the LocationManager class */
     private int mTimeToFirstFix;
@@ -153,11 +155,22 @@
             final int constellationType =
                     (svidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH)
                     & GnssStatus.CONSTELLATION_TYPE_MASK;
-            // Skip all non-GPS satellites.
-            if (constellationType != GnssStatus.CONSTELLATION_GPS) {
+            int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH;
+            // Other satellites passed through these APIs before GnssSvStatus was availble.
+            // GPS, SBAS & QZSS can pass through at their nominally
+            // assigned prn number (as long as it fits in the valid 0-255 range below.)
+            // Glonass, and Beidou are passed through with the defacto standard offsets
+            // Other future constellation reporting (e.g. Galileo) needs to use
+            // GnssSvStatus on (N level) HAL & Java layers.
+            if (constellationType == GnssStatus.CONSTELLATION_GLONASS) {
+                prn += GLONASS_SVID_OFFSET;
+            } else if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) {
+                prn += BEIDOU_SVID_OFFSET;
+            } else if ((constellationType != GnssStatus.CONSTELLATION_GPS) &&
+                    (constellationType != GnssStatus.CONSTELLATION_QZSS) &&
+                    (constellationType != GnssStatus.CONSTELLATION_SBAS)) {
                 continue;
             }
-            int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH;
             if (prn > 0 && prn <= NUM_SATELLITES) {
                 GpsSatellite satellite = mSatellites.get(prn);
                 if (satellite == null) {
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index c5c90e0..e29452a 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -72,6 +72,18 @@
 #define GPS_MAX_SATELLITE_COUNT 32
 #define GNSS_MAX_SATELLITE_COUNT 64
 
+// Let these through, with ID remapped by offset
+#define GLONASS_SVID_OFFSET 64
+#define GLONASS_SVID_COUNT 24
+#define BEIDOU_SVID_OFFSET 200
+#define BEIDOU_SVID_COUNT 35
+
+// Let these through, with no ID remapping
+#define SBAS_SVID_MIN 120
+#define SBAS_SVID_MAX 151
+#define QZSS_SVID_MIN 193
+#define QZSS_SVID_MAX 200
+
 #define SVID_SHIFT_WIDTH 7
 #define CONSTELLATION_TYPE_SHIFT_WIDTH 3
 
@@ -134,8 +146,21 @@
     for (size_t i = 0; i < sGnssSvListSize; i++) {
         GnssSvInfo& info = sGnssSvList[i];
         info.svid = sv_status->sv_list[i].prn;
+        // Defacto mapping from the overused API that was designed for GPS-only
         if (info.svid >=1 && info.svid <= 32) {
             info.constellation = GNSS_CONSTELLATION_GPS;
+        } else if (info.svid > GLONASS_SVID_OFFSET &&
+                   info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) {
+            info.constellation = GNSS_CONSTELLATION_GLONASS;
+            info.svid -= GLONASS_SVID_OFFSET;
+        } else if (info.svid > BEIDOU_SVID_OFFSET &&
+                   info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) {
+            info.constellation = GNSS_CONSTELLATION_BEIDOU;
+            info.svid -= BEIDOU_SVID_OFFSET;
+        } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) {
+            info.constellation = GNSS_CONSTELLATION_SBAS;
+        } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) {
+            info.constellation = GNSS_CONSTELLATION_QZSS;
         } else {
             ALOGD("Unknown constellation type with Svid = %d.", info.svid);
             info.constellation = GNSS_CONSTELLATION_UNKNOWN;
@@ -144,7 +169,8 @@
         info.elevation = sv_status->sv_list[i].elevation;
         info.azimuth = sv_status->sv_list[i].azimuth;
         info.flags = GNSS_SV_FLAGS_NONE;
-        if (info.svid > 0 && info.svid <= 32) {
+        // Only GPS info is valid for these fields, as these masks are just 32 bits, by GPS prn
+        if (info.constellation == GNSS_CONSTELLATION_GPS) {
             int32_t this_svid_mask = (1 << (info.svid - 1));
             if ((ephemeris_mask & this_svid_mask) != 0) {
                 info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA;