Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78ccaf5d authored by Siddharth Ray's avatar Siddharth Ray
Browse files

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
parent 61823f3a
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -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;

@@ -1497,6 +1498,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;
@@ -2085,6 +2090,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.
@@ -2309,6 +2331,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[] {
@@ -4726,6 +4751,43 @@ public abstract class BatteryStats implements Parcelable {

        printControllerActivity(pw, sb, prefix, "WiFi", getWifiControllerActivity(), which);

        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);
+20 −0
Original line number Diff line number Diff line
/*
 * 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
+108 −0
Original line number Diff line number Diff line
/*
 * 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
+5 −0
Original line number Diff line number Diff line
@@ -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;
@@ -87,6 +88,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);
@@ -138,6 +140,9 @@ interface IBatteryStats {
    /** {@hide} */
    CellularBatteryStats getCellularBatteryStats();

    /** {@hide} */
    GpsBatteryStats getGpsBatteryStats();

    HealthStatsParceler takeUidSnapshot(int uid);
    HealthStatsParceler[] takeUidSnapshots(in int[] uid);

+98 −1
Original line number Diff line number Diff line
@@ -31,6 +31,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;
@@ -73,6 +74,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;
@@ -635,6 +637,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 =
@@ -4478,10 +4484,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;
@@ -4815,6 +4848,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();
@@ -6052,6 +6097,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);
    }
@@ -9757,6 +9816,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);
@@ -10445,6 +10508,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);
@@ -12301,6 +12367,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;
@@ -12906,6 +12987,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);
@@ -13344,6 +13428,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);
@@ -13816,7 +13903,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,
@@ -14016,6 +14106,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);
@@ -14210,6 +14303,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:");
Loading