Merge "Average of top 4 CNO" into oc-dr1-dev
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index f5f1024..833376c 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -21,6 +21,8 @@
 import android.util.Base64;
 import android.util.TimeUtils;
 
+import java.util.Arrays;
+
 import com.android.internal.location.nano.GnssLogsProto.GnssLog;
 
 /**
@@ -40,6 +42,7 @@
     locationFailureStatistics = new Statistics();
     timeToFirstFixSecStatistics = new Statistics();
     positionAccuracyMeterStatistics = new Statistics();
+    topFourAverageCn0Statistics = new Statistics();
     reset();
   }
 
@@ -95,6 +98,27 @@
     return;
   }
 
+  /*
+  * Logs CN0 when at least 4 SVs are available
+  *
+  */
+  public void logCn0(float[] cn0s, int numSv) {
+    if (numSv < 4) {
+      return;
+    }
+    float[] cn0Array = Arrays.copyOf(cn0s, numSv);
+    Arrays.sort(cn0Array);
+    if (cn0Array[numSv - 4] > 0.0) {
+      double top4AvgCn0 = 0.0;
+      for (int i = numSv - 4; i < numSv; i++) {
+        top4AvgCn0 += (double) cn0Array[i];
+      }
+      top4AvgCn0 /= 4;
+      topFourAverageCn0Statistics.addItem(top4AvgCn0);
+    }
+    return;
+  }
+
   /**
    * Dumps GNSS metrics as a proto string
    * @return
@@ -117,6 +141,12 @@
       msg.standardDeviationPositionAccuracyMeters
           = (int) positionAccuracyMeterStatistics.getStandardDeviation();
     }
+    if (topFourAverageCn0Statistics.getCount() > 0) {
+      msg.numTopFourAverageCn0Processed = topFourAverageCn0Statistics.getCount();
+      msg.meanTopFourAverageCn0DbHz = topFourAverageCn0Statistics.getMean();
+      msg.standardDeviationTopFourAverageCn0DbHz
+          = topFourAverageCn0Statistics.getStandardDeviation();
+    }
     String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT);
     reset();
     return s;
@@ -155,6 +185,14 @@
       s.append("  Position accuracy standard deviation (m): ").append(
           positionAccuracyMeterStatistics.getStandardDeviation()).append("\n");
     }
+    s.append("  Number of CN0 reports: ").append(
+        topFourAverageCn0Statistics.getCount()).append("\n");
+    if (topFourAverageCn0Statistics.getCount() > 0) {
+      s.append("  Top 4 Avg CN0 mean (dB-Hz): ").append(
+          topFourAverageCn0Statistics.getMean()).append("\n");
+      s.append("  Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
+          topFourAverageCn0Statistics.getStandardDeviation()).append("\n");
+    }
     s.append("GNSS_KPI_END").append("\n");
     return s.toString();
   }
@@ -211,6 +249,9 @@
   /** Position accuracy statistics */
   private Statistics positionAccuracyMeterStatistics;
 
+  /** Top 4 average CN0 statistics */
+  private Statistics topFourAverageCn0Statistics;
+
   /**
    * Resets GNSS metrics
    */
@@ -221,6 +262,7 @@
     locationFailureStatistics.reset();
     timeToFirstFixSecStatistics.reset();
     positionAccuracyMeterStatistics.reset();
+    topFourAverageCn0Statistics.reset();
     return;
   }
 }
\ No newline at end of file
diff --git a/proto/src/gnss.proto b/proto/src/gnss.proto
index 33a5584..c54ddad 100644
--- a/proto/src/gnss.proto
+++ b/proto/src/gnss.proto
@@ -33,4 +33,13 @@
 
   // Standard deviation of position accuracy (in meters)
   optional int32 standard_deviation_position_accuracy_meters = 8;
+
+  // Number of top 4 average CN0 processed
+  optional int32 num_top_four_average_cn0_processed = 9;
+
+  // Mean of top 4 average CN0 (dB-Hz)
+  optional double mean_top_four_average_cn0_db_hz = 10;
+
+  // Standard deviation of top 4 average CN0 (dB-Hz)
+  optional double standard_deviation_top_four_average_cn0_db_hz = 11;
 }
\ 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 4511aa9..601dd94 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1651,6 +1651,9 @@
                 mSvAzimuths,
                 mSvCarrierFreqs);
 
+        // Log CN0 as part of GNSS metrics
+        mGnssMetrics.logCn0(mCn0s, svCount);
+
         if (VERBOSE) {
             Log.v(TAG, "SV count: " + svCount);
         }