Rate limit battery external stats collection in takeUidSnapshot(s).
Bug: 74146897
Test: atest cts/tests/tests/os/src/android/os/health/cts/SystemHealthManagerTest.java
Test: atest core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
Change-Id: I2e01146718c3ce65d230308097622b958cb2897a
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c5fc067..6b6e14f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10775,6 +10775,7 @@
* track_cpu_active_cluster_time (boolean)
* read_binary_cpu_time (boolean)
* proc_state_cpu_times_read_delay_ms (long)
+ * external_stats_collection_rate_limit_ms (long)
* </pre>
*
* <p>
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5da3874..d18faa7 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -13261,18 +13261,23 @@
= "kernel_uid_readers_throttle_time";
public static final String KEY_UID_REMOVE_DELAY_MS
= "uid_remove_delay_ms";
+ public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS
+ = "external_stats_collection_rate_limit_ms";
private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true;
private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000;
private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 10_000;
private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L;
+ private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000;
public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE;
public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME;
public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS;
public long KERNEL_UID_READERS_THROTTLE_TIME = DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME;
public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS;
+ public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS
+ = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -13318,6 +13323,9 @@
DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME));
updateUidRemoveDelay(
mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS));
+ EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong(
+ KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS,
+ DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS);
}
}
@@ -13367,6 +13375,14 @@
pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS);
pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("=");
pw.println(KERNEL_UID_READERS_THROTTLE_TIME);
+ pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("=");
+ pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS);
+ }
+ }
+
+ public long getExternalStatsCollectionRateLimitMs() {
+ synchronized (this) {
+ return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS;
}
}
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 2291e44..87194bc 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -117,6 +117,13 @@
private WifiActivityEnergyInfo mLastInfo =
new WifiActivityEnergyInfo(0, 0, 0, new long[]{0}, 0, 0, 0, 0);
+ /**
+ * Timestamp at which all external stats were last collected in
+ * {@link SystemClock#elapsedRealtime()} time base.
+ */
+ @GuardedBy("this")
+ private long mLastCollectionTimeStamp;
+
BatteryExternalStatsWorker(Context context, BatteryStatsImpl stats) {
mContext = context;
mStats = stats;
@@ -259,6 +266,12 @@
return mCurrentFuture;
}
+ long getLastCollectionTimeStamp() {
+ synchronized (this) {
+ return mLastCollectionTimeStamp;
+ }
+ }
+
private final Runnable mSyncTask = new Runnable() {
@Override
public void run() {
@@ -312,6 +325,10 @@
} catch (Exception e) {
Slog.wtf(TAG, "Error updating external stats: ", e);
}
+
+ synchronized (BatteryExternalStatsWorker.this) {
+ mLastCollectionTimeStamp = SystemClock.elapsedRealtime();
+ }
}
};
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 9c2b1a5..0c328a8 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1541,7 +1541,9 @@
}
long ident = Binder.clearCallingIdentity();
try {
- syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
+ if (shouldCollectExternalStats()) {
+ syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
+ }
synchronized (mStats) {
return getHealthStatsForUidLocked(requestUid);
}
@@ -1565,7 +1567,9 @@
long ident = Binder.clearCallingIdentity();
int i=-1;
try {
- syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
+ if (shouldCollectExternalStats()) {
+ syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
+ }
synchronized (mStats) {
final int N = requestUids.length;
final HealthStatsParceler[] results = new HealthStatsParceler[N];
@@ -1583,6 +1587,11 @@
}
}
+ private boolean shouldCollectExternalStats() {
+ return (SystemClock.elapsedRealtime() - mWorker.getLastCollectionTimeStamp())
+ > mStats.getExternalStatsCollectionRateLimitMs();
+ }
+
/**
* Returns whether the Binder.getCallingUid is the only thing in requestUids.
*/