Merge "Rate limit BatteryStats' ModemActivityInfo querying" into tm-qpr-dev am: c3ea7bd98c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20227643 Change-Id: Ia513d7975da9a105d367afc778043e0a921b3126 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
committed by
Automerger Merge Worker
commit
d6a834dddc
@@ -1348,6 +1348,13 @@ public class BatteryStatsImpl extends BatteryStats {
|
|||||||
LongSamplingCounter mMobileRadioActiveUnknownTime;
|
LongSamplingCounter mMobileRadioActiveUnknownTime;
|
||||||
LongSamplingCounter mMobileRadioActiveUnknownCount;
|
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;
|
int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
@@ -6282,6 +6289,15 @@ public class BatteryStatsImpl extends BatteryStats {
|
|||||||
} else {
|
} else {
|
||||||
mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
|
mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
|
||||||
mMobileRadioActivePerAppTimer.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.
|
// Tell the caller to collect radio network/power stats.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import android.telephony.DataConnectionRealTimeInfo;
|
|||||||
import android.telephony.ModemActivityInfo;
|
import android.telephony.ModemActivityInfo;
|
||||||
import android.telephony.ServiceState;
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.MutableInt;
|
import android.util.MutableInt;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.util.SparseLongArray;
|
import android.util.SparseLongArray;
|
||||||
@@ -82,6 +83,7 @@ import java.util.function.IntConsumer;
|
|||||||
* com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
|
* com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
|
||||||
*/
|
*/
|
||||||
public class BatteryStatsNoteTest extends TestCase {
|
public class BatteryStatsNoteTest extends TestCase {
|
||||||
|
private static final String TAG = BatteryStatsNoteTest.class.getSimpleName();
|
||||||
|
|
||||||
private static final int UID = 10500;
|
private static final int UID = 10500;
|
||||||
private static final int ISOLATED_APP_ID = Process.FIRST_ISOLATED_UID + 23;
|
private static final int ISOLATED_APP_ID = Process.FIRST_ISOLATED_UID + 23;
|
||||||
@@ -2031,6 +2033,115 @@ public class BatteryStatsNoteTest extends TestCase {
|
|||||||
noRadioProcFlags, lastProcStateChangeFlags.value);
|
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) {
|
private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
|
||||||
// Note that noteUidProcessStateLocked uses ActivityManager process states.
|
// Note that noteUidProcessStateLocked uses ActivityManager process states.
|
||||||
if (fgOn) {
|
if (fgOn) {
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
|
|||||||
return getUidStatsLocked(uid).mOnBatteryScreenOffBackgroundTimeBase;
|
return getUidStatsLocked(uid).mOnBatteryScreenOffBackgroundTimeBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getMobileRadioPowerStateUpdateRateLimit() {
|
||||||
|
return MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS;
|
||||||
|
}
|
||||||
|
|
||||||
public MockBatteryStatsImpl setNetworkStats(NetworkStats networkStats) {
|
public MockBatteryStatsImpl setNetworkStats(NetworkStats networkStats) {
|
||||||
mNetworkStats = networkStats;
|
mNetworkStats = networkStats;
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
Reference in New Issue
Block a user