diff options
| author | 2018-01-19 21:40:07 +0000 | |
|---|---|---|
| committer | 2018-01-19 21:40:07 +0000 | |
| commit | f87fe4845608d26da0a7d5b5dc07c6d3cb3c7ff4 (patch) | |
| tree | 1bc4c399b5fabcc20e105d25c8cf272f1d822873 | |
| parent | 19916d8b8edbf26e49bedfbd805bc3772af02576 (diff) | |
| parent | 78ccaf5d287cbb6bd214913d72653aa74ecfef76 (diff) | |
Merge "GPS Signal Quality added to BatteryStats"
8 files changed, 395 insertions, 4 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 4c35a5c75c47..49879a8a84a7 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -35,6 +35,7 @@ import android.util.proto.ProtoOutputStream; import android.view.Display; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.location.gnssmetrics.GnssMetrics; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; @@ -1508,6 +1509,10 @@ public abstract class BatteryStats implements Parcelable { public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4; public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK = 0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT; + // Values for NUM_GPS_SIGNAL_QUALITY_LEVELS + public static final int STATE2_GPS_SIGNAL_QUALITY_SHIFT = 7; + public static final int STATE2_GPS_SIGNAL_QUALITY_MASK = + 0x1 << STATE2_GPS_SIGNAL_QUALITY_SHIFT; public static final int STATE2_POWER_SAVE_FLAG = 1<<31; public static final int STATE2_VIDEO_ON_FLAG = 1<<30; @@ -2096,6 +2101,23 @@ public abstract class BatteryStats implements Parcelable { */ public abstract int getNumConnectivityChange(int which); + + /** + * Returns the time in microseconds that the phone has been running with + * the given GPS signal quality level + * + * {@hide} + */ + public abstract long getGpsSignalQualityTime(int strengthBin, + long elapsedRealtimeUs, int which); + + /** + * Returns the GPS battery drain in mA-ms + * + * {@hide} + */ + public abstract long getGpsBatteryDrainMaMs(); + /** * Returns the time in microseconds that the phone has been on while the device was * running on battery. @@ -2320,6 +2342,9 @@ public abstract class BatteryStats implements Parcelable { WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES), new BitDescription(HistoryItem.STATE2_CAMERA_FLAG, "camera", "ca"), new BitDescription(HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG, "ble_scan", "bles"), + new BitDescription(HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK, + HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT, "gps_signal_quality", "Gss", + new String[] { "poor", "good"}, new String[] { "poor", "good"}), }; public static final String[] HISTORY_EVENT_NAMES = new String[] { @@ -4740,6 +4765,43 @@ public abstract class BatteryStats implements Parcelable { pw.print(prefix); sb.setLength(0); sb.append(prefix); + sb.append(" GPS Statistics:"); + pw.println(sb.toString()); + + sb.setLength(0); + sb.append(prefix); + sb.append(" GPS signal quality (Top 4 Average CN0):"); + final String[] gpsSignalQualityDescription = new String[]{ + "poor (less than 20 dBHz): ", + "good (greater than 20 dBHz): "}; + final int numGpsSignalQualityBins = Math.min(GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS, + gpsSignalQualityDescription.length); + for (int i=0; i<numGpsSignalQualityBins; i++) { + final long time = getGpsSignalQualityTime(i, rawRealtime, which); + sb.append("\n "); + sb.append(prefix); + sb.append(" "); + sb.append(gpsSignalQualityDescription[i]); + formatTimeMs(sb, time/1000); + sb.append("("); + sb.append(formatRatioLocked(time, whichBatteryRealtime)); + sb.append(") "); + } + pw.println(sb.toString()); + + final long gpsBatteryDrainMaMs = getGpsBatteryDrainMaMs(); + if (gpsBatteryDrainMaMs > 0) { + pw.print(prefix); + sb.setLength(0); + sb.append(prefix); + sb.append(" Battery Drain (mAh): "); + sb.append(Double.toString(((double) gpsBatteryDrainMaMs)/(3600 * 1000))); + pw.println(sb.toString()); + } + + pw.print(prefix); + sb.setLength(0); + sb.append(prefix); sb.append(" CONNECTIVITY POWER SUMMARY END"); pw.println(sb.toString()); pw.println(""); diff --git a/core/java/android/os/connectivity/GpsBatteryStats.aidl b/core/java/android/os/connectivity/GpsBatteryStats.aidl new file mode 100644 index 000000000000..7b96d1a8e062 --- /dev/null +++ b/core/java/android/os/connectivity/GpsBatteryStats.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2016 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.os.connectivity; + +/** {@hide} */ +parcelable GpsBatteryStats;
\ No newline at end of file diff --git a/core/java/android/os/connectivity/GpsBatteryStats.java b/core/java/android/os/connectivity/GpsBatteryStats.java new file mode 100644 index 000000000000..f2ac5ef6d40b --- /dev/null +++ b/core/java/android/os/connectivity/GpsBatteryStats.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2016 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.os.connectivity; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.location.gnssmetrics.GnssMetrics; + +import java.util.Arrays; + +/** + * API for GPS power stats + * + * @hide + */ +public final class GpsBatteryStats implements Parcelable { + + private long mLoggingDurationMs; + private long mEnergyConsumedMaMs; + private long[] mTimeInGpsSignalQualityLevel; + + public static final Parcelable.Creator<GpsBatteryStats> CREATOR = new + Parcelable.Creator<GpsBatteryStats>() { + public GpsBatteryStats createFromParcel(Parcel in) { + return new GpsBatteryStats(in); + } + + public GpsBatteryStats[] newArray(int size) { + return new GpsBatteryStats[size]; + } + }; + + public GpsBatteryStats() { + initialize(); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeLong(mLoggingDurationMs); + out.writeLong(mEnergyConsumedMaMs); + out.writeLongArray(mTimeInGpsSignalQualityLevel); + } + + public void readFromParcel(Parcel in) { + mLoggingDurationMs = in.readLong(); + mEnergyConsumedMaMs = in.readLong(); + in.readLongArray(mTimeInGpsSignalQualityLevel); + } + + public long getLoggingDurationMs() { + return mLoggingDurationMs; + } + + public long getEnergyConsumedMaMs() { + return mEnergyConsumedMaMs; + } + + public long[] getTimeInGpsSignalQualityLevel() { + return mTimeInGpsSignalQualityLevel; + } + + public void setLoggingDurationMs(long t) { + mLoggingDurationMs = t; + return; + } + + public void setEnergyConsumedMaMs(long e) { + mEnergyConsumedMaMs = e; + return; + } + + public void setTimeInGpsSignalQualityLevel(long[] t) { + mTimeInGpsSignalQualityLevel = Arrays.copyOfRange(t, 0, + Math.min(t.length, GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS)); + return; + } + + @Override + public int describeContents() { + return 0; + } + + private GpsBatteryStats(Parcel in) { + initialize(); + readFromParcel(in); + } + + private void initialize() { + mLoggingDurationMs = 0; + mEnergyConsumedMaMs = 0; + mTimeInGpsSignalQualityLevel = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; + return; + } +}
\ No newline at end of file diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 388180dc61e0..e2d1ad59043e 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -23,6 +23,7 @@ import android.net.wifi.WifiActivityEnergyInfo; import android.os.ParcelFileDescriptor; import android.os.WorkSource; import android.os.connectivity.CellularBatteryStats; +import android.os.connectivity.GpsBatteryStats; import android.os.health.HealthStatsParceler; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.ModemActivityInfo; @@ -91,6 +92,7 @@ interface IBatteryStats { void noteVibratorOff(int uid); void noteStartGps(int uid); void noteStopGps(int uid); + void noteGpsSignalQuality(int signalLevel); void noteScreenState(int state); void noteScreenBrightness(int brightness); void noteUserActivity(int uid, int event); @@ -140,6 +142,9 @@ interface IBatteryStats { /** {@hide} */ CellularBatteryStats getCellularBatteryStats(); + /** {@hide} */ + GpsBatteryStats getGpsBatteryStats(); + HealthStatsParceler takeUidSnapshot(int uid); HealthStatsParceler[] takeUidSnapshots(in int[] uid); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index b4bfee5802ff..bd22b33f9507 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -34,6 +34,7 @@ import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Build; import android.os.connectivity.CellularBatteryStats; +import android.os.connectivity.GpsBatteryStats; import android.os.FileUtils; import android.os.Handler; import android.os.IBatteryPropertiesRegistrar; @@ -78,6 +79,7 @@ import android.view.Display; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.location.gnssmetrics.GnssMetrics; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; @@ -672,6 +674,10 @@ public class BatteryStatsImpl extends BatteryStats { int mCameraOnNesting; StopwatchTimer mCameraOnTimer; + int mGpsSignalQualityBin = -1; + final StopwatchTimer[] mGpsSignalQualityTimer = + new StopwatchTimer[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; + int mPhoneSignalStrengthBin = -1; int mPhoneSignalStrengthBinRaw = -1; final StopwatchTimer[] mPhoneSignalStrengthsTimer = @@ -4583,10 +4589,37 @@ public class BatteryStatsImpl extends BatteryStats { if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " + Integer.toHexString(mHistoryCur.states)); addHistoryRecordLocked(elapsedRealtime, uptime); + stopAllGpsSignalQualityTimersLocked(-1); + mGpsSignalQualityBin = -1; } getUidStatsLocked(uid).noteStopGps(elapsedRealtime); } + public void noteGpsSignalQualityLocked(int signalLevel) { + if (mGpsNesting == 0) { + return; + } + if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { + stopAllGpsSignalQualityTimersLocked(-1); + return; + } + final long elapsedRealtime = mClocks.elapsedRealtime(); + final long uptime = mClocks.uptimeMillis(); + if (mGpsSignalQualityBin != signalLevel) { + if (mGpsSignalQualityBin >= 0) { + mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime); + } + if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { + mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime); + } + mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) + | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); + addHistoryRecordLocked(elapsedRealtime, uptime); + mGpsSignalQualityBin = signalLevel; + } + return; + } + public void noteScreenStateLocked(int state) { state = mPretendScreenOff ? Display.STATE_OFF : state; @@ -4920,6 +4953,18 @@ public class BatteryStatsImpl extends BatteryStats { mDailyPackageChanges.add(pc); } + void stopAllGpsSignalQualityTimersLocked(int except) { + final long elapsedRealtime = mClocks.elapsedRealtime(); + for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + if (i == except) { + continue; + } + while (mGpsSignalQualityTimer[i].isRunningLocked()) { + mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime); + } + } + } + public void notePhoneOnLocked() { if (!mPhoneOn) { final long elapsedRealtime = mClocks.elapsedRealtime(); @@ -6131,6 +6176,20 @@ public class BatteryStatsImpl extends BatteryStats { return val; } + @Override public long getGpsSignalQualityTime(int strengthBin, + long elapsedRealtimeUs, int which) { + if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { + return 0; + } + return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( + elapsedRealtimeUs, which); + } + + @Override public long getGpsBatteryDrainMaMs() { + //TODO: Add GPS power computation (b/67213967) + return 0; + } + @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); } @@ -9857,6 +9916,10 @@ public class BatteryStatsImpl extends BatteryStats { mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, mOnBatteryTimeBase); } + for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, + mOnBatteryTimeBase); + } mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); @@ -10546,6 +10609,9 @@ public class BatteryStatsImpl extends BatteryStats { mWifiSignalStrengthsTimer[i].reset(false); } mWifiMulticastWakelockTimer.reset(false); + for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + mGpsSignalQualityTimer[i].reset(false); + } mWifiActivity.reset(false); mBluetoothActivity.reset(false); mModemActivity.reset(false); @@ -12464,6 +12530,21 @@ public class BatteryStatsImpl extends BatteryStats { return s; } + /*@hide */ + public GpsBatteryStats getGpsBatteryStats() { + GpsBatteryStats s = new GpsBatteryStats(); + final int which = STATS_SINCE_CHARGED; + final long rawRealTime = SystemClock.elapsedRealtime() * 1000; + s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); + s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); + long[] time = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; + for (int i=0; i<time.length; i++) { + time[i] = getGpsSignalQualityTime(i, rawRealTime, which) / 1000; + } + s.setTimeInGpsSignalQualityLevel(time); + return s; + } + @Override public LevelStepTracker getChargeLevelStepTracker() { return mChargeStepTracker; @@ -13141,6 +13222,9 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); } + for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); + } mWifiActivity.readSummaryFromParcel(in); mBluetoothActivity.readSummaryFromParcel(in); mModemActivity.readSummaryFromParcel(in); @@ -13583,6 +13667,9 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); } + for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } mWifiActivity.writeSummaryToParcel(out); mBluetoothActivity.writeSummaryToParcel(out); mModemActivity.writeSummaryToParcel(out); @@ -14058,7 +14145,10 @@ public class BatteryStatsImpl extends BatteryStats { mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, mOnBatteryTimeBase, in); } - + for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, + null, mOnBatteryTimeBase, in); + } mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS, in); mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, @@ -14258,6 +14348,9 @@ public class BatteryStatsImpl extends BatteryStats { for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); } + for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); + } mWifiActivity.writeToParcel(out, 0); mBluetoothActivity.writeToParcel(out, 0); mModemActivity.writeToParcel(out, 0); @@ -14452,6 +14545,10 @@ public class BatteryStatsImpl extends BatteryStats { pr.println("*** Wifi signal strength #" + i + ":"); mWifiSignalStrengthsTimer[i].logState(pr, " "); } + for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { + pr.println("*** GPS signal quality #" + i + ":"); + mGpsSignalQualityTimer[i].logState(pr, " "); + } pr.println("*** Flashlight timer:"); mFlashlightOnTimer.logState(pr, " "); pr.println("*** Camera timer:"); diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java index 833376cfa057..603926f4fe4d 100644 --- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java +++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java @@ -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; + } + } }
\ No newline at end of file diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 81e8eb0d4136..207aaa76e5b8 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -40,6 +40,7 @@ import android.os.UserManagerInternal; import android.os.WorkSource; import android.os.WorkSource.WorkChain; import android.os.connectivity.CellularBatteryStats; +import android.os.connectivity.GpsBatteryStats; import android.os.health.HealthStatsParceler; import android.os.health.HealthStatsWriter; import android.os.health.UidHealthStats; @@ -594,6 +595,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } + public void noteGpsSignalQuality(int signalLevel) { + synchronized (mStats) { + mStats.noteGpsSignalQualityLocked(signalLevel); + } + } + public void noteScreenState(int state) { enforceCallingPermission(); if (DBG) Slog.d(TAG, "begin noteScreenState"); @@ -1448,6 +1455,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub } /** + * Gets a snapshot of Gps stats + * @hide + */ + public GpsBatteryStats getGpsBatteryStats() { + synchronized (mStats) { + return mStats.getGpsBatteryStats(); + } + } + + /** * Gets a snapshot of the system health for a particular uid. */ @Override diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 6dc5403acc99..48d275cc483f 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -827,7 +827,7 @@ public class GnssLocationProvider implements LocationProviderInterface { return isEnabled(); } }; - mGnssMetrics = new GnssMetrics(); + mGnssMetrics = new GnssMetrics(mBatteryStats); } /** |