GPS Signal Quality added to BatteryStats
- GPS Signal Quality (Top four average CN0) added to Batterystats (Aggregate + Historian) - Added API to obtain Gps battery stats for power drain diagnostics. BUG:38354997 Test: Manual (https://docs.google.com/document/d/1X6g7HBZ80GA3KuqEYyQtD0WQRUnXN8nbCpf0G1HvzqY/edit?usp=sharing) Change-Id: Ic23bfa758977bf0677f368f617b0c28196d2d0c1
This commit is contained in:
@@ -19,10 +19,12 @@ package com.android.internal.location.gnssmetrics;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.location.nano.GnssLogsProto.GnssLog;
|
||||
|
||||
/**
|
||||
@@ -31,14 +33,29 @@ import com.android.internal.location.nano.GnssLogsProto.GnssLog;
|
||||
*/
|
||||
public class GnssMetrics {
|
||||
|
||||
private static final String TAG = GnssMetrics.class.getSimpleName();
|
||||
|
||||
/* Constant which indicates GPS signal quality is poor */
|
||||
public static final int GPS_SIGNAL_QUALITY_POOR = 0;
|
||||
|
||||
/* Constant which indicates GPS signal quality is good */
|
||||
public static final int GPS_SIGNAL_QUALITY_GOOD = 1;
|
||||
|
||||
/* Number of GPS signal quality levels */
|
||||
public static final int NUM_GPS_SIGNAL_QUALITY_LEVELS = GPS_SIGNAL_QUALITY_GOOD + 1;
|
||||
|
||||
/** Default time between location fixes (in millisecs) */
|
||||
private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000;
|
||||
|
||||
/* The time since boot when logging started */
|
||||
private String logStartInElapsedRealTime;
|
||||
|
||||
/* GNSS power metrics */
|
||||
private GnssPowerMetrics mGnssPowerMetrics;
|
||||
|
||||
/** Constructor */
|
||||
public GnssMetrics() {
|
||||
public GnssMetrics(IBatteryStats stats) {
|
||||
mGnssPowerMetrics = new GnssPowerMetrics(stats);
|
||||
locationFailureStatistics = new Statistics();
|
||||
timeToFirstFixSecStatistics = new Statistics();
|
||||
positionAccuracyMeterStatistics = new Statistics();
|
||||
@@ -103,11 +120,18 @@ public class GnssMetrics {
|
||||
*
|
||||
*/
|
||||
public void logCn0(float[] cn0s, int numSv) {
|
||||
if (numSv < 4) {
|
||||
if (numSv == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < numSv) {
|
||||
if (numSv == 0) {
|
||||
mGnssPowerMetrics.reportSignalQuality(null, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
float[] cn0Array = Arrays.copyOf(cn0s, numSv);
|
||||
Arrays.sort(cn0Array);
|
||||
mGnssPowerMetrics.reportSignalQuality(cn0Array, numSv);
|
||||
if (numSv < 4) {
|
||||
return;
|
||||
}
|
||||
if (cn0Array[numSv - 4] > 0.0) {
|
||||
double top4AvgCn0 = 0.0;
|
||||
for (int i = numSv - 4; i < numSv; i++) {
|
||||
@@ -265,4 +289,62 @@ public class GnssMetrics {
|
||||
topFourAverageCn0Statistics.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Class for handling GNSS power related metrics */
|
||||
private class GnssPowerMetrics {
|
||||
|
||||
/* Threshold for Top Four Average CN0 below which GNSS signal quality is declared poor */
|
||||
private static final double POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ = 20.0;
|
||||
|
||||
/* Minimum change in Top Four Average CN0 needed to trigger a report */
|
||||
private static final double REPORTING_THRESHOLD_DB_HZ = 1.0;
|
||||
|
||||
/* BatteryStats API */
|
||||
private final IBatteryStats mBatteryStats;
|
||||
|
||||
/* Last reported Top Four Average CN0 */
|
||||
private double mLastAverageCn0;
|
||||
|
||||
public GnssPowerMetrics(IBatteryStats stats) {
|
||||
mBatteryStats = stats;
|
||||
// Used to initialize the variable to a very small value (unachievable in practice) so that
|
||||
// the first CNO report will trigger an update to BatteryStats
|
||||
mLastAverageCn0 = -100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports signal quality to BatteryStats. Signal quality is based on Top four average CN0. If
|
||||
* the number of SVs seen is less than 4, then signal quality is the average CN0.
|
||||
* Changes are reported only if the average CN0 changes by more than REPORTING_THRESHOLD_DB_HZ.
|
||||
*/
|
||||
public void reportSignalQuality(float[] ascendingCN0Array, int numSv) {
|
||||
double avgCn0 = 0.0;
|
||||
if (numSv > 0) {
|
||||
for (int i = Math.max(0, numSv - 4); i < numSv; i++) {
|
||||
avgCn0 += (double) ascendingCN0Array[i];
|
||||
}
|
||||
avgCn0 /= Math.min(numSv, 4);
|
||||
}
|
||||
if (Math.abs(avgCn0 - mLastAverageCn0) < REPORTING_THRESHOLD_DB_HZ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mBatteryStats.noteGpsSignalQuality(getSignalLevel(avgCn0));
|
||||
mLastAverageCn0 = avgCn0;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Exception", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains signal level based on CN0
|
||||
*/
|
||||
private int getSignalLevel(double cn0) {
|
||||
if (cn0 > POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ) {
|
||||
return GnssMetrics.GPS_SIGNAL_QUALITY_GOOD;
|
||||
}
|
||||
return GnssMetrics.GPS_SIGNAL_QUALITY_POOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user