Utilize specific info provided by the Modem HAL
ModemActivityInfo can now include Radio Access Technology specific information, if the HAL supports it.
If available, utilize the information.
Bug: 207697945
Test: atest BatteryStatsNoteTest
Change-Id: Ifbd3c8cca7baa35cbccf64883ae5ce87ae39ab74
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f623a73..4b20347 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -69,6 +69,7 @@
import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.connectivity.WifiBatteryStats;
import android.provider.Settings;
+import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation.NetworkType;
import android.telephony.CellSignalStrength;
import android.telephony.CellSignalStrengthLte;
@@ -6830,6 +6831,27 @@
}
}
+ @RadioAccessTechnology
+ private static int mapRadioAccessNetworkTypeToRadioAccessTechnology(
+ @AccessNetworkConstants.RadioAccessNetworkType int dataType) {
+ switch (dataType) {
+ case AccessNetworkConstants.AccessNetworkType.NGRAN:
+ return RADIO_ACCESS_TECHNOLOGY_NR;
+ case AccessNetworkConstants.AccessNetworkType.EUTRAN:
+ return RADIO_ACCESS_TECHNOLOGY_LTE;
+ case AccessNetworkConstants.AccessNetworkType.UNKNOWN: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.GERAN: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.UTRAN: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.CDMA2000: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.IWLAN:
+ return RADIO_ACCESS_TECHNOLOGY_OTHER;
+ default:
+ Slog.w(TAG,
+ "Unhandled RadioAccessNetworkType (" + dataType + "), mapping to OTHER");
+ return RADIO_ACCESS_TECHNOLOGY_OTHER;
+ }
+ }
+
@GuardedBy("this")
public void noteWifiOnLocked() {
noteWifiOnLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
@@ -13721,66 +13743,7 @@
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);
- }
- }
+ incrementPerRatDataLocked(deltaInfo, elapsedRealtimeMs);
}
long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
elapsedRealtimeMs * 1000);
@@ -13931,6 +13894,100 @@
}
}
+ @GuardedBy("this")
+ private void incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs) {
+ final int infoSize = deltaInfo.getSpecificInfoLength();
+ if (infoSize == 1 && deltaInfo.getSpecificInfoRat(0)
+ == AccessNetworkConstants.AccessNetworkType.UNKNOWN
+ && deltaInfo.getSpecificInfoFrequencyRange(0)
+ == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Specific info data unavailable. 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);
+ }
+
+ }
+ }
+ } else {
+ // Specific data available.
+ for (int index = 0; index < infoSize; index++) {
+ final int rat = deltaInfo.getSpecificInfoRat(index);
+ final int freq = deltaInfo.getSpecificInfoFrequencyRange(index);
+
+ // Map RadioAccessNetworkType to course grain RadioAccessTechnology.
+ final int ratBucket = mapRadioAccessNetworkTypeToRadioAccessTechnology(rat);
+ final RadioAccessTechnologyBatteryStats ratStats = getRatBatteryStatsLocked(
+ ratBucket);
+
+ final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq);
+ final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq);
+
+ ratStats.incrementRxDuration(freq, rxTimeMs);
+ final int numTxLvl = txTimesMs.length;
+ for (int lvl = 0; lvl < numTxLvl; lvl++) {
+ ratStats.incrementTxDuration(freq, lvl, txTimesMs[lvl]);
+ }
+ }
+ }
+
+ for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+ final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+ if (ratStats == null) continue;
+ ratStats.setMark(elapsedRealtimeMs);
+ }
+ }
+
/**
* Add modem tx power to history
* Device is said to be in high cellular transmit power when it has spent most of the transmit
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index dbe1e81..87c45dc 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -32,12 +32,15 @@
import android.app.ActivityManager;
import android.app.usage.NetworkStatsManager;
+import android.hardware.radio.V1_5.AccessNetwork;
import android.os.BatteryStats;
import android.os.BatteryStats.HistoryItem;
import android.os.BatteryStats.Uid.Sensor;
import android.os.Process;
import android.os.UserHandle;
import android.os.WorkSource;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.ActivityStatsTechSpecificInfo;
import android.telephony.Annotation;
import android.telephony.CellSignalStrength;
import android.telephony.DataConnectionRealTimeInfo;
@@ -58,8 +61,10 @@
import org.mockito.Mock;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.function.IntConsumer;
@@ -1322,7 +1327,7 @@
}
}
- final ModemAndBatteryState state = new ModemAndBatteryState(bi, null);
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, null, null);
IntConsumer incrementTime = inc -> {
state.currentTimeMs += inc;
@@ -1469,32 +1474,16 @@
final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
for (int rat = 0; rat < ratCount; rat++) {
for (int freq = 0; freq < frequencyCount; freq++) {
- if (rat != RADIO_ACCESS_TECHNOLOGY_NR
- && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
- // Only the NR RAT should have per frequency data.
- expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
- } else {
- expectedRxDurationsMs[rat][freq] = 0;
- }
expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
- expectedDurationsMs[rat][freq][txLvl] = 0;
-
- if (rat != RADIO_ACCESS_TECHNOLOGY_NR
- && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
- // Only the NR RAT should have per frequency data.
- expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
- } else {
- expectedTxDurationsMs[rat][freq][txLvl] = 0;
- }
expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
}
}
}
final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L);
- final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai);
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, null);
IntConsumer incrementTime = inc -> {
state.currentTimeMs += inc;
@@ -1711,6 +1700,288 @@
expectedTxDurationsMs, bi, state.currentTimeMs);
}
+ @SmallTest
+ public void testGetPerStateActiveRadioDurationMs_withSpecificInfoModemActivity() {
+ final MockClock clock = new MockClock(); // holds realtime and uptime in ms
+ final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
+ bi.setPowerProfile(mock(PowerProfile.class));
+ final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
+ final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
+ final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
+
+ List<ActivityStatsTechSpecificInfo> specificInfoList = new ArrayList();
+
+ final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+ final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
+ final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+ for (int rat = 0; rat < ratCount; rat++) {
+ for (int freq = 0; freq < frequencyCount; freq++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Initialize available specific Modem info
+ specificInfoList.add(
+ new ActivityStatsTechSpecificInfo(rat, freq, new int[txLevelCount], 0));
+ }
+ expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
+
+ for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+ expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
+ }
+ }
+ }
+
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UNKNOWN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.GERAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UTRAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.EUTRAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.CDMA2000,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.IWLAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_LOW, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_MID, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_HIGH, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_MMWAVE, new int[txLevelCount], 0));
+
+ final ActivityStatsTechSpecificInfo[] specificInfos = specificInfoList.toArray(
+ new ActivityStatsTechSpecificInfo[specificInfoList.size()]);
+ final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, specificInfos);
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, specificInfos);
+
+ IntConsumer incrementTime = inc -> {
+ state.currentTimeMs += inc;
+ clock.realtime = clock.uptime = state.currentTimeMs;
+
+ // If the device is not on battery, no timers should increment.
+ if (!state.onBattery) return;
+ // If the modem is not active, no timers should increment.
+ if (!state.modemActive) return;
+
+ final int currRat = state.currentRat;
+ final int currRant = state.currentRadioAccessNetworkType;
+ final int currFreqRange =
+ currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
+ int currSignalStrength = state.currentSignalStrengths.get(currRat);
+
+ expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+
+ // Evaluate the HAL provided time in states.
+ final ActivityStatsTechSpecificInfo info = state.getSpecificInfo(currRant,
+ currFreqRange);
+ switch (state.modemState) {
+ case SLEEP:
+ long sleepMs = state.modemActivityInfo.getSleepTimeMillis();
+ state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc);
+ break;
+ case IDLE:
+ long idleMs = state.modemActivityInfo.getIdleTimeMillis();
+ state.modemActivityInfo.setIdleTimeMillis(idleMs + inc);
+ break;
+ case RECEIVING:
+ long rxMs = info.getReceiveTimeMillis();
+ info.setReceiveTimeMillis(rxMs + inc);
+ expectedRxDurationsMs[currRat][currFreqRange] += inc;
+ break;
+ case TRANSMITTING:
+ int[] txMs = info.getTransmitTimeMillis().clone();
+ txMs[currSignalStrength] += inc;
+ info.setTransmitTimeMillis(txMs);
+ expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+ break;
+ }
+ };
+
+ state.setOnBattery(false);
+ state.setModemActive(false);
+ state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ AccessNetworkConstants.AccessNetworkType.UNKNOWN);
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // While not on battery, the timers should not increase.
+ state.setModemActive(true);
+ incrementTime.accept(100);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+ AccessNetworkConstants.AccessNetworkType.NGRAN);
+ incrementTime.accept(200);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+ CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+ incrementTime.accept(500);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
+ incrementTime.accept(300);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ AccessNetworkConstants.AccessNetworkType.EUTRAN);
+ incrementTime.accept(400);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
+ incrementTime.accept(500);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Data will now be available.
+ for (int rat = 0; rat < ratCount; rat++) {
+ for (int freq = 0; freq < frequencyCount; freq++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedRxDurationsMs[rat][freq] = 0;
+ }
+ for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedTxDurationsMs[rat][freq][txLvl] = 0;
+ }
+ }
+ }
+ }
+
+ // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
+ // start counting up.
+ state.setOnBattery(true);
+ state.noteModemControllerActivity();
+ incrementTime.accept(300);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(500);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(600);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+ // Changing LTE signal strength should be tracked.
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_POOR);
+ incrementTime.accept(300);
+ state.setModemState(ModemState.SLEEP);
+ incrementTime.accept(1000);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(700);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+ incrementTime.accept(800);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(222);
+ state.setModemState(ModemState.IDLE);
+ incrementTime.accept(111);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(7777);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+ incrementTime.accept(88);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(900);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_GREAT);
+ incrementTime.accept(123);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(333);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1000);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(555);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Change in the signal strength of nonactive RAT should not affect anything.
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ CellSignalStrength.SIGNAL_STRENGTH_POOR);
+ incrementTime.accept(631);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(321);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(99);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Changing to OTHER Rat should start tracking the poor signal strength.
+ state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ AccessNetworkConstants.AccessNetworkType.CDMA2000);
+ incrementTime.accept(1200);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Noting frequency change should not affect non NR Rat.
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
+ incrementTime.accept(444);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1300);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
+ state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+ AccessNetworkConstants.AccessNetworkType.NGRAN);
+ incrementTime.accept(1400);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Frequency changed to low.
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
+ incrementTime.accept(852);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(157);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1500);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Modem no longer active, should not be tracking any more.
+ state.setModemActive(false);
+ incrementTime.accept(1500);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+ }
+
private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
// Note that noteUidProcessStateLocked uses ActivityManager process states.
if (fgOn) {
@@ -1841,17 +2112,22 @@
public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
@BatteryStats.RadioAccessTechnology
public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER;
+ @AccessNetworkConstants.RadioAccessNetworkType
+ public int currentRadioAccessNetworkType = AccessNetworkConstants.AccessNetworkType.UNKNOWN;
@ServiceState.FrequencyRange
public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
public SparseIntArray currentSignalStrengths = new SparseIntArray();
public ModemState modemState = ModemState.SLEEP;
public ModemActivityInfo modemActivityInfo;
+ public ActivityStatsTechSpecificInfo[] specificInfo;
private final MockBatteryStatsImpl mBsi;
- ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai) {
+ ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai,
+ ActivityStatsTechSpecificInfo[] astsi) {
mBsi = bsi;
modemActivityInfo = mai;
+ specificInfo = astsi;
}
void setOnBattery(boolean onBattery) {
@@ -1871,6 +2147,13 @@
}
void setRatType(@Annotation.NetworkType int dataType,
+ @BatteryStats.RadioAccessTechnology int rat,
+ @AccessNetworkConstants.RadioAccessNetworkType int halDataType) {
+ currentRadioAccessNetworkType = halDataType;
+ setRatType(dataType, rat);
+ }
+
+ void setRatType(@Annotation.NetworkType int dataType,
@BatteryStats.RadioAccessTechnology int rat) {
currentNetworkDataType = dataType;
currentRat = rat;
@@ -1895,13 +2178,45 @@
modemState = state;
}
+ ActivityStatsTechSpecificInfo getSpecificInfo(@BatteryStats.RadioAccessTechnology int rat,
+ @ServiceState.FrequencyRange int frequency) {
+ if (specificInfo == null) return null;
+ for (ActivityStatsTechSpecificInfo info : specificInfo) {
+ if (info.getRat() == rat && info.getFrequencyRange() == frequency) {
+ return info;
+ }
+ }
+ return null;
+ }
+
void noteModemControllerActivity() {
if (modemActivityInfo == null) return;
modemActivityInfo.setTimestamp(currentTimeMs);
- ModemActivityInfo copy = new ModemActivityInfo(modemActivityInfo.getTimestampMillis(),
- modemActivityInfo.getSleepTimeMillis(), modemActivityInfo.getIdleTimeMillis(),
- modemActivityInfo.getTransmitTimeMillis().clone(),
- modemActivityInfo.getReceiveTimeMillis());
+ final ModemActivityInfo copy;
+ if (specificInfo == null) {
+ copy = new ModemActivityInfo(
+ modemActivityInfo.getTimestampMillis(),
+ modemActivityInfo.getSleepTimeMillis(),
+ modemActivityInfo.getIdleTimeMillis(),
+ modemActivityInfo.getTransmitTimeMillis().clone(),
+ modemActivityInfo.getReceiveTimeMillis());
+ } else {
+ // Deep copy specificInfo
+ final ActivityStatsTechSpecificInfo[] infoCopies =
+ new ActivityStatsTechSpecificInfo[specificInfo.length];
+ for (int i = 0; i < specificInfo.length; i++) {
+ final ActivityStatsTechSpecificInfo info = specificInfo[i];
+ infoCopies[i] = new ActivityStatsTechSpecificInfo(info.getRat(),
+ info.getFrequencyRange(), info.getTransmitTimeMillis().clone(),
+ (int) info.getReceiveTimeMillis());
+ }
+
+ copy = new ModemActivityInfo(
+ modemActivityInfo.getTimestampMillis(),
+ modemActivityInfo.getSleepTimeMillis(),
+ modemActivityInfo.getIdleTimeMillis(),
+ infoCopies);
+ }
mBsi.noteModemControllerActivity(copy, POWER_DATA_UNAVAILABLE,
currentTimeMs, currentTimeMs, mNetworkStatsManager);
}
diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java
index 730a9d1..2d0135a 100644
--- a/telephony/java/android/telephony/ModemActivityInfo.java
+++ b/telephony/java/android/telephony/ModemActivityInfo.java
@@ -383,8 +383,6 @@
* activity.
*/
public @NonNull ModemActivityInfo getDelta(@NonNull ModemActivityInfo other) {
- int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
-
ActivityStatsTechSpecificInfo[] mDeltaSpecificInfo;
mDeltaSpecificInfo = new ActivityStatsTechSpecificInfo[other.getSpecificInfoLength()];
@@ -399,6 +397,7 @@
if (other.mActivityStatsTechSpecificInfo[i].getFrequencyRange()
== mActivityStatsTechSpecificInfo[j].getFrequencyRange()) {
int freq = mActivityStatsTechSpecificInfo[j].getFrequencyRange();
+ int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
txTimeMs[lvl] =
(int) (other.getTransmitDurationMillisAtPowerLevel(
@@ -416,6 +415,7 @@
- getReceiveTimeMillis(rat, freq)));
}
} else {
+ int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
txTimeMs[lvl] =
(int) (other.getTransmitDurationMillisAtPowerLevel(lvl, rat)