summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java45
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java40
-rw-r--r--core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java4
-rw-r--r--services/core/java/com/android/server/am/BatteryExternalStatsWorker.java8
5 files changed, 88 insertions, 10 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1223271ad4c7..88935c0d648c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10495,6 +10495,7 @@ public final class Settings {
* track_cpu_times_by_proc_state (boolean)
* track_cpu_active_cluster_time (boolean)
* read_binary_cpu_time (boolean)
+ * proc_state_cpu_times_read_delay_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 6a56f452f3fe..e63351473767 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -230,6 +230,13 @@ public class BatteryStatsImpl extends BatteryStats {
@VisibleForTesting
protected final SparseIntArray mPendingUids = new SparseIntArray();
+ @GuardedBy("this")
+ private long mNumCpuTimeReads;
+ @GuardedBy("this")
+ private long mNumBatchedCpuTimeReads;
+ @GuardedBy("this")
+ private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis();
+
/** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */
private final RpmStats mTmpRpmStats = new RpmStats();
/** The soonest the RPM stats can be updated after it was last updated. */
@@ -485,7 +492,8 @@ public class BatteryStatsImpl extends BatteryStats {
Future<?> scheduleSync(String reason, int flags);
Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
- Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff);
+ Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff,
+ long delayMillis);
Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff);
Future<?> scheduleCpuSyncDueToSettingChange();
Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery,
@@ -9682,7 +9690,11 @@ public class BatteryStatsImpl extends BatteryStats {
if (mBsi.mPendingUids.size() == 0) {
mBsi.mExternalSync.scheduleReadProcStateCpuTimes(
mBsi.mOnBatteryTimeBase.isRunning(),
- mBsi.mOnBatteryScreenOffTimeBase.isRunning());
+ mBsi.mOnBatteryScreenOffTimeBase.isRunning(),
+ mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS);
+ mBsi.mNumCpuTimeReads++;
+ } else {
+ mBsi.mNumBatchedCpuTimeReads++;
}
if (mBsi.mPendingUids.indexOfKey(mUid) < 0
|| ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) {
@@ -13155,15 +13167,19 @@ public class BatteryStatsImpl extends BatteryStats {
= "track_cpu_active_cluster_time";
public static final String KEY_READ_BINARY_CPU_TIME
= "read_binary_cpu_time";
+ public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS
+ = "proc_state_cpu_times_read_delay_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 boolean DEFAULT_READ_BINARY_CPU_TIME = false;
+ private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_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;
// Not used right now.
public boolean READ_BINARY_CPU_TIME = DEFAULT_READ_BINARY_CPU_TIME;
+ public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -13203,7 +13219,9 @@ public class BatteryStatsImpl extends BatteryStats {
KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME);
READ_BINARY_CPU_TIME = mParser.getBoolean(
KEY_READ_BINARY_CPU_TIME, DEFAULT_READ_BINARY_CPU_TIME);
-
+ updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS,
+ mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS,
+ DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS));
}
}
@@ -13212,6 +13230,19 @@ public class BatteryStatsImpl extends BatteryStats {
if (isEnabled && !wasEnabled) {
mKernelSingleUidTimeReader.markDataAsStale(true);
mExternalSync.scheduleCpuSyncDueToSettingChange();
+
+ mNumCpuTimeReads = 0;
+ mNumBatchedCpuTimeReads = 0;
+ mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
+ }
+ }
+
+ private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) {
+ PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis;
+ if (oldDelayMillis != newDelayMillis) {
+ mNumCpuTimeReads = 0;
+ mNumBatchedCpuTimeReads = 0;
+ mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
}
}
@@ -13222,6 +13253,8 @@ public class BatteryStatsImpl extends BatteryStats {
pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME);
pw.print(KEY_READ_BINARY_CPU_TIME); pw.print("=");
pw.println(READ_BINARY_CPU_TIME);
+ pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("=");
+ pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS);
}
}
@@ -14931,5 +14964,11 @@ public class BatteryStatsImpl extends BatteryStats {
mCameraOnTimer.logState(pr, " ");
}
super.dumpLocked(context, pw, flags, reqUid, histStart);
+ pw.print("Total cpu time reads: ");
+ pw.println(mNumCpuTimeReads);
+ pw.print("Batched cpu time reads: ");
+ pw.println(mNumBatchedCpuTimeReads);
+ pw.print("Batching Duration (min): ");
+ pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000));
}
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
index d425dcc7f592..42c9139e04e2 100644
--- a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
@@ -25,6 +25,7 @@ import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING;
import static android.os.BatteryStats.Uid.UID_PROCESS_TYPES;
+import static com.android.internal.os.BatteryStatsImpl.Constants.KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS;
import static com.android.internal.os.BatteryStatsImpl.Constants.KEY_TRACK_CPU_TIMES_BY_PROC_STATE;
import static junit.framework.Assert.assertNotNull;
@@ -101,6 +102,11 @@ public class BstatsCpuTimesValidationTest {
private static final int WORK_DURATION_MS = 2000;
+ private static final String DESIRED_PROC_STATE_CPU_TIMES_DELAY = "0";
+
+ private static boolean sBatteryStatsConstsUpdated;
+ private static String sOriginalBatteryStatsConsts;
+
private static Context sContext;
private static UiDevice sUiDevice;
private static int sTestPkgUid;
@@ -117,13 +123,43 @@ public class BstatsCpuTimesValidationTest {
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
sTestPkgUid = sContext.getPackageManager().getPackageUid(TEST_PKG, 0);
checkCpuTimesAvailability();
+ if (sPerProcStateTimesAvailable && sCpuFreqTimesAvailable) {
+ setDesiredReadyDelay();
+ }
}
@AfterClass
public static void tearDownOnce() throws Exception {
+ if (sBatteryStatsConstsUpdated) {
+ Settings.Global.putString(sContext.getContentResolver(),
+ Settings.Global.BATTERY_STATS_CONSTANTS, sOriginalBatteryStatsConsts);
+ }
batteryReset();
}
+ private static void setDesiredReadyDelay() {
+ sOriginalBatteryStatsConsts = Settings.Global.getString(sContext.getContentResolver(),
+ Settings.Global.BATTERY_STATS_CONSTANTS);
+ String newBatteryStatsConstants;
+ final String newConstant = KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS
+ + "=" + DESIRED_PROC_STATE_CPU_TIMES_DELAY;
+ if (sOriginalBatteryStatsConsts == null || "null".equals(sOriginalBatteryStatsConsts)) {
+ // battery_stats_constants is initially empty, so just assign the desired value.
+ newBatteryStatsConstants = newConstant;
+ } else if (sOriginalBatteryStatsConsts.contains(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS)) {
+ // battery_stats_constants contains delay duration, so replace it
+ // with the desired value.
+ newBatteryStatsConstants = sOriginalBatteryStatsConsts.replaceAll(
+ KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS + "=\\d+", newConstant);
+ } else {
+ // battery_stats_constants didn't contain any delay, so append the desired value.
+ newBatteryStatsConstants = sOriginalBatteryStatsConsts + "," + newConstant;
+ }
+ Settings.Global.putString(sContext.getContentResolver(),
+ Settings.Global.BATTERY_STATS_CONSTANTS, newBatteryStatsConstants);
+ sBatteryStatsConstsUpdated = true;
+ }
+
// Checks cpu freq times of system uid as an indication of whether /proc/uid_time_in_state
// and /proc/uid/<uid>/time_in_state kernel nodes are available.
private static void checkCpuTimesAvailability() throws Exception {
@@ -132,9 +168,9 @@ public class BstatsCpuTimesValidationTest {
batteryOff();
final long[] totalCpuTimes = getAllCpuFreqTimes(Process.SYSTEM_UID);
sCpuFreqTimesAvailable = totalCpuTimes != null;
- final long[] fgSvcCpuTimes = getAllCpuFreqTimes(Process.SYSTEM_UID,
+ final long[] fgCpuTimes = getAllCpuFreqTimes(Process.SYSTEM_UID,
PROCESS_STATE_FOREGROUND);
- sPerProcStateTimesAvailable = fgSvcCpuTimes != null;
+ sPerProcStateTimesAvailable = fgCpuTimes != null;
}
@Test
diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
index cb05253c6f57..6d5c7e7749e8 100644
--- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
+++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
@@ -160,8 +160,8 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
}
@Override
- public Future<?> scheduleReadProcStateCpuTimes(
- boolean onBattery, boolean onBatteryScreenOff) {
+ public Future<?> scheduleReadProcStateCpuTimes(boolean onBattery,
+ boolean onBatteryScreenOff, long delayMillis) {
return null;
}
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index fba03774e5d9..1f101814d294 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -139,7 +139,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
}
@Override
- public Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) {
+ public Future<?> scheduleReadProcStateCpuTimes(
+ boolean onBattery, boolean onBatteryScreenOff, long delayMillis) {
synchronized (mStats) {
if (!mStats.trackPerProcStateCpuTimes()) {
return null;
@@ -147,9 +148,10 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
}
synchronized (BatteryExternalStatsWorker.this) {
if (!mExecutorService.isShutdown()) {
- return mExecutorService.submit(PooledLambda.obtainRunnable(
+ return mExecutorService.schedule(PooledLambda.obtainRunnable(
BatteryStatsImpl::updateProcStateCpuTimes,
- mStats, onBattery, onBatteryScreenOff).recycleOnUse());
+ mStats, onBattery, onBatteryScreenOff).recycleOnUse(),
+ delayMillis, TimeUnit.MILLISECONDS);
}
}
return null;