Ignore the first modem activity when system_server start

Don't count up the first reported modem activity as the
modem power stats updates to battery stats.

Bug: 283337636
Test: atest BatteryStatsNoteTest MobileRadioPowerCalculatorTest
Change-Id: I5894eb70b9b014bea831b5ea3d00e5405eae59ac
This commit is contained in:
Xin Guan
2023-06-23 14:23:13 +00:00
parent 172728297b
commit 0870ea9217
3 changed files with 168 additions and 1 deletions

View File

@@ -12159,7 +12159,8 @@ public class BatteryStatsImpl extends BatteryStats {
if (DEBUG_ENERGY) {
Slog.d(TAG, "Updating mobile radio stats with " + activityInfo);
}
ModemActivityInfo deltaInfo = mLastModemActivityInfo == null ? activityInfo
ModemActivityInfo deltaInfo = mLastModemActivityInfo == null
? (activityInfo == null ? null : activityInfo.getDelta(activityInfo))
: mLastModemActivityInfo.getDelta(activityInfo);
mLastModemActivityInfo = activityInfo;

View File

@@ -1456,6 +1456,148 @@ public class BatteryStatsNoteTest extends TestCase {
expectedTxDurationsMs, bi, state.currentTimeMs);
}
@SmallTest
public void testGetPerStateActiveRadioDurationMs_initialModemActivity() {
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) {
// Only the NR RAT should have per frequency data.
expectedRxDurationsMs[rat][freq] = 0;
} else {
expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
}
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;
} else {
expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
}
}
}
}
// The first modem activity pulled from modem with activity stats for each RATs.
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.UNKNOWN,
ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 101));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.GERAN,
ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 202));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.UTRAN,
ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 303));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.EUTRAN,
ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[]{3, 9, 133, 48, 218}, 404));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.CDMA2000,
ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 505));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.IWLAN,
ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 606));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.NGRAN,
ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 707));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.NGRAN,
ServiceState.FREQUENCY_RANGE_LOW, new int[txLevelCount], 808));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.NGRAN,
ServiceState.FREQUENCY_RANGE_MID, new int[txLevelCount], 909));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.NGRAN,
ServiceState.FREQUENCY_RANGE_HIGH, new int[txLevelCount], 1010));
specificInfoList.add(new ActivityStatsTechSpecificInfo(
AccessNetworkConstants.AccessNetworkType.NGRAN,
ServiceState.FREQUENCY_RANGE_MMWAVE, new int[txLevelCount], 1111));
final ActivityStatsTechSpecificInfo[] specificInfos = specificInfoList.toArray(
new ActivityStatsTechSpecificInfo[specificInfoList.size()]);
final ModemActivityInfo mai = new ModemActivityInfo(0L, 2002L, 3003L, specificInfos);
final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, specificInfos);
IntConsumer incrementTime = inc -> {
state.currentTimeMs += inc;
clock.realtime = clock.uptime = state.currentTimeMs;
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);
if (state.modemActive) {
// Don't count the duration if the modem is not active
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;
}
};
// On battery, but the modem is not active
bi.updateTimeBasesLocked(true, Display.STATE_OFF, state.currentTimeMs * 1000,
state.currentTimeMs * 1000);
bi.setOnBatteryInternal(true);
state.noteModemControllerActivity();
// Ensure the first modem activity should not be counted up.
checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
expectedTxDurationsMs, bi, state.currentTimeMs);
// Start counting.
state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
AccessNetworkConstants.AccessNetworkType.NGRAN);
// Frequency changed to low.
state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
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);
}
@SmallTest
public void testGetPerStateActiveRadioDurationMs_withModemActivity() {
final MockClock clock = new MockClock(); // holds realtime and uptime in ms

View File

@@ -76,6 +76,9 @@ public class MobileRadioPowerCalculatorTest {
.initMeasuredEnergyStatsLocked();
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
// The first ModemActivityInfo doesn't count up.
setInitialEmptyModemActivityInfo(stats);
// Scan for a cell
stats.notePhoneStateLocked(ServiceState.STATE_OUT_OF_SERVICE,
TelephonyManager.SIM_STATE_READY,
@@ -193,6 +196,9 @@ public class MobileRadioPowerCalculatorTest {
.initMeasuredEnergyStatsLocked();
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
// The first ModemActivityInfo doesn't count up.
setInitialEmptyModemActivityInfo(stats);
// Scan for a cell
stats.notePhoneStateLocked(ServiceState.STATE_OUT_OF_SERVICE,
TelephonyManager.SIM_STATE_READY,
@@ -347,6 +353,9 @@ public class MobileRadioPowerCalculatorTest {
.initMeasuredEnergyStatsLocked();
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
// The first ModemActivityInfo doesn't count up.
setInitialEmptyModemActivityInfo(stats);
// Scan for a cell
stats.notePhoneStateLocked(ServiceState.STATE_OUT_OF_SERVICE,
TelephonyManager.SIM_STATE_READY,
@@ -583,6 +592,9 @@ public class MobileRadioPowerCalculatorTest {
.initMeasuredEnergyStatsLocked();
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
// The first ModemActivityInfo doesn't count up.
setInitialEmptyModemActivityInfo(stats);
// Scan for a cell
stats.notePhoneStateLocked(ServiceState.STATE_OUT_OF_SERVICE,
TelephonyManager.SIM_STATE_READY,
@@ -660,6 +672,9 @@ public class MobileRadioPowerCalculatorTest {
.initMeasuredEnergyStatsLocked();
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
// The first ModemActivityInfo doesn't count up.
setInitialEmptyModemActivityInfo(stats);
stats.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, 0, -1,
0, 0);
@@ -841,6 +856,9 @@ public class MobileRadioPowerCalculatorTest {
.initMeasuredEnergyStatsLocked();
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
// The first ModemActivityInfo doesn't count up.
setInitialEmptyModemActivityInfo(stats);
stats.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, 0, -1,
0, 0);
@@ -1023,4 +1041,10 @@ public class MobileRadioPowerCalculatorTest {
assertThat(uidConsumer.getConsumedPower(background)).isWithin(PRECISION).of(2.08130);
assertThat(uidConsumer.getConsumedPower(fgs)).isWithin(PRECISION).of(0);
}
public void setInitialEmptyModemActivityInfo(BatteryStatsImpl stats) {
// Initial empty ModemActivityInfo.
final ModemActivityInfo emptyMai = new ModemActivityInfo(0L, 0L, 0L, new int[5], 0L);
stats.noteModemControllerActivity(emptyMai, 0, 0, 0, mNetworkStatsManager);
}
}