Loading core/java/android/os/BatteryStats.java +74 −0 Original line number Diff line number Diff line Loading @@ -2702,6 +2702,46 @@ public abstract class BatteryStats implements Parcelable { @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs); /** * Returns the time in microseconds that the mobile radio has been actively transmitting data on * a given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given * transmission power level. * * @param rat Radio Access Technology {@see RadioAccessTechnology} * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for * RADIO_ACCESS_TECHNOLOGY_NR. Use * {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access * Technologies. * @param signalStrength the cellular signal strength. {@see CellSignalStrength#getLevel()} * @param elapsedRealtimeMs current elapsed realtime * @return time (in milliseconds) the mobile radio spent actively transmitting data in the * specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if * data unavailable. * @hide */ public abstract long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs); /** * Returns the time in microseconds that the mobile radio has been actively receiving data on a * given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given * transmission power level. * * @param rat Radio Access Technology {@see RadioAccessTechnology} * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for * RADIO_ACCESS_TECHNOLOGY_NR. Use * {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access * Technologies. * @param elapsedRealtimeMs current elapsed realtime * @return time (in milliseconds) the mobile radio spent actively receiving data in the * specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if * data unavailable. * @hide */ public abstract long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs); static final String[] WIFI_SUPPL_STATE_NAMES = { "invalid", "disconn", "disabled", "inactive", "scanning", "authenticating", "associating", "associated", "4-way-handshake", Loading @@ -2721,6 +2761,13 @@ public abstract class BatteryStats implements Parcelable { */ public static final long POWER_DATA_UNAVAILABLE = -1L; /** * Returned value if duration data is unavailable. * * {@hide} */ public static final long DURATION_UNAVAILABLE = -1L; /** * Returns the battery consumption (in microcoulombs) of bluetooth, derived from on * device power measurement data. Loading Loading @@ -4095,6 +4142,10 @@ public abstract class BatteryStats implements Parcelable { " Mmwave frequency (greater than 6GHz):\n"}; final String signalStrengthHeader = " Signal Strength Time:\n"; final String txHeader = " Tx Time:\n"; final String rxHeader = " Rx Time: "; final String[] signalStrengthDescription = new String[]{ " unknown: ", " poor: ", Loading Loading @@ -4146,6 +4197,29 @@ public abstract class BatteryStats implements Parcelable { sb.append(")\n"); } sb.append(prefix); sb.append(txHeader); for (int strength = 0; strength < numSignalStrength; strength++) { final long timeMs = getActiveTxRadioDurationMs(rat, freqLvl, strength, rawRealtimeMs); if (timeMs <= 0) continue; hasFreqData = true; sb.append(prefix); sb.append(signalStrengthDescription[strength]); formatTimeMs(sb, timeMs); sb.append("("); sb.append(formatRatioLocked(timeMs, totalActiveTimesMs)); sb.append(")\n"); } sb.append(prefix); sb.append(rxHeader); final long rxTimeMs = getActiveRxRadioDurationMs(rat, freqLvl, rawRealtimeMs); formatTimeMs(sb, rxTimeMs); sb.append("("); sb.append(formatRatioLocked(rxTimeMs, totalActiveTimesMs)); sb.append(")\n"); if (hasFreqData) { hasData = true; pw.print(sb); Loading core/java/com/android/internal/os/BatteryStatsImpl.java +300 −2 Original line number Diff line number Diff line Loading @@ -166,7 +166,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version static final int VERSION = 206; static final int VERSION = 207; // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks Loading Loading @@ -964,6 +964,16 @@ public class BatteryStatsImpl extends BatteryStats { * Timers for each combination of frequency range and signal strength. */ public final StopwatchTimer[][] perStateTimers; /** * Counters tracking the time (in milliseconds) spent transmitting data in a given state. */ @Nullable private LongSamplingCounter[][] mPerStateTxDurationMs = null; /** * Counters tracking the time (in milliseconds) spent receiving data in at given frequency. */ @Nullable private LongSamplingCounter[] mPerFrequencyRxDurationMs = null; RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) { perStateTimers = Loading Loading @@ -1024,15 +1034,198 @@ public class BatteryStatsImpl extends BatteryStats { } /** * Reset display timers. * Returns the duration in milliseconds spent in a given state since the last mark. */ public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs) { return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked( elapsedRealtimeMs * 1000) / 1000; } /** * Set mark for all timers. */ public void setMark(long elapsedRealtimeMs) { final int size = perStateTimers.length; for (int i = 0; i < size; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { perStateTimers[i][j].setMark(elapsedRealtimeMs); } } } /** * Returns numbers of frequencies tracked for this RAT. */ public int getFrequencyRangeCount() { return perStateTimers.length; } /** * Add TX time for a given state. */ public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange, int signalStrength, long durationMs) { getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs); } /** * Add TX time for a given frequency. */ public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange, long durationMs) { getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs); } /** * Reset radio access technology timers and counts. */ public void reset(long elapsedRealtimeUs) { final int size = perStateTimers.length; for (int i = 0; i < size; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { perStateTimers[i][j].reset(false, elapsedRealtimeUs); if (mPerStateTxDurationMs == null) continue; mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs); } if (mPerFrequencyRxDurationMs == null) continue; mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs); } } /** * Write data to summary parcel */ public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { final int freqCount = perStateTimers.length; out.writeInt(freqCount); out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS); for (int i = 0; i < freqCount; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); } } if (mPerStateTxDurationMs == null) { out.writeInt(0); } else { out.writeInt(1); for (int i = 0; i < freqCount; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out); } } } if (mPerFrequencyRxDurationMs == null) { out.writeInt(0); } else { out.writeInt(1); for (int i = 0; i < freqCount; i++) { mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out); } } } /** * Read data from summary parcel */ public void readSummaryFromParcel(Parcel in) { final int oldFreqCount = in.readInt(); final int oldSignalStrengthCount = in.readInt(); final int currFreqCount = perStateTimers.length; final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; for (int freq = 0; freq < oldFreqCount; freq++) { for (int strength = 0; strength < oldSignalStrengthCount; strength++) { if (freq >= currFreqCount || strength >= currSignalStrengthCount) { // Mismatch with the summary parcel. Consume the data but don't use it. final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); // Consume perStateTimers data. temp.readSummaryFromParcelLocked(in); } else { perStateTimers[freq][strength].readSummaryFromParcelLocked(in); } } } if (in.readInt() == 1) { for (int freq = 0; freq < oldFreqCount; freq++) { for (int strength = 0; strength < oldSignalStrengthCount; strength++) { if (freq >= currFreqCount || strength >= currSignalStrengthCount) { // Mismatch with the summary parcel. Consume the data but don't use it. final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); // Consume mPerStateTxDurationMs data. temp.readSummaryFromParcelLocked(in); } getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in); } } } if (in.readInt() == 1) { for (int freq = 0; freq < oldFreqCount; freq++) { if (freq >= currFreqCount) { // Mismatch with the summary parcel. Consume the data but don't use it. final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); // Consume mPerFrequencyRxDurationMs data. temp.readSummaryFromParcelLocked(in); continue; } getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in); } } } private LongSamplingCounter getTxDurationCounter( @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) { if (mPerStateTxDurationMs == null) { if (!make) return null; final int freqCount = getFrequencyRangeCount(); final int signalStrengthCount = perStateTimers[0].length; final TimeBase timeBase = perStateTimers[0][0].mTimeBase; mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount]; for (int freq = 0; freq < freqCount; freq++) { for (int strength = 0; strength < signalStrengthCount; strength++) { mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase); } } } if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { Slog.w(TAG, "Unexpected frequency range (" + frequencyRange + ") requested in getTxDurationCounter"); return null; } if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) { Slog.w(TAG, "Unexpected signal strength (" + signalStrength + ") requested in getTxDurationCounter"); return null; } return mPerStateTxDurationMs[frequencyRange][signalStrength]; } private LongSamplingCounter getRxDurationCounter( @ServiceState.FrequencyRange int frequencyRange, boolean make) { if (mPerFrequencyRxDurationMs == null) { if (!make) return null; final int freqCount = getFrequencyRangeCount(); final TimeBase timeBase = perStateTimers[0][0].mTimeBase; mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount]; for (int freq = 0; freq < freqCount; freq++) { mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase); } } if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { Slog.w(TAG, "Unexpected frequency range (" + frequencyRange + ") requested in getRxDurationCounter"); return null; } return mPerFrequencyRxDurationMs[frequencyRange]; } } Loading Loading @@ -8006,6 +8199,32 @@ public class BatteryStatsImpl extends BatteryStats { elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; } @Override public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs) { final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; if (stats == null) return DURATION_UNAVAILABLE; final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange, signalStrength, false); if (counter == null) return DURATION_UNAVAILABLE; return counter.getCountLocked(STATS_SINCE_CHARGED); } @Override public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) { final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; if (stats == null) return DURATION_UNAVAILABLE; final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false); if (counter == null) return DURATION_UNAVAILABLE; return counter.getCountLocked(STATS_SINCE_CHARGED); } @UnsupportedAppUsage @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); Loading Loading @@ -13484,6 +13703,67 @@ public class BatteryStatsImpl extends BatteryStats { addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mTmpRailStats.resetCellularTotalEnergyUsed(); } // Proportionally smear Rx and Tx times across each RAt final int levelCount = CellSignalStrength.getNumSignalStrengthLevels(); long[] perSignalStrengthActiveTimeMs = new long[levelCount]; long totalActiveTimeMs = 0; for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; if (ratStats == null) continue; final int freqCount = ratStats.getFrequencyRangeCount(); for (int freq = 0; freq < freqCount; freq++) { for (int level = 0; level < levelCount; level++) { final long durationMs = ratStats.getTimeSinceMark(freq, level, elapsedRealtimeMs); perSignalStrengthActiveTimeMs[level] += durationMs; totalActiveTimeMs += durationMs; } } } if (totalActiveTimeMs != 0) { // Smear the provided Tx/Rx durations across each RAT, frequency, and signal // strength. for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; if (ratStats == null) continue; final int freqCount = ratStats.getFrequencyRangeCount(); for (int freq = 0; freq < freqCount; freq++) { long frequencyDurationMs = 0; for (int level = 0; level < levelCount; level++) { final long durationMs = ratStats.getTimeSinceMark(freq, level, elapsedRealtimeMs); final long totalLvlDurationMs = perSignalStrengthActiveTimeMs[level]; if (totalLvlDurationMs == 0) continue; final long totalTxLvlDurations = deltaInfo.getTransmitDurationMillisAtPowerLevel(level); // Smear HAL provided Tx power level duration based on active modem // duration in a given state. (Add totalLvlDurationMs / 2 before // the integer division with totalLvlDurationMs for rounding.) final long proportionalTxDurationMs = (durationMs * totalTxLvlDurations + (totalLvlDurationMs / 2)) / totalLvlDurationMs; ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs); frequencyDurationMs += durationMs; } final long totalRxDuration = deltaInfo.getReceiveTimeMillis(); // Smear HAL provided Rx power duration based on active modem // duration in a given state. (Add totalActiveTimeMs / 2 before the // integer division with totalActiveTimeMs for rounding.) final long proportionalRxDurationMs = (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs / 2)) / totalActiveTimeMs; ratStats.incrementRxDuration(freq, proportionalRxDurationMs); } ratStats.setMark(elapsedRealtimeMs); } } } long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( elapsedRealtimeMs * 1000); Loading Loading @@ -16932,6 +17212,13 @@ public class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); } final int numRat = in.readInt(); for (int i = 0; i < numRat; i++) { if (in.readInt() == 0) continue; getRatBatteryStatsLocked(i).readSummaryFromParcel(in); } mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); Loading Loading @@ -17432,6 +17719,17 @@ public class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); } final int numRat = mPerRatBatteryStats.length; out.writeInt(numRat); for (int i = 0; i < numRat; i++) { final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i]; if (ratStat == null) { out.writeInt(0); continue; } out.writeInt(1); ratStat.writeSummaryToParcel(out, nowRealtime); } mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime); mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +422 −78 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/os/BatteryStats.java +74 −0 Original line number Diff line number Diff line Loading @@ -2702,6 +2702,46 @@ public abstract class BatteryStats implements Parcelable { @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs); /** * Returns the time in microseconds that the mobile radio has been actively transmitting data on * a given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given * transmission power level. * * @param rat Radio Access Technology {@see RadioAccessTechnology} * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for * RADIO_ACCESS_TECHNOLOGY_NR. Use * {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access * Technologies. * @param signalStrength the cellular signal strength. {@see CellSignalStrength#getLevel()} * @param elapsedRealtimeMs current elapsed realtime * @return time (in milliseconds) the mobile radio spent actively transmitting data in the * specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if * data unavailable. * @hide */ public abstract long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs); /** * Returns the time in microseconds that the mobile radio has been actively receiving data on a * given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given * transmission power level. * * @param rat Radio Access Technology {@see RadioAccessTechnology} * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for * RADIO_ACCESS_TECHNOLOGY_NR. Use * {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access * Technologies. * @param elapsedRealtimeMs current elapsed realtime * @return time (in milliseconds) the mobile radio spent actively receiving data in the * specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if * data unavailable. * @hide */ public abstract long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs); static final String[] WIFI_SUPPL_STATE_NAMES = { "invalid", "disconn", "disabled", "inactive", "scanning", "authenticating", "associating", "associated", "4-way-handshake", Loading @@ -2721,6 +2761,13 @@ public abstract class BatteryStats implements Parcelable { */ public static final long POWER_DATA_UNAVAILABLE = -1L; /** * Returned value if duration data is unavailable. * * {@hide} */ public static final long DURATION_UNAVAILABLE = -1L; /** * Returns the battery consumption (in microcoulombs) of bluetooth, derived from on * device power measurement data. Loading Loading @@ -4095,6 +4142,10 @@ public abstract class BatteryStats implements Parcelable { " Mmwave frequency (greater than 6GHz):\n"}; final String signalStrengthHeader = " Signal Strength Time:\n"; final String txHeader = " Tx Time:\n"; final String rxHeader = " Rx Time: "; final String[] signalStrengthDescription = new String[]{ " unknown: ", " poor: ", Loading Loading @@ -4146,6 +4197,29 @@ public abstract class BatteryStats implements Parcelable { sb.append(")\n"); } sb.append(prefix); sb.append(txHeader); for (int strength = 0; strength < numSignalStrength; strength++) { final long timeMs = getActiveTxRadioDurationMs(rat, freqLvl, strength, rawRealtimeMs); if (timeMs <= 0) continue; hasFreqData = true; sb.append(prefix); sb.append(signalStrengthDescription[strength]); formatTimeMs(sb, timeMs); sb.append("("); sb.append(formatRatioLocked(timeMs, totalActiveTimesMs)); sb.append(")\n"); } sb.append(prefix); sb.append(rxHeader); final long rxTimeMs = getActiveRxRadioDurationMs(rat, freqLvl, rawRealtimeMs); formatTimeMs(sb, rxTimeMs); sb.append("("); sb.append(formatRatioLocked(rxTimeMs, totalActiveTimesMs)); sb.append(")\n"); if (hasFreqData) { hasData = true; pw.print(sb); Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +300 −2 Original line number Diff line number Diff line Loading @@ -166,7 +166,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version static final int VERSION = 206; static final int VERSION = 207; // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks Loading Loading @@ -964,6 +964,16 @@ public class BatteryStatsImpl extends BatteryStats { * Timers for each combination of frequency range and signal strength. */ public final StopwatchTimer[][] perStateTimers; /** * Counters tracking the time (in milliseconds) spent transmitting data in a given state. */ @Nullable private LongSamplingCounter[][] mPerStateTxDurationMs = null; /** * Counters tracking the time (in milliseconds) spent receiving data in at given frequency. */ @Nullable private LongSamplingCounter[] mPerFrequencyRxDurationMs = null; RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) { perStateTimers = Loading Loading @@ -1024,15 +1034,198 @@ public class BatteryStatsImpl extends BatteryStats { } /** * Reset display timers. * Returns the duration in milliseconds spent in a given state since the last mark. */ public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs) { return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked( elapsedRealtimeMs * 1000) / 1000; } /** * Set mark for all timers. */ public void setMark(long elapsedRealtimeMs) { final int size = perStateTimers.length; for (int i = 0; i < size; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { perStateTimers[i][j].setMark(elapsedRealtimeMs); } } } /** * Returns numbers of frequencies tracked for this RAT. */ public int getFrequencyRangeCount() { return perStateTimers.length; } /** * Add TX time for a given state. */ public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange, int signalStrength, long durationMs) { getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs); } /** * Add TX time for a given frequency. */ public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange, long durationMs) { getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs); } /** * Reset radio access technology timers and counts. */ public void reset(long elapsedRealtimeUs) { final int size = perStateTimers.length; for (int i = 0; i < size; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { perStateTimers[i][j].reset(false, elapsedRealtimeUs); if (mPerStateTxDurationMs == null) continue; mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs); } if (mPerFrequencyRxDurationMs == null) continue; mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs); } } /** * Write data to summary parcel */ public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { final int freqCount = perStateTimers.length; out.writeInt(freqCount); out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS); for (int i = 0; i < freqCount; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); } } if (mPerStateTxDurationMs == null) { out.writeInt(0); } else { out.writeInt(1); for (int i = 0; i < freqCount; i++) { for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out); } } } if (mPerFrequencyRxDurationMs == null) { out.writeInt(0); } else { out.writeInt(1); for (int i = 0; i < freqCount; i++) { mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out); } } } /** * Read data from summary parcel */ public void readSummaryFromParcel(Parcel in) { final int oldFreqCount = in.readInt(); final int oldSignalStrengthCount = in.readInt(); final int currFreqCount = perStateTimers.length; final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; for (int freq = 0; freq < oldFreqCount; freq++) { for (int strength = 0; strength < oldSignalStrengthCount; strength++) { if (freq >= currFreqCount || strength >= currSignalStrengthCount) { // Mismatch with the summary parcel. Consume the data but don't use it. final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); // Consume perStateTimers data. temp.readSummaryFromParcelLocked(in); } else { perStateTimers[freq][strength].readSummaryFromParcelLocked(in); } } } if (in.readInt() == 1) { for (int freq = 0; freq < oldFreqCount; freq++) { for (int strength = 0; strength < oldSignalStrengthCount; strength++) { if (freq >= currFreqCount || strength >= currSignalStrengthCount) { // Mismatch with the summary parcel. Consume the data but don't use it. final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); // Consume mPerStateTxDurationMs data. temp.readSummaryFromParcelLocked(in); } getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in); } } } if (in.readInt() == 1) { for (int freq = 0; freq < oldFreqCount; freq++) { if (freq >= currFreqCount) { // Mismatch with the summary parcel. Consume the data but don't use it. final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); // Consume mPerFrequencyRxDurationMs data. temp.readSummaryFromParcelLocked(in); continue; } getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in); } } } private LongSamplingCounter getTxDurationCounter( @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) { if (mPerStateTxDurationMs == null) { if (!make) return null; final int freqCount = getFrequencyRangeCount(); final int signalStrengthCount = perStateTimers[0].length; final TimeBase timeBase = perStateTimers[0][0].mTimeBase; mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount]; for (int freq = 0; freq < freqCount; freq++) { for (int strength = 0; strength < signalStrengthCount; strength++) { mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase); } } } if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { Slog.w(TAG, "Unexpected frequency range (" + frequencyRange + ") requested in getTxDurationCounter"); return null; } if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) { Slog.w(TAG, "Unexpected signal strength (" + signalStrength + ") requested in getTxDurationCounter"); return null; } return mPerStateTxDurationMs[frequencyRange][signalStrength]; } private LongSamplingCounter getRxDurationCounter( @ServiceState.FrequencyRange int frequencyRange, boolean make) { if (mPerFrequencyRxDurationMs == null) { if (!make) return null; final int freqCount = getFrequencyRangeCount(); final TimeBase timeBase = perStateTimers[0][0].mTimeBase; mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount]; for (int freq = 0; freq < freqCount; freq++) { mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase); } } if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { Slog.w(TAG, "Unexpected frequency range (" + frequencyRange + ") requested in getRxDurationCounter"); return null; } return mPerFrequencyRxDurationMs[frequencyRange]; } } Loading Loading @@ -8006,6 +8199,32 @@ public class BatteryStatsImpl extends BatteryStats { elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; } @Override public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs) { final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; if (stats == null) return DURATION_UNAVAILABLE; final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange, signalStrength, false); if (counter == null) return DURATION_UNAVAILABLE; return counter.getCountLocked(STATS_SINCE_CHARGED); } @Override public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) { final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; if (stats == null) return DURATION_UNAVAILABLE; final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false); if (counter == null) return DURATION_UNAVAILABLE; return counter.getCountLocked(STATS_SINCE_CHARGED); } @UnsupportedAppUsage @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); Loading Loading @@ -13484,6 +13703,67 @@ public class BatteryStatsImpl extends BatteryStats { addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mTmpRailStats.resetCellularTotalEnergyUsed(); } // Proportionally smear Rx and Tx times across each RAt final int levelCount = CellSignalStrength.getNumSignalStrengthLevels(); long[] perSignalStrengthActiveTimeMs = new long[levelCount]; long totalActiveTimeMs = 0; for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; if (ratStats == null) continue; final int freqCount = ratStats.getFrequencyRangeCount(); for (int freq = 0; freq < freqCount; freq++) { for (int level = 0; level < levelCount; level++) { final long durationMs = ratStats.getTimeSinceMark(freq, level, elapsedRealtimeMs); perSignalStrengthActiveTimeMs[level] += durationMs; totalActiveTimeMs += durationMs; } } } if (totalActiveTimeMs != 0) { // Smear the provided Tx/Rx durations across each RAT, frequency, and signal // strength. for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; if (ratStats == null) continue; final int freqCount = ratStats.getFrequencyRangeCount(); for (int freq = 0; freq < freqCount; freq++) { long frequencyDurationMs = 0; for (int level = 0; level < levelCount; level++) { final long durationMs = ratStats.getTimeSinceMark(freq, level, elapsedRealtimeMs); final long totalLvlDurationMs = perSignalStrengthActiveTimeMs[level]; if (totalLvlDurationMs == 0) continue; final long totalTxLvlDurations = deltaInfo.getTransmitDurationMillisAtPowerLevel(level); // Smear HAL provided Tx power level duration based on active modem // duration in a given state. (Add totalLvlDurationMs / 2 before // the integer division with totalLvlDurationMs for rounding.) final long proportionalTxDurationMs = (durationMs * totalTxLvlDurations + (totalLvlDurationMs / 2)) / totalLvlDurationMs; ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs); frequencyDurationMs += durationMs; } final long totalRxDuration = deltaInfo.getReceiveTimeMillis(); // Smear HAL provided Rx power duration based on active modem // duration in a given state. (Add totalActiveTimeMs / 2 before the // integer division with totalActiveTimeMs for rounding.) final long proportionalRxDurationMs = (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs / 2)) / totalActiveTimeMs; ratStats.incrementRxDuration(freq, proportionalRxDurationMs); } ratStats.setMark(elapsedRealtimeMs); } } } long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( elapsedRealtimeMs * 1000); Loading Loading @@ -16932,6 +17212,13 @@ public class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); } final int numRat = in.readInt(); for (int i = 0; i < numRat; i++) { if (in.readInt() == 0) continue; getRatBatteryStatsLocked(i).readSummaryFromParcel(in); } mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); Loading Loading @@ -17432,6 +17719,17 @@ public class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); } final int numRat = mPerRatBatteryStats.length; out.writeInt(numRat); for (int i = 0; i < numRat; i++) { final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i]; if (ratStat == null) { out.writeInt(0); continue; } out.writeInt(1); ratStat.writeSummaryToParcel(out, nowRealtime); } mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime); mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +422 −78 File changed.Preview size limit exceeded, changes collapsed. Show changes