Merge "Rate limit BatteryStats' ModemActivityInfo querying"
This commit is contained in:
committed by
Android (Google) Code Review
commit
c14454d6e0
@@ -1331,6 +1331,13 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
LongSamplingCounter mMobileRadioActiveUnknownTime;
|
||||
LongSamplingCounter mMobileRadioActiveUnknownCount;
|
||||
|
||||
/**
|
||||
* The soonest the Mobile Radio stats can be updated due to a mobile radio power state change
|
||||
* after it was last updated.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected static final long MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS = 1000 * 60 * 10;
|
||||
|
||||
int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
|
||||
|
||||
@GuardedBy("this")
|
||||
@@ -5531,6 +5538,15 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
} else {
|
||||
mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
|
||||
mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
|
||||
|
||||
if (mLastModemActivityInfo != null) {
|
||||
if (elapsedRealtimeMs < mLastModemActivityInfo.getTimestampMillis()
|
||||
+ MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS) {
|
||||
// Modem Activity info has been collected recently, don't bother
|
||||
// triggering another update.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Tell the caller to collect radio network/power stats.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import android.telephony.DataConnectionRealTimeInfo;
|
||||
import android.telephony.ModemActivityInfo;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.util.MutableInt;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.SparseLongArray;
|
||||
@@ -83,6 +84,7 @@ import java.util.function.IntConsumer;
|
||||
* com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
|
||||
*/
|
||||
public class BatteryStatsNoteTest extends TestCase {
|
||||
private static final String TAG = BatteryStatsNoteTest.class.getSimpleName();
|
||||
|
||||
private static final int UID = 10500;
|
||||
private static final int ISOLATED_APP_ID = Process.FIRST_ISOLATED_UID + 23;
|
||||
@@ -2030,6 +2032,113 @@ public class BatteryStatsNoteTest extends TestCase {
|
||||
noRadioProcFlags, lastProcStateChangeFlags.value);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNoteMobileRadioPowerStateLocked() {
|
||||
long curr;
|
||||
boolean update;
|
||||
final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
|
||||
final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
bi.setOnBatteryInternal(true);
|
||||
|
||||
// Note mobile radio is on.
|
||||
curr = 1000L * (clocks.realtime = clocks.uptime = 1001);
|
||||
bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
|
||||
UID);
|
||||
|
||||
// Note mobile radio is still on.
|
||||
curr = 1000L * (clocks.realtime = clocks.uptime = 2001);
|
||||
update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH,
|
||||
curr, UID);
|
||||
assertFalse(
|
||||
"noteMobileRadioPowerStateLocked should not request an update when the power "
|
||||
+ "state does not change from HIGH.",
|
||||
update);
|
||||
|
||||
// Note mobile radio is off.
|
||||
curr = 1000L * (clocks.realtime = clocks.uptime = 3001);
|
||||
update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
|
||||
curr, UID);
|
||||
assertTrue(
|
||||
"noteMobileRadioPowerStateLocked should request an update when the power state "
|
||||
+ "changes from HIGH to LOW.",
|
||||
update);
|
||||
|
||||
// Note mobile radio is still off.
|
||||
curr = 1000L * (clocks.realtime = clocks.uptime = 4001);
|
||||
update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
|
||||
curr, UID);
|
||||
assertFalse(
|
||||
"noteMobileRadioPowerStateLocked should not request an update when the power "
|
||||
+ "state does not change from LOW.",
|
||||
update);
|
||||
|
||||
// Note mobile radio is on.
|
||||
curr = 1000L * (clocks.realtime = clocks.uptime = 5001);
|
||||
update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH,
|
||||
curr, UID);
|
||||
assertFalse(
|
||||
"noteMobileRadioPowerStateLocked should not request an update when the power "
|
||||
+ "state changes from LOW to HIGH.",
|
||||
update);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNoteMobileRadioPowerStateLocked_rateLimited() {
|
||||
long curr;
|
||||
boolean update;
|
||||
final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
|
||||
final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
bi.setPowerProfile(mock(PowerProfile.class));
|
||||
|
||||
final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
|
||||
final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L);
|
||||
|
||||
final long rateLimit = bi.getMobileRadioPowerStateUpdateRateLimit();
|
||||
if (rateLimit < 0) {
|
||||
Log.w(TAG, "Skipping testNoteMobileRadioPowerStateLocked_rateLimited, rateLimit = "
|
||||
+ rateLimit);
|
||||
return;
|
||||
}
|
||||
bi.setOnBatteryInternal(true);
|
||||
|
||||
// Note mobile radio is on.
|
||||
curr = 1000L * (clocks.realtime = clocks.uptime = 1001);
|
||||
bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
|
||||
UID);
|
||||
|
||||
clocks.realtime = clocks.uptime = 2001;
|
||||
mai.setTimestamp(clocks.realtime);
|
||||
bi.noteModemControllerActivity(mai, POWER_DATA_UNAVAILABLE,
|
||||
clocks.realtime, clocks.uptime, mNetworkStatsManager);
|
||||
|
||||
// Note mobile radio is off within the rate limit duration.
|
||||
clocks.realtime = clocks.uptime = clocks.realtime + (long) (rateLimit * 0.7);
|
||||
curr = 1000L * clocks.realtime;
|
||||
update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
|
||||
curr, UID);
|
||||
assertFalse(
|
||||
"noteMobileRadioPowerStateLocked should not request an update when the power "
|
||||
+ "state so soon after a noteModemControllerActivity",
|
||||
update);
|
||||
|
||||
// Note mobile radio is on.
|
||||
clocks.realtime = clocks.uptime = clocks.realtime + (long) (rateLimit * 0.7);
|
||||
curr = 1000L * clocks.realtime;
|
||||
bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
|
||||
UID);
|
||||
|
||||
// Note mobile radio is off much later
|
||||
clocks.realtime = clocks.uptime = clocks.realtime + rateLimit;
|
||||
curr = 1000L * clocks.realtime;
|
||||
update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
|
||||
curr, UID);
|
||||
assertTrue(
|
||||
"noteMobileRadioPowerStateLocked should request an update when the power state "
|
||||
+ "changes from HIGH to LOW much later after a "
|
||||
+ "noteModemControllerActivity.",
|
||||
update);
|
||||
}
|
||||
|
||||
private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
|
||||
// Note that noteUidProcessStateLocked uses ActivityManager process states.
|
||||
if (fgOn) {
|
||||
|
||||
@@ -113,6 +113,10 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
|
||||
return getUidStatsLocked(uid).mOnBatteryScreenOffBackgroundTimeBase;
|
||||
}
|
||||
|
||||
public long getMobileRadioPowerStateUpdateRateLimit() {
|
||||
return MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS;
|
||||
}
|
||||
|
||||
public MockBatteryStatsImpl setNetworkStats(NetworkStats networkStats) {
|
||||
mNetworkStats = networkStats;
|
||||
return this;
|
||||
|
||||
Reference in New Issue
Block a user