summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java105
-rw-r--r--core/java/com/android/internal/os/KernelCpuProcReader.java162
-rw-r--r--core/java/com/android/internal/os/KernelCpuUidTimeReader.java3
-rw-r--r--core/java/com/android/internal/os/KernelSingleUidTimeReader.java10
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java179
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java239
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java296
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuTimeReader.java213
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java60
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java316
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java5
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java199
-rw-r--r--core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java3
-rw-r--r--core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java260
-rw-r--r--core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java326
-rw-r--r--core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java331
-rw-r--r--core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java32
-rw-r--r--services/core/java/com/android/server/stats/StatsCompanionService.java39
19 files changed, 272 insertions, 2510 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 17cc6afcd8f0..534361e13c7d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -87,6 +87,10 @@ import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.location.gnssmetrics.GnssMetrics;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
@@ -187,18 +191,19 @@ public class BatteryStatsImpl extends BatteryStats {
private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
@VisibleForTesting
- protected KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
+ protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader =
+ new KernelCpuUidUserSysTimeReader(true);
@VisibleForTesting
protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
@VisibleForTesting
- protected KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader =
- new KernelUidCpuFreqTimeReader();
+ protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader =
+ new KernelCpuUidFreqTimeReader(true);
@VisibleForTesting
- protected KernelUidCpuActiveTimeReader mKernelUidCpuActiveTimeReader =
- new KernelUidCpuActiveTimeReader();
+ protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader =
+ new KernelCpuUidActiveTimeReader(true);
@VisibleForTesting
- protected KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader =
- new KernelUidCpuClusterTimeReader();
+ protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader =
+ new KernelCpuUidClusterTimeReader(true);
@VisibleForTesting
protected KernelSingleUidTimeReader mKernelSingleUidTimeReader;
@@ -248,9 +253,9 @@ public class BatteryStatsImpl extends BatteryStats {
/** Last time that RPM stats were updated by updateRpmStatsLocked. */
private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS;
/**
- * Use a queue to delay removing UIDs from {@link KernelUidCpuTimeReader},
- * {@link KernelUidCpuActiveTimeReader}, {@link KernelUidCpuClusterTimeReader},
- * {@link KernelUidCpuFreqTimeReader} and from the Kernel.
+ * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader},
+ * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader},
+ * {@link KernelCpuUidFreqTimeReader} and from the Kernel.
*
* Isolated and invalid UID info must be removed to conserve memory. However, STATSD and
* Batterystats both need to access UID cpu time. To resolve this race condition, only
@@ -281,22 +286,22 @@ public class BatteryStatsImpl extends BatteryStats {
void remove() {
if (startUid == endUid) {
- mKernelUidCpuTimeReader.removeUid(startUid);
- mKernelUidCpuFreqTimeReader.removeUid(startUid);
+ mCpuUidUserSysTimeReader.removeUid(startUid);
+ mCpuUidFreqTimeReader.removeUid(startUid);
if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
- mKernelUidCpuActiveTimeReader.removeUid(startUid);
- mKernelUidCpuClusterTimeReader.removeUid(startUid);
+ mCpuUidActiveTimeReader.removeUid(startUid);
+ mCpuUidClusterTimeReader.removeUid(startUid);
}
if (mKernelSingleUidTimeReader != null) {
mKernelSingleUidTimeReader.removeUid(startUid);
}
mNumUidsRemoved++;
} else if (startUid < endUid) {
- mKernelUidCpuFreqTimeReader.removeUidsInRange(startUid, endUid);
- mKernelUidCpuTimeReader.removeUidsInRange(startUid, endUid);
+ mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid);
+ mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid);
if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
- mKernelUidCpuActiveTimeReader.removeUidsInRange(startUid, endUid);
- mKernelUidCpuClusterTimeReader.removeUidsInRange(startUid, endUid);
+ mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid);
+ mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid);
}
if (mKernelSingleUidTimeReader != null) {
mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid);
@@ -496,7 +501,7 @@ public class BatteryStatsImpl extends BatteryStats {
}
final SparseArray<long[]> allUidCpuFreqTimesMs =
- mKernelUidCpuFreqTimeReader.getAllUidCpuFreqTimeMs();
+ mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs();
// If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to
// compute deltas since it might result in mis-attributing cpu times to wrong states.
if (mIsPerProcessStateCpuDataStale) {
@@ -553,16 +558,16 @@ public class BatteryStatsImpl extends BatteryStats {
return false;
}
if (mCpuFreqs == null) {
- mCpuFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile);
+ mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile);
}
if (mCpuFreqs != null) {
mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length);
} else {
- mPerProcStateCpuTimesAvailable = mKernelUidCpuFreqTimeReader.allUidTimesAvailable();
+ mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable();
return false;
}
}
- mPerProcStateCpuTimesAvailable = mKernelUidCpuFreqTimeReader.allUidTimesAvailable()
+ mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable()
&& mKernelSingleUidTimeReader.singleUidCpuTimesAvailable();
return true;
}
@@ -11926,7 +11931,7 @@ public class BatteryStatsImpl extends BatteryStats {
}
if (mCpuFreqs == null) {
- mCpuFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile);
+ mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile);
}
// Calculate the wakelocks we have to distribute amongst. The system is excluded as it is
@@ -11952,12 +11957,12 @@ public class BatteryStatsImpl extends BatteryStats {
// When the battery is not on, we don't attribute the cpu times to any timers but we still
// need to take the snapshots.
if (!onBattery) {
- mKernelUidCpuTimeReader.readDelta(null);
- mKernelUidCpuFreqTimeReader.readDelta(null);
+ mCpuUidUserSysTimeReader.readDelta(null);
+ mCpuUidFreqTimeReader.readDelta(null);
mNumAllUidCpuTimeReads += 2;
if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
- mKernelUidCpuActiveTimeReader.readDelta(null);
- mKernelUidCpuClusterTimeReader.readDelta(null);
+ mCpuUidActiveTimeReader.readDelta(null);
+ mCpuUidClusterTimeReader.readDelta(null);
mNumAllUidCpuTimeReads += 2;
}
for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) {
@@ -11967,7 +11972,7 @@ public class BatteryStatsImpl extends BatteryStats {
}
mUserInfoProvider.refreshUserIds();
- final SparseLongArray updatedUids = mKernelUidCpuFreqTimeReader.perClusterTimesAvailable()
+ final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable()
? null : new SparseLongArray();
readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery);
// updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu
@@ -12084,18 +12089,20 @@ public class BatteryStatsImpl extends BatteryStats {
final int numWakelocks = partialTimers == null ? 0 : partialTimers.size();
final long startTimeMs = mClocks.uptimeMillis();
- mKernelUidCpuTimeReader.readDelta((uid, userTimeUs, systemTimeUs) -> {
+ mCpuUidUserSysTimeReader.readDelta((uid, timesUs) -> {
+ long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
+
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
// This could happen if the isolated uid mapping was removed before that process
// was actually killed.
- mKernelUidCpuTimeReader.removeUid(uid);
+ mCpuUidUserSysTimeReader.removeUid(uid);
Slog.d(TAG, "Got readings for an isolated uid with no mapping: " + uid);
return;
}
if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
Slog.d(TAG, "Got readings for an invalid user's uid " + uid);
- mKernelUidCpuTimeReader.removeUid(uid);
+ mCpuUidUserSysTimeReader.removeUid(uid);
return;
}
final Uid u = getUidStatsLocked(uid);
@@ -12189,21 +12196,21 @@ public class BatteryStatsImpl extends BatteryStats {
public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers,
boolean onBattery, boolean onBatteryScreenOff) {
final boolean perClusterTimesAvailable =
- mKernelUidCpuFreqTimeReader.perClusterTimesAvailable();
+ mCpuUidFreqTimeReader.perClusterTimesAvailable();
final int numWakelocks = partialTimers == null ? 0 : partialTimers.size();
final int numClusters = mPowerProfile.getNumCpuClusters();
mWakeLockAllocationsUs = null;
final long startTimeMs = mClocks.uptimeMillis();
- mKernelUidCpuFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> {
+ mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> {
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
- mKernelUidCpuFreqTimeReader.removeUid(uid);
+ mCpuUidFreqTimeReader.removeUid(uid);
Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid);
return;
}
if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid);
- mKernelUidCpuFreqTimeReader.removeUid(uid);
+ mCpuUidFreqTimeReader.removeUid(uid);
return;
}
final Uid u = getUidStatsLocked(uid);
@@ -12307,16 +12314,16 @@ public class BatteryStatsImpl extends BatteryStats {
@VisibleForTesting
public void readKernelUidCpuActiveTimesLocked(boolean onBattery) {
final long startTimeMs = mClocks.uptimeMillis();
- mKernelUidCpuActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> {
+ mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> {
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
- mKernelUidCpuActiveTimeReader.removeUid(uid);
+ mCpuUidActiveTimeReader.removeUid(uid);
Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid);
return;
}
if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
Slog.w(TAG, "Got active times for an invalid user's uid " + uid);
- mKernelUidCpuActiveTimeReader.removeUid(uid);
+ mCpuUidActiveTimeReader.removeUid(uid);
return;
}
final Uid u = getUidStatsLocked(uid);
@@ -12336,16 +12343,16 @@ public class BatteryStatsImpl extends BatteryStats {
@VisibleForTesting
public void readKernelUidCpuClusterTimesLocked(boolean onBattery) {
final long startTimeMs = mClocks.uptimeMillis();
- mKernelUidCpuClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> {
+ mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> {
uid = mapUid(uid);
if (Process.isIsolated(uid)) {
- mKernelUidCpuClusterTimeReader.removeUid(uid);
+ mCpuUidClusterTimeReader.removeUid(uid);
Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid);
return;
}
if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid);
- mKernelUidCpuClusterTimeReader.removeUid(uid);
+ mCpuUidClusterTimeReader.removeUid(uid);
return;
}
final Uid u = getUidStatsLocked(uid);
@@ -13344,7 +13351,7 @@ public class BatteryStatsImpl extends BatteryStats {
private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = false;
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_KERNEL_UID_READERS_THROTTLE_TIME = 1_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;
private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000;
@@ -13357,7 +13364,9 @@ public class BatteryStatsImpl extends BatteryStats {
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;
+ /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an
+ * update when startObserving. */
+ public long 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;
@@ -13464,11 +13473,11 @@ public class BatteryStatsImpl extends BatteryStats {
private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) {
KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs;
if (oldTimeMs != newTimeMs) {
- mKernelUidCpuTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
- mKernelUidCpuFreqTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
- mKernelUidCpuActiveTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
- mKernelUidCpuClusterTimeReader
- .setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
+ mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME);
+ mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME);
+ mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME);
+ mCpuUidClusterTimeReader
+ .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME);
}
}
diff --git a/core/java/com/android/internal/os/KernelCpuProcReader.java b/core/java/com/android/internal/os/KernelCpuProcReader.java
deleted file mode 100644
index c233ea8e78b7..000000000000
--- a/core/java/com/android/internal/os/KernelCpuProcReader.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import android.os.StrictMode;
-import android.os.SystemClock;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-
-/**
- * Reads cpu time proc files with throttling (adjustable interval).
- *
- * KernelCpuProcReader is implemented as singletons for built-in kernel proc files. Get___Instance()
- * method will return corresponding reader instance. In order to prevent frequent GC,
- * KernelCpuProcReader reuses a {@link ByteBuffer} to store data read from proc files.
- *
- * A KernelCpuProcReader instance keeps an error counter. When the number of read errors within that
- * instance accumulates to 5, this instance will reject all further read requests.
- *
- * Each KernelCpuProcReader instance also has a throttler. Throttle interval can be adjusted via
- * {@link #setThrottleInterval(long)} method. Default throttle interval is 3000ms. If current
- * timestamp based on {@link SystemClock#elapsedRealtime()} is less than throttle interval from
- * the last read timestamp, {@link #readBytes()} will return previous result.
- *
- * A KernelCpuProcReader instance is thread-unsafe. Caller needs to hold a lock on this object while
- * accessing its instance methods or digesting the return values.
- */
-public class KernelCpuProcReader {
- private static final String TAG = "KernelCpuProcReader";
- private static final int ERROR_THRESHOLD = 5;
- // Throttle interval in milliseconds
- private static final long DEFAULT_THROTTLE_INTERVAL = 3000L;
- private static final int MAX_BUFFER_SIZE = 1024 * 1024;
- private static final String PROC_UID_FREQ_TIME = "/proc/uid_cpupower/time_in_state";
- private static final String PROC_UID_ACTIVE_TIME = "/proc/uid_cpupower/concurrent_active_time";
- private static final String PROC_UID_CLUSTER_TIME = "/proc/uid_cpupower/concurrent_policy_time";
-
- private static final KernelCpuProcReader mFreqTimeReader = new KernelCpuProcReader(
- PROC_UID_FREQ_TIME);
- private static final KernelCpuProcReader mActiveTimeReader = new KernelCpuProcReader(
- PROC_UID_ACTIVE_TIME);
- private static final KernelCpuProcReader mClusterTimeReader = new KernelCpuProcReader(
- PROC_UID_CLUSTER_TIME);
-
- public static KernelCpuProcReader getFreqTimeReaderInstance() {
- return mFreqTimeReader;
- }
-
- public static KernelCpuProcReader getActiveTimeReaderInstance() {
- return mActiveTimeReader;
- }
-
- public static KernelCpuProcReader getClusterTimeReaderInstance() {
- return mClusterTimeReader;
- }
-
- private int mErrors;
- private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
- private long mLastReadTime = Long.MIN_VALUE;
- private final Path mProc;
- private byte[] mBuffer = new byte[8 * 1024];
- private int mContentSize;
-
- @VisibleForTesting
- public KernelCpuProcReader(String procFile) {
- mProc = Paths.get(procFile);
- }
-
- /**
- * Reads all bytes from the corresponding proc file.
- *
- * If elapsed time since last call to this method is less than the throttle interval, it will
- * return previous result. When IOException accumulates to 5, it will always return null. This
- * method is thread-unsafe, so is the return value. Caller needs to hold a lock on this
- * object while calling this method and digesting its return value.
- *
- * @return a {@link ByteBuffer} containing all bytes from the proc file.
- */
- public ByteBuffer readBytes() {
- if (mErrors >= ERROR_THRESHOLD) {
- return null;
- }
- if (SystemClock.elapsedRealtime() < mLastReadTime + mThrottleInterval) {
- if (mContentSize > 0) {
- return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer()
- .order(ByteOrder.nativeOrder());
- }
- return null;
- }
- mLastReadTime = SystemClock.elapsedRealtime();
- mContentSize = 0;
- final int oldMask = StrictMode.allowThreadDiskReadsMask();
- try (InputStream in = Files.newInputStream(mProc)) {
- int numBytes = 0;
- int curr;
- while ((curr = in.read(mBuffer, numBytes, mBuffer.length - numBytes)) >= 0) {
- numBytes += curr;
- if (numBytes == mBuffer.length) {
- // Hit the limit. Resize mBuffer.
- if (mBuffer.length == MAX_BUFFER_SIZE) {
- mErrors++;
- Slog.e(TAG, "Proc file is too large: " + mProc);
- return null;
- }
- mBuffer = Arrays.copyOf(mBuffer,
- Math.min(mBuffer.length << 1, MAX_BUFFER_SIZE));
- }
- }
- mContentSize = numBytes;
- return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer()
- .order(ByteOrder.nativeOrder());
- } catch (NoSuchFileException | FileNotFoundException e) {
- // Happens when the kernel does not provide this file. Not a big issue. Just log it.
- mErrors++;
- Slog.w(TAG, "File not exist: " + mProc);
- } catch (IOException e) {
- mErrors++;
- Slog.e(TAG, "Error reading: " + mProc, e);
- } finally {
- StrictMode.setThreadPolicyMask(oldMask);
- }
- return null;
- }
-
- /**
- * Sets the throttle interval. Set to 0 will disable throttling. Thread-unsafe, holding a lock
- * on this object is recommended.
- *
- * @param throttleInterval throttle interval in milliseconds
- */
- public void setThrottleInterval(long throttleInterval) {
- if (throttleInterval >= 0) {
- mThrottleInterval = throttleInterval;
- }
- }
-}
diff --git a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
index 7021b5781347..e6d044f4722b 100644
--- a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
+++ b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
@@ -177,6 +177,9 @@ public abstract class KernelCpuUidTimeReader<T> {
* The file contains a monotonically increasing count of time for a single boot. This class
* maintains the previous results of a call to {@link #readDelta} in order to provide a proper
* delta.
+ *
+ * The second parameter of the callback is a long[] with 2 elements, [user time in us, system
+ * time in us].
*/
public static class KernelCpuUidUserSysTimeReader extends KernelCpuUidTimeReader<long[]> {
private static final String REMOVE_UID_PROC_FILE = "/proc/uid_cputime/remove_uid_range";
diff --git a/core/java/com/android/internal/os/KernelSingleUidTimeReader.java b/core/java/com/android/internal/os/KernelSingleUidTimeReader.java
index ad628524f443..3c43a11a8e9f 100644
--- a/core/java/com/android/internal/os/KernelSingleUidTimeReader.java
+++ b/core/java/com/android/internal/os/KernelSingleUidTimeReader.java
@@ -16,7 +16,6 @@
package com.android.internal.os;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
-import static com.android.internal.os.KernelUidCpuFreqTimeReader.UID_TIMES_PROC_FILE;
import android.annotation.NonNull;
import android.util.Slog;
@@ -34,11 +33,12 @@ import java.util.Arrays;
@VisibleForTesting(visibility = PACKAGE)
public class KernelSingleUidTimeReader {
- private final String TAG = KernelUidCpuFreqTimeReader.class.getName();
- private final boolean DBG = false;
+ private static final String TAG = KernelSingleUidTimeReader.class.getName();
+ private static final boolean DBG = false;
- private final String PROC_FILE_DIR = "/proc/uid/";
- private final String PROC_FILE_NAME = "/time_in_state";
+ private static final String PROC_FILE_DIR = "/proc/uid/";
+ private static final String PROC_FILE_NAME = "/time_in_state";
+ private static final String UID_TIMES_PROC_FILE = "/proc/uid_time_in_state";
@VisibleForTesting
public static final int TOTAL_READ_ERROR_COUNT = 5;
diff --git a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
deleted file mode 100644
index bd8a67a8bd0e..000000000000
--- a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import android.annotation.Nullable;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.util.function.Consumer;
-
-/**
- * Reads binary proc file /proc/uid_cpupower/concurrent_active_time and reports CPU active time to
- * BatteryStats to compute {@link PowerProfile#POWER_CPU_ACTIVE}.
- *
- * concurrent_active_time is an array of u32's in the following format:
- * [n, uid0, time0a, time0b, ..., time0n,
- * uid1, time1a, time1b, ..., time1n,
- * uid2, time2a, time2b, ..., time2n, etc.]
- * where n is the total number of cpus (num_possible_cpus)
- * ...
- * timeXn means the CPU time that a UID X spent running concurrently with n other processes.
- * The file contains a monotonically increasing count of time for a single boot. This class
- * maintains the previous results of a call to {@link #readDelta} in order to provide a
- * proper delta.
- *
- * This class uses a throttler to reject any {@link #readDelta} call within
- * {@link #mThrottleInterval}. This is different from the throttler in {@link KernelCpuProcReader},
- * which has a shorter throttle interval and returns cached result from last read when the request
- * is throttled.
- *
- * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
- * caller has its own view of delta.
- */
-public class KernelUidCpuActiveTimeReader extends
- KernelUidCpuTimeReaderBase<KernelUidCpuActiveTimeReader.Callback> {
- private static final String TAG = KernelUidCpuActiveTimeReader.class.getSimpleName();
-
- private final KernelCpuProcReader mProcReader;
- private SparseArray<Double> mLastUidCpuActiveTimeMs = new SparseArray<>();
- private int mCores;
-
- public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
- /**
- * Notifies when new data is available.
- *
- * @param uid uid int
- * @param cpuActiveTimeMs cpu active time spent by this uid in milliseconds
- */
- void onUidCpuActiveTime(int uid, long cpuActiveTimeMs);
- }
-
- public KernelUidCpuActiveTimeReader() {
- mProcReader = KernelCpuProcReader.getActiveTimeReaderInstance();
- }
-
- @VisibleForTesting
- public KernelUidCpuActiveTimeReader(KernelCpuProcReader procReader) {
- mProcReader = procReader;
- }
-
- @Override
- protected void readDeltaImpl(@Nullable Callback callback) {
- readImpl((buf) -> {
- int uid = buf.get();
- double activeTime = sumActiveTime(buf);
- if (activeTime > 0) {
- double delta = activeTime - mLastUidCpuActiveTimeMs.get(uid, 0.0);
- if (delta > 0) {
- mLastUidCpuActiveTimeMs.put(uid, activeTime);
- if (callback != null) {
- callback.onUidCpuActiveTime(uid, (long) delta);
- }
- } else if (delta < 0) {
- Slog.e(TAG, "Negative delta from active time proc: " + delta);
- }
- }
- });
- }
-
- public void readAbsolute(Callback callback) {
- readImpl((buf) -> {
- int uid = buf.get();
- double activeTime = sumActiveTime(buf);
- if (activeTime > 0) {
- callback.onUidCpuActiveTime(uid, (long) activeTime);
- }
- });
- }
-
- private double sumActiveTime(IntBuffer buffer) {
- double sum = 0;
- boolean corrupted = false;
- for (int j = 1; j <= mCores; j++) {
- int time = buffer.get();
- if (time < 0) {
- // Even if error happens, we still need to continue reading.
- // Buffer cannot be skipped.
- Slog.e(TAG, "Negative time from active time proc: " + time);
- corrupted = true;
- } else {
- sum += (double) time * 10 / j; // Unit is 10ms.
- }
- }
- return corrupted ? -1 : sum;
- }
-
- /**
- * readImpl accepts a callback to process the uid entry. readDeltaImpl needs to store the last
- * seen results while processing the buffer, while readAbsolute returns the absolute value read
- * from the buffer without storing. So readImpl contains the common logic of the two, leaving
- * the difference to a processUid function.
- *
- * @param processUid the callback function to process the uid entry in the buffer.
- */
- private void readImpl(Consumer<IntBuffer> processUid) {
- synchronized (mProcReader) {
- final ByteBuffer bytes = mProcReader.readBytes();
- if (bytes == null || bytes.remaining() <= 4) {
- // Error already logged in mProcReader.
- return;
- }
- if ((bytes.remaining() & 3) != 0) {
- Slog.wtf(TAG,
- "Cannot parse active time proc bytes to int: " + bytes.remaining());
- return;
- }
- final IntBuffer buf = bytes.asIntBuffer();
- final int cores = buf.get();
- if (mCores != 0 && cores != mCores) {
- Slog.wtf(TAG, "Cpu active time wrong # cores: " + cores);
- return;
- }
- mCores = cores;
- if (cores <= 0 || buf.remaining() % (cores + 1) != 0) {
- Slog.wtf(TAG,
- "Cpu active time format error: " + buf.remaining() + " / " + (cores
- + 1));
- return;
- }
- int numUids = buf.remaining() / (cores + 1);
- for (int i = 0; i < numUids; i++) {
- processUid.accept(buf);
- }
- if (DEBUG) {
- Slog.d(TAG, "Read uids: " + numUids);
- }
- }
- }
-
- public void removeUid(int uid) {
- mLastUidCpuActiveTimeMs.delete(uid);
- }
-
- public void removeUidsInRange(int startUid, int endUid) {
- mLastUidCpuActiveTimeMs.put(startUid, null);
- mLastUidCpuActiveTimeMs.put(endUid, null);
- final int firstIndex = mLastUidCpuActiveTimeMs.indexOfKey(startUid);
- final int lastIndex = mLastUidCpuActiveTimeMs.indexOfKey(endUid);
- mLastUidCpuActiveTimeMs.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
- }
-}
diff --git a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
deleted file mode 100644
index 3cbfaead4779..000000000000
--- a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import android.annotation.Nullable;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.util.function.Consumer;
-
-/**
- * Reads binary proc file /proc/uid_cpupower/concurrent_policy_time and reports CPU cluster times
- * to BatteryStats to compute cluster power. See
- * {@link PowerProfile#getAveragePowerForCpuCluster(int)}.
- *
- * concurrent_policy_time is an array of u32's in the following format:
- * [n, x0, ..., xn, uid0, time0a, time0b, ..., time0n,
- * uid1, time1a, time1b, ..., time1n,
- * uid2, time2a, time2b, ..., time2n, etc.]
- * where n is the number of policies
- * xi is the number cpus on a particular policy
- * Each uidX is followed by x0 time entries corresponding to the time UID X spent on cluster0
- * running concurrently with 0, 1, 2, ..., x0 - 1 other processes, then followed by x1, ..., xn
- * time entries.
- *
- * The file contains a monotonically increasing count of time for a single boot. This class
- * maintains the previous results of a call to {@link #readDelta} in order to provide a
- * proper delta.
- *
- * This class uses a throttler to reject any {@link #readDelta} call within
- * {@link #mThrottleInterval}. This is different from the throttler in {@link KernelCpuProcReader},
- * which has a shorter throttle interval and returns cached result from last read when the request
- * is throttled.
- *
- * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
- * caller has its own view of delta.
- */
-public class KernelUidCpuClusterTimeReader extends
- KernelUidCpuTimeReaderBase<KernelUidCpuClusterTimeReader.Callback> {
- private static final String TAG = KernelUidCpuClusterTimeReader.class.getSimpleName();
-
- private final KernelCpuProcReader mProcReader;
- private SparseArray<double[]> mLastUidPolicyTimeMs = new SparseArray<>();
-
- private int mNumClusters = -1;
- private int mNumCores;
- private int[] mNumCoresOnCluster;
-
- private double[] mCurTime; // Reuse to avoid GC.
- private long[] mDeltaTime; // Reuse to avoid GC.
- private long[] mCurTimeRounded; // Reuse to avoid GC.
-
- public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
- /**
- * Notifies when new data is available.
- *
- * @param uid uid int
- * @param cpuClusterTimeMs an array of times spent by this uid on corresponding clusters.
- * The array index is the cluster index.
- */
- void onUidCpuPolicyTime(int uid, long[] cpuClusterTimeMs);
- }
-
- public KernelUidCpuClusterTimeReader() {
- mProcReader = KernelCpuProcReader.getClusterTimeReaderInstance();
- }
-
- @VisibleForTesting
- public KernelUidCpuClusterTimeReader(KernelCpuProcReader procReader) {
- mProcReader = procReader;
- }
-
- @Override
- protected void readDeltaImpl(@Nullable Callback cb) {
- readImpl((buf) -> {
- int uid = buf.get();
- double[] lastTimes = mLastUidPolicyTimeMs.get(uid);
- if (lastTimes == null) {
- lastTimes = new double[mNumClusters];
- mLastUidPolicyTimeMs.put(uid, lastTimes);
- }
- if (!sumClusterTime(buf, mCurTime)) {
- return;
- }
- boolean valid = true;
- boolean notify = false;
- for (int i = 0; i < mNumClusters; i++) {
- mDeltaTime[i] = (long) (mCurTime[i] - lastTimes[i]);
- if (mDeltaTime[i] < 0) {
- Slog.e(TAG, "Negative delta from cluster time proc: " + mDeltaTime[i]);
- valid = false;
- }
- notify |= mDeltaTime[i] > 0;
- }
- if (notify && valid) {
- System.arraycopy(mCurTime, 0, lastTimes, 0, mNumClusters);
- if (cb != null) {
- cb.onUidCpuPolicyTime(uid, mDeltaTime);
- }
- }
- });
- }
-
- public void readAbsolute(Callback callback) {
- readImpl((buf) -> {
- int uid = buf.get();
- if (sumClusterTime(buf, mCurTime)) {
- for (int i = 0; i < mNumClusters; i++) {
- mCurTimeRounded[i] = (long) mCurTime[i];
- }
- callback.onUidCpuPolicyTime(uid, mCurTimeRounded);
- }
- });
- }
-
- private boolean sumClusterTime(IntBuffer buffer, double[] clusterTime) {
- boolean valid = true;
- for (int i = 0; i < mNumClusters; i++) {
- clusterTime[i] = 0;
- for (int j = 1; j <= mNumCoresOnCluster[i]; j++) {
- int time = buffer.get();
- if (time < 0) {
- Slog.e(TAG, "Negative time from cluster time proc: " + time);
- valid = false;
- }
- clusterTime[i] += (double) time * 10 / j; // Unit is 10ms.
- }
- }
- return valid;
- }
-
- /**
- * readImpl accepts a callback to process the uid entry. readDeltaImpl needs to store the last
- * seen results while processing the buffer, while readAbsolute returns the absolute value read
- * from the buffer without storing. So readImpl contains the common logic of the two, leaving
- * the difference to a processUid function.
- *
- * @param processUid the callback function to process the uid entry in the buffer.
- */
- private void readImpl(Consumer<IntBuffer> processUid) {
- synchronized (mProcReader) {
- ByteBuffer bytes = mProcReader.readBytes();
- if (bytes == null || bytes.remaining() <= 4) {
- // Error already logged in mProcReader.
- return;
- }
- if ((bytes.remaining() & 3) != 0) {
- Slog.wtf(TAG,
- "Cannot parse cluster time proc bytes to int: " + bytes.remaining());
- return;
- }
- IntBuffer buf = bytes.asIntBuffer();
- final int numClusters = buf.get();
- if (numClusters <= 0) {
- Slog.wtf(TAG, "Cluster time format error: " + numClusters);
- return;
- }
- if (mNumClusters == -1) {
- mNumClusters = numClusters;
- }
- if (buf.remaining() < numClusters) {
- Slog.wtf(TAG, "Too few data left in the buffer: " + buf.remaining());
- return;
- }
- if (mNumCores <= 0) {
- if (!readCoreInfo(buf, numClusters)) {
- return;
- }
- } else {
- buf.position(buf.position() + numClusters);
- }
-
- if (buf.remaining() % (mNumCores + 1) != 0) {
- Slog.wtf(TAG,
- "Cluster time format error: " + buf.remaining() + " / " + (mNumCores
- + 1));
- return;
- }
- int numUids = buf.remaining() / (mNumCores + 1);
-
- for (int i = 0; i < numUids; i++) {
- processUid.accept(buf);
- }
- if (DEBUG) {
- Slog.d(TAG, "Read uids: " + numUids);
- }
- }
- }
-
- // Returns if it has read valid info.
- private boolean readCoreInfo(IntBuffer buf, int numClusters) {
- int numCores = 0;
- int[] numCoresOnCluster = new int[numClusters];
- for (int i = 0; i < numClusters; i++) {
- numCoresOnCluster[i] = buf.get();
- numCores += numCoresOnCluster[i];
- }
- if (numCores <= 0) {
- Slog.e(TAG, "Invalid # cores from cluster time proc file: " + numCores);
- return false;
- }
- mNumCores = numCores;
- mNumCoresOnCluster = numCoresOnCluster;
- mCurTime = new double[numClusters];
- mDeltaTime = new long[numClusters];
- mCurTimeRounded = new long[numClusters];
- return true;
- }
-
- public void removeUid(int uid) {
- mLastUidPolicyTimeMs.delete(uid);
- }
-
- public void removeUidsInRange(int startUid, int endUid) {
- mLastUidPolicyTimeMs.put(startUid, null);
- mLastUidPolicyTimeMs.put(endUid, null);
- final int firstIndex = mLastUidPolicyTimeMs.indexOfKey(startUid);
- final int lastIndex = mLastUidPolicyTimeMs.indexOfKey(endUid);
- mLastUidPolicyTimeMs.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
- }
-}
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
deleted file mode 100644
index 5b46d0f29c20..000000000000
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.StrictMode;
-import android.util.IntArray;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.util.function.Consumer;
-
-/**
- * Reads /proc/uid_time_in_state which has the format:
- *
- * uid: [freq1] [freq2] [freq3] ...
- * [uid1]: [time in freq1] [time in freq2] [time in freq3] ...
- * [uid2]: [time in freq1] [time in freq2] [time in freq3] ...
- * ...
- *
- * Binary variation reads /proc/uid_cpupower/time_in_state in the following format:
- * [n, uid0, time0a, time0b, ..., time0n,
- * uid1, time1a, time1b, ..., time1n,
- * uid2, time2a, time2b, ..., time2n, etc.]
- * where n is the total number of frequencies.
- *
- * This provides the times a UID's processes spent executing at each different cpu frequency.
- * The file contains a monotonically increasing count of time for a single boot. This class
- * maintains the previous results of a call to {@link #readDelta} in order to provide a proper
- * delta.
- *
- * This class uses a throttler to reject any {@link #readDelta} call within
- * {@link #mThrottleInterval}. This is different from the throttler in {@link KernelCpuProcReader},
- * which has a shorter throttle interval and returns cached result from last read when the request
- * is throttled.
- *
- * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
- * caller has its own view of delta.
- */
-public class KernelUidCpuFreqTimeReader extends
- KernelUidCpuTimeReaderBase<KernelUidCpuFreqTimeReader.Callback> {
- private static final String TAG = KernelUidCpuFreqTimeReader.class.getSimpleName();
- static final String UID_TIMES_PROC_FILE = "/proc/uid_time_in_state";
-
- public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
- void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs);
- }
-
- private long[] mCpuFreqs;
- private long[] mCurTimes; // Reuse to prevent GC.
- private long[] mDeltaTimes; // Reuse to prevent GC.
- private int mCpuFreqsCount;
- private final KernelCpuProcReader mProcReader;
-
- private SparseArray<long[]> mLastUidCpuFreqTimeMs = new SparseArray<>();
-
- // We check the existence of proc file a few times (just in case it is not ready yet when we
- // start reading) and if it is not available, we simply ignore further read requests.
- private static final int TOTAL_READ_ERROR_COUNT = 5;
- private int mReadErrorCounter;
- private boolean mPerClusterTimesAvailable;
- private boolean mAllUidTimesAvailable = true;
-
- public KernelUidCpuFreqTimeReader() {
- mProcReader = KernelCpuProcReader.getFreqTimeReaderInstance();
- }
-
- @VisibleForTesting
- public KernelUidCpuFreqTimeReader(KernelCpuProcReader procReader) {
- mProcReader = procReader;
- }
-
- public boolean perClusterTimesAvailable() {
- return mPerClusterTimesAvailable;
- }
-
- public boolean allUidTimesAvailable() {
- return mAllUidTimesAvailable;
- }
-
- public SparseArray<long[]> getAllUidCpuFreqTimeMs() {
- return mLastUidCpuFreqTimeMs;
- }
-
- public long[] readFreqs(@NonNull PowerProfile powerProfile) {
- checkNotNull(powerProfile);
- if (mCpuFreqs != null) {
- // No need to read cpu freqs more than once.
- return mCpuFreqs;
- }
- if (!mAllUidTimesAvailable) {
- return null;
- }
- final int oldMask = StrictMode.allowThreadDiskReadsMask();
- try (BufferedReader reader = new BufferedReader(new FileReader(UID_TIMES_PROC_FILE))) {
- return readFreqs(reader, powerProfile);
- } catch (IOException e) {
- if (++mReadErrorCounter >= TOTAL_READ_ERROR_COUNT) {
- mAllUidTimesAvailable = false;
- }
- Slog.e(TAG, "Failed to read " + UID_TIMES_PROC_FILE + ": " + e);
- return null;
- } finally {
- StrictMode.setThreadPolicyMask(oldMask);
- }
- }
-
- @VisibleForTesting
- public long[] readFreqs(BufferedReader reader, PowerProfile powerProfile)
- throws IOException {
- final String line = reader.readLine();
- if (line == null) {
- return null;
- }
- final String[] freqStr = line.split(" ");
- // First item would be "uid: " which needs to be ignored.
- mCpuFreqsCount = freqStr.length - 1;
- mCpuFreqs = new long[mCpuFreqsCount];
- mCurTimes = new long[mCpuFreqsCount];
- mDeltaTimes = new long[mCpuFreqsCount];
- for (int i = 0; i < mCpuFreqsCount; ++i) {
- mCpuFreqs[i] = Long.parseLong(freqStr[i + 1], 10);
- }
-
- // Check if the freqs in the proc file correspond to per-cluster freqs.
- final IntArray numClusterFreqs = extractClusterInfoFromProcFileFreqs();
- final int numClusters = powerProfile.getNumCpuClusters();
- if (numClusterFreqs.size() == numClusters) {
- mPerClusterTimesAvailable = true;
- for (int i = 0; i < numClusters; ++i) {
- if (numClusterFreqs.get(i) != powerProfile.getNumSpeedStepsInCpuCluster(i)) {
- mPerClusterTimesAvailable = false;
- break;
- }
- }
- } else {
- mPerClusterTimesAvailable = false;
- }
- Slog.i(TAG, "mPerClusterTimesAvailable=" + mPerClusterTimesAvailable);
- return mCpuFreqs;
- }
-
- @Override
- @VisibleForTesting
- public void readDeltaImpl(@Nullable Callback callback) {
- if (mCpuFreqs == null) {
- return;
- }
- readImpl((buf) -> {
- int uid = buf.get();
- long[] lastTimes = mLastUidCpuFreqTimeMs.get(uid);
- if (lastTimes == null) {
- lastTimes = new long[mCpuFreqsCount];
- mLastUidCpuFreqTimeMs.put(uid, lastTimes);
- }
- if (!getFreqTimeForUid(buf, mCurTimes)) {
- return;
- }
- boolean notify = false;
- boolean valid = true;
- for (int i = 0; i < mCpuFreqsCount; i++) {
- mDeltaTimes[i] = mCurTimes[i] - lastTimes[i];
- if (mDeltaTimes[i] < 0) {
- Slog.e(TAG, "Negative delta from freq time proc: " + mDeltaTimes[i]);
- valid = false;
- }
- notify |= mDeltaTimes[i] > 0;
- }
- if (notify && valid) {
- System.arraycopy(mCurTimes, 0, lastTimes, 0, mCpuFreqsCount);
- if (callback != null) {
- callback.onUidCpuFreqTime(uid, mDeltaTimes);
- }
- }
- });
- }
-
- public void readAbsolute(Callback callback) {
- readImpl((buf) -> {
- int uid = buf.get();
- if (getFreqTimeForUid(buf, mCurTimes)) {
- callback.onUidCpuFreqTime(uid, mCurTimes);
- }
- });
- }
-
- private boolean getFreqTimeForUid(IntBuffer buffer, long[] freqTime) {
- boolean valid = true;
- for (int i = 0; i < mCpuFreqsCount; i++) {
- freqTime[i] = (long) buffer.get() * 10; // Unit is 10ms.
- if (freqTime[i] < 0) {
- Slog.e(TAG, "Negative time from freq time proc: " + freqTime[i]);
- valid = false;
- }
- }
- return valid;
- }
-
- /**
- * readImpl accepts a callback to process the uid entry. readDeltaImpl needs to store the last
- * seen results while processing the buffer, while readAbsolute returns the absolute value read
- * from the buffer without storing. So readImpl contains the common logic of the two, leaving
- * the difference to a processUid function.
- *
- * @param processUid the callback function to process the uid entry in the buffer.
- */
- private void readImpl(Consumer<IntBuffer> processUid) {
- synchronized (mProcReader) {
- ByteBuffer bytes = mProcReader.readBytes();
- if (bytes == null || bytes.remaining() <= 4) {
- // Error already logged in mProcReader.
- return;
- }
- if ((bytes.remaining() & 3) != 0) {
- Slog.wtf(TAG, "Cannot parse freq time proc bytes to int: " + bytes.remaining());
- return;
- }
- IntBuffer buf = bytes.asIntBuffer();
- final int freqs = buf.get();
- if (freqs != mCpuFreqsCount) {
- Slog.wtf(TAG, "Cpu freqs expect " + mCpuFreqsCount + " , got " + freqs);
- return;
- }
- if (buf.remaining() % (freqs + 1) != 0) {
- Slog.wtf(TAG, "Freq time format error: " + buf.remaining() + " / " + (freqs + 1));
- return;
- }
- int numUids = buf.remaining() / (freqs + 1);
- for (int i = 0; i < numUids; i++) {
- processUid.accept(buf);
- }
- if (DEBUG) {
- Slog.d(TAG, "Read uids: #" + numUids);
- }
- }
- }
-
- public void removeUid(int uid) {
- mLastUidCpuFreqTimeMs.delete(uid);
- }
-
- public void removeUidsInRange(int startUid, int endUid) {
- mLastUidCpuFreqTimeMs.put(startUid, null);
- mLastUidCpuFreqTimeMs.put(endUid, null);
- final int firstIndex = mLastUidCpuFreqTimeMs.indexOfKey(startUid);
- final int lastIndex = mLastUidCpuFreqTimeMs.indexOfKey(endUid);
- mLastUidCpuFreqTimeMs.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
- }
-
- /**
- * Extracts no. of cpu clusters and no. of freqs in each of these clusters from the freqs
- * read from the proc file.
- *
- * We need to assume that freqs in each cluster are strictly increasing.
- * For e.g. if the freqs read from proc file are: 12, 34, 15, 45, 12, 15, 52. Then it means
- * there are 3 clusters: (12, 34), (15, 45), (12, 15, 52)
- *
- * @return an IntArray filled with no. of freqs in each cluster.
- */
- private IntArray extractClusterInfoFromProcFileFreqs() {
- final IntArray numClusterFreqs = new IntArray();
- int freqsFound = 0;
- for (int i = 0; i < mCpuFreqsCount; ++i) {
- freqsFound++;
- if (i + 1 == mCpuFreqsCount || mCpuFreqs[i + 1] <= mCpuFreqs[i]) {
- numClusterFreqs.add(freqsFound);
- freqsFound = 0;
- }
- }
- return numClusterFreqs;
- }
-}
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
deleted file mode 100644
index 97b7211e5e87..000000000000
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.os;
-
-import android.annotation.Nullable;
-import android.os.StrictMode;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.Slog;
-import android.util.SparseLongArray;
-import android.util.TimeUtils;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-
-/**
- * Reads /proc/uid_cputime/show_uid_stat which has the line format:
- *
- * uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-micro_seconds
- *
- * This provides the time a UID's processes spent executing in user-space and kernel-space.
- * The file contains a monotonically increasing count of time for a single boot. This class
- * maintains the previous results of a call to {@link #readDelta} in order to provide a proper
- * delta.
- */
-public class KernelUidCpuTimeReader extends
- KernelUidCpuTimeReaderBase<KernelUidCpuTimeReader.Callback> {
- private static final String TAG = KernelUidCpuTimeReader.class.getSimpleName();
- private static final String sProcFile = "/proc/uid_cputime/show_uid_stat";
- private static final String sRemoveUidProcFile = "/proc/uid_cputime/remove_uid_range";
-
- /**
- * Callback interface for processing each line of the proc file.
- */
- public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
- /**
- * @param uid UID of the app
- * @param userTimeUs time spent executing in user space in microseconds
- * @param systemTimeUs time spent executing in kernel space in microseconds
- */
- void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
- }
-
- private SparseLongArray mLastUserTimeUs = new SparseLongArray();
- private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
- private long mLastTimeReadUs = 0;
-
- /**
- * Reads the proc file, calling into the callback with a delta of time for each UID.
- *
- * @param callback The callback to invoke for each line of the proc file. If null,
- * the data is consumed and subsequent calls to readDelta will provide
- * a fresh delta.
- */
- @Override
- protected void readDeltaImpl(@Nullable Callback callback) {
- final int oldMask = StrictMode.allowThreadDiskReadsMask();
- long nowUs = SystemClock.elapsedRealtime() * 1000;
- try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
- TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
- String line;
- while ((line = reader.readLine()) != null) {
- splitter.setString(line);
- final String uidStr = splitter.next();
- final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10);
- final long userTimeUs = Long.parseLong(splitter.next(), 10);
- final long systemTimeUs = Long.parseLong(splitter.next(), 10);
-
- boolean notifyCallback = false;
- long userTimeDeltaUs = userTimeUs;
- long systemTimeDeltaUs = systemTimeUs;
- // Only report if there is a callback and if this is not the first read.
- if (callback != null && mLastTimeReadUs != 0) {
- int index = mLastUserTimeUs.indexOfKey(uid);
- if (index >= 0) {
- userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
- systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
-
- final long timeDiffUs = nowUs - mLastTimeReadUs;
- if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0) {
- StringBuilder sb = new StringBuilder("Malformed cpu data for UID=");
- sb.append(uid).append("!\n");
- sb.append("Time between reads: ");
- TimeUtils.formatDuration(timeDiffUs / 1000, sb);
- sb.append("\n");
- sb.append("Previous times: u=");
- TimeUtils.formatDuration(mLastUserTimeUs.valueAt(index) / 1000, sb);
- sb.append(" s=");
- TimeUtils.formatDuration(mLastSystemTimeUs.valueAt(index) / 1000, sb);
-
- sb.append("\nCurrent times: u=");
- TimeUtils.formatDuration(userTimeUs / 1000, sb);
- sb.append(" s=");
- TimeUtils.formatDuration(systemTimeUs / 1000, sb);
- sb.append("\nDelta: u=");
- TimeUtils.formatDuration(userTimeDeltaUs / 1000, sb);
- sb.append(" s=");
- TimeUtils.formatDuration(systemTimeDeltaUs / 1000, sb);
- Slog.e(TAG, sb.toString());
-
- userTimeDeltaUs = 0;
- systemTimeDeltaUs = 0;
- }
- }
-
- notifyCallback = (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0);
- }
- mLastUserTimeUs.put(uid, userTimeUs);
- mLastSystemTimeUs.put(uid, systemTimeUs);
- if (notifyCallback) {
- callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs);
- }
- }
- } catch (IOException e) {
- Slog.e(TAG, "Failed to read uid_cputime: " + e.getMessage());
- } finally {
- StrictMode.setThreadPolicyMask(oldMask);
- }
- mLastTimeReadUs = nowUs;
- }
-
- /**
- * Reads the proc file, calling into the callback with raw absolute value of time for each UID.
- * @param callback The callback to invoke for each line of the proc file.
- */
- public void readAbsolute(Callback callback) {
- final int oldMask = StrictMode.allowThreadDiskReadsMask();
- try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
- TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
- String line;
- while ((line = reader.readLine()) != null) {
- splitter.setString(line);
- final String uidStr = splitter.next();
- final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10);
- final long userTimeUs = Long.parseLong(splitter.next(), 10);
- final long systemTimeUs = Long.parseLong(splitter.next(), 10);
- callback.onUidCpuTime(uid, userTimeUs, systemTimeUs);
- }
- } catch (IOException e) {
- Slog.e(TAG, "Failed to read uid_cputime: " + e.getMessage());
- } finally {
- StrictMode.setThreadPolicyMask(oldMask);
- }
- }
-
- /**
- * Removes the UID from the kernel module and from internal accounting data. Only
- * {@link BatteryStatsImpl} and its child processes should call this, as the change on Kernel is
- * visible system wide.
- *
- * @param uid The UID to remove.
- */
- public void removeUid(int uid) {
- final int index = mLastSystemTimeUs.indexOfKey(uid);
- if (index >= 0) {
- mLastSystemTimeUs.removeAt(index);
- mLastUserTimeUs.removeAt(index);
- }
- removeUidsFromKernelModule(uid, uid);
- }
-
- /**
- * Removes UIDs in a given range from the kernel module and internal accounting data. Only
- * {@link BatteryStatsImpl} and its child processes should call this, as the change on Kernel is
- * visible system wide.
- *
- * @param startUid the first uid to remove
- * @param endUid the last uid to remove
- */
- public void removeUidsInRange(int startUid, int endUid) {
- if (endUid < startUid) {
- return;
- }
- mLastSystemTimeUs.put(startUid, 0);
- mLastUserTimeUs.put(startUid, 0);
- mLastSystemTimeUs.put(endUid, 0);
- mLastUserTimeUs.put(endUid, 0);
- final int startIndex = mLastSystemTimeUs.indexOfKey(startUid);
- final int endIndex = mLastSystemTimeUs.indexOfKey(endUid);
- mLastSystemTimeUs.removeAtRange(startIndex, endIndex - startIndex + 1);
- mLastUserTimeUs.removeAtRange(startIndex, endIndex - startIndex + 1);
- removeUidsFromKernelModule(startUid, endUid);
- }
-
- private void removeUidsFromKernelModule(int startUid, int endUid) {
- Slog.d(TAG, "Removing uids " + startUid + "-" + endUid);
- final int oldMask = StrictMode.allowThreadDiskWritesMask();
- try (FileWriter writer = new FileWriter(sRemoveUidProcFile)) {
- writer.write(startUid + "-" + endUid);
- writer.flush();
- } catch (IOException e) {
- Slog.e(TAG, "failed to remove uids " + startUid + " - " + endUid
- + " from uid_cputime module", e);
- } finally {
- StrictMode.setThreadPolicyMask(oldMask);
- }
- }
-}
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java b/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java
deleted file mode 100644
index 11e50e1ecb95..000000000000
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import android.annotation.Nullable;
-import android.os.SystemClock;
-import android.util.Slog;
-
-/**
- * The base class of all KernelUidCpuTimeReaders.
- *
- * This class is NOT designed to be thread-safe or accessed by more than one caller (due to
- * the nature of {@link #readDelta(Callback)}).
- */
-public abstract class KernelUidCpuTimeReaderBase<T extends KernelUidCpuTimeReaderBase.Callback> {
- protected static final boolean DEBUG = false;
- // Throttle interval in milliseconds
- private static final long DEFAULT_THROTTLE_INTERVAL = 10_000L;
-
- private final String TAG = this.getClass().getSimpleName();
- private long mLastTimeReadMs = Long.MIN_VALUE;
- private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
-
- // A generic Callback interface (used by readDelta) to be extended by subclasses.
- public interface Callback {
- }
-
- public void readDelta(@Nullable T cb) {
- if (SystemClock.elapsedRealtime() < mLastTimeReadMs + mThrottleInterval) {
- if (DEBUG) {
- Slog.d(TAG, "Throttle");
- }
- return;
- }
- readDeltaImpl(cb);
- mLastTimeReadMs = SystemClock.elapsedRealtime();
- }
-
- protected abstract void readDeltaImpl(@Nullable T cb);
-
- public void setThrottleInterval(long throttleInterval) {
- if (throttleInterval >= 0) {
- mThrottleInterval = throttleInterval;
- }
- }
-}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java
index 0179eadae6a1..9cac7e794965 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java
@@ -43,6 +43,10 @@ import android.view.Display;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
import com.android.internal.util.ArrayUtils;
import org.junit.Before;
@@ -76,13 +80,13 @@ import java.util.Arrays;
@RunWith(AndroidJUnit4.class)
public class BatteryStatsCpuTimesTest {
@Mock
- KernelUidCpuTimeReader mKernelUidCpuTimeReader;
+ KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader;
@Mock
- KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader;
+ KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader;
@Mock
- KernelUidCpuActiveTimeReader mKernelUidCpuActiveTimeReader;
+ KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader;
@Mock
- KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader;
+ KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader;
@Mock
BatteryStatsImpl.UserInfoProvider mUserInfoProvider;
@Mock
@@ -98,10 +102,10 @@ public class BatteryStatsCpuTimesTest {
mClocks = new MockClocks();
mBatteryStatsImpl = new MockBatteryStatsImpl(mClocks)
- .setKernelUidCpuTimeReader(mKernelUidCpuTimeReader)
- .setKernelUidCpuFreqTimeReader(mKernelUidCpuFreqTimeReader)
- .setKernelUidCpuActiveTimeReader(mKernelUidCpuActiveTimeReader)
- .setKernelUidCpuClusterTimeReader(mKernelUidCpuClusterTimeReader)
+ .setKernelCpuUidUserSysTimeReader(mCpuUidUserSysTimeReader)
+ .setKernelCpuUidFreqTimeReader(mCpuUidFreqTimeReader)
+ .setKernelCpuUidActiveTimeReader(mCpuUidActiveTimeReader)
+ .setKernelCpuUidClusterTimeReader(mCpuUidClusterTimeReader)
.setUserInfoProvider(mUserInfoProvider);
}
@@ -113,21 +117,21 @@ public class BatteryStatsCpuTimesTest {
final int numClusters = 3;
initKernelCpuSpeedReaders(numClusters);
final long[] freqs = {1, 12, 123, 12, 1234};
- when(mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile)).thenReturn(freqs);
+ when(mCpuUidFreqTimeReader.readFreqs(mPowerProfile)).thenReturn(freqs);
// RUN
mBatteryStatsImpl.updateCpuTimeLocked(false, false);
// VERIFY
assertArrayEquals("Unexpected cpu freqs", freqs, mBatteryStatsImpl.getCpuFreqs());
- verify(mKernelUidCpuTimeReader).readDelta(null);
- verify(mKernelUidCpuFreqTimeReader).readDelta(null);
+ verify(mCpuUidUserSysTimeReader).readDelta(null);
+ verify(mCpuUidFreqTimeReader).readDelta(null);
for (int i = 0; i < numClusters; ++i) {
verify(mKernelCpuSpeedReaders[i]).readDelta();
}
// Prepare for next test
- Mockito.reset(mUserInfoProvider, mKernelUidCpuFreqTimeReader, mKernelUidCpuTimeReader);
+ Mockito.reset(mUserInfoProvider, mCpuUidFreqTimeReader, mCpuUidUserSysTimeReader);
for (int i = 0; i < numClusters; ++i) {
Mockito.reset(mKernelCpuSpeedReaders[i]);
}
@@ -140,17 +144,18 @@ public class BatteryStatsCpuTimesTest {
// VERIFY
verify(mUserInfoProvider).refreshUserIds();
- verify(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class));
+ verify(mCpuUidUserSysTimeReader).readDelta(
+ any(KernelCpuUidUserSysTimeReader.Callback.class));
// perClusterTimesAvailable is called twice, once in updateCpuTimeLocked() and the other
// in readKernelUidCpuFreqTimesLocked.
- verify(mKernelUidCpuFreqTimeReader, times(2)).perClusterTimesAvailable();
- verify(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
- verify(mKernelUidCpuActiveTimeReader).readDelta(
- any(KernelUidCpuActiveTimeReader.Callback.class));
- verify(mKernelUidCpuClusterTimeReader).readDelta(
- any(KernelUidCpuClusterTimeReader.Callback.class));
- verifyNoMoreInteractions(mKernelUidCpuFreqTimeReader);
+ verify(mCpuUidFreqTimeReader, times(2)).perClusterTimesAvailable();
+ verify(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
+ verify(mCpuUidActiveTimeReader).readDelta(
+ any(KernelCpuUidActiveTimeReader.Callback.class));
+ verify(mCpuUidClusterTimeReader).readDelta(
+ any(KernelCpuUidClusterTimeReader.Callback.class));
+ verifyNoMoreInteractions(mCpuUidFreqTimeReader);
for (int i = 0; i < numClusters; ++i) {
verify(mKernelCpuSpeedReaders[i]).readDelta();
}
@@ -253,13 +258,14 @@ public class BatteryStatsCpuTimesTest {
{12, 34}, {34897394, 3123983}, {79775429834l, 8430434903489l}
};
doAnswer(invocation -> {
- final KernelUidCpuTimeReader.Callback callback =
- (KernelUidCpuTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidUserSysTimeReader.Callback<long[]> callback =
+ (KernelCpuUidUserSysTimeReader.Callback<long[]>) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuTime(testUids[i], uidTimesUs[i][0], uidTimesUs[i][1]);
+ callback.onUidCpuTime(testUids[i], uidTimesUs[i]);
}
return null;
- }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class));
+ }).when(mCpuUidUserSysTimeReader).readDelta(
+ any(KernelCpuUidUserSysTimeReader.Callback.class));
// RUN
final SparseLongArray updatedUids = new SparseLongArray();
@@ -287,13 +293,14 @@ public class BatteryStatsCpuTimesTest {
{9379, 3332409833484l}, {493247, 723234}, {3247819, 123348}
};
doAnswer(invocation -> {
- final KernelUidCpuTimeReader.Callback callback =
- (KernelUidCpuTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidUserSysTimeReader.Callback<long[]> callback =
+ (KernelCpuUidUserSysTimeReader.Callback<long[]>) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuTime(testUids[i], deltasUs[i][0], deltasUs[i][1]);
+ callback.onUidCpuTime(testUids[i], deltasUs[i]);
}
return null;
- }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class));
+ }).when(mCpuUidUserSysTimeReader).readDelta(
+ any(KernelCpuUidUserSysTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true);
@@ -326,13 +333,14 @@ public class BatteryStatsCpuTimesTest {
{12, 34}, {34897394, 3123983}, {79775429834l, 8430434903489l}
};
doAnswer(invocation -> {
- final KernelUidCpuTimeReader.Callback callback =
- (KernelUidCpuTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidUserSysTimeReader.Callback<long[]> callback =
+ (KernelCpuUidUserSysTimeReader.Callback<long[]>) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuTime(testUids[i], uidTimesUs[i][0], uidTimesUs[i][1]);
+ callback.onUidCpuTime(testUids[i], uidTimesUs[i]);
}
return null;
- }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class));
+ }).when(mCpuUidUserSysTimeReader).readDelta(
+ any(KernelCpuUidUserSysTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true);
@@ -350,7 +358,7 @@ public class BatteryStatsCpuTimesTest {
assertEquals("Unexpected system cpu time for uid=" + testUids[i],
uidTimesUs[i][1], u.getSystemCpuTimeUs(STATS_SINCE_CHARGED));
}
- verify(mKernelUidCpuTimeReader).removeUid(isolatedUid);
+ verify(mCpuUidUserSysTimeReader).removeUid(isolatedUid);
// Add an isolated uid mapping and repeat the test.
@@ -361,13 +369,14 @@ public class BatteryStatsCpuTimesTest {
{9379, 3332409833484l}, {493247, 723234}, {3247819, 123348}
};
doAnswer(invocation -> {
- final KernelUidCpuTimeReader.Callback callback =
- (KernelUidCpuTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidUserSysTimeReader.Callback<long[]> callback =
+ (KernelCpuUidUserSysTimeReader.Callback<long[]>) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuTime(testUids[i], deltasUs[i][0], deltasUs[i][1]);
+ callback.onUidCpuTime(testUids[i], deltasUs[i]);
}
return null;
- }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class));
+ }).when(mCpuUidUserSysTimeReader).readDelta(
+ any(KernelCpuUidUserSysTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true);
@@ -414,15 +423,16 @@ public class BatteryStatsCpuTimesTest {
{12, 34}, {34897394, 3123983}, {79775429834l, 8430434903489l}
};
doAnswer(invocation -> {
- final KernelUidCpuTimeReader.Callback callback =
- (KernelUidCpuTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidUserSysTimeReader.Callback<long[]> callback =
+ (KernelCpuUidUserSysTimeReader.Callback<long[]>) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuTime(testUids[i], uidTimesUs[i][0], uidTimesUs[i][1]);
+ callback.onUidCpuTime(testUids[i], uidTimesUs[i]);
}
// And one for the invalid uid
- callback.onUidCpuTime(invalidUid, 3879, 239);
+ callback.onUidCpuTime(invalidUid, new long[]{3879, 239});
return null;
- }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class));
+ }).when(mCpuUidUserSysTimeReader).readDelta(
+ any(KernelCpuUidUserSysTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true);
@@ -438,7 +448,7 @@ public class BatteryStatsCpuTimesTest {
}
assertNull("There shouldn't be an entry for invalid uid=" + invalidUid,
mBatteryStatsImpl.getUidStats().get(invalidUid));
- verify(mKernelUidCpuTimeReader).removeUid(invalidUid);
+ verify(mCpuUidUserSysTimeReader).removeUid(invalidUid);
}
@Test
@@ -462,13 +472,14 @@ public class BatteryStatsCpuTimesTest {
{12, 34}, {3394, 3123}, {7977, 80434}
};
doAnswer(invocation -> {
- final KernelUidCpuTimeReader.Callback callback =
- (KernelUidCpuTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidUserSysTimeReader.Callback<long[]> callback =
+ (KernelCpuUidUserSysTimeReader.Callback<long[]>) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuTime(testUids[i], uidTimesUs[i][0], uidTimesUs[i][1]);
+ callback.onUidCpuTime(testUids[i], uidTimesUs[i]);
}
return null;
- }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class));
+ }).when(mCpuUidUserSysTimeReader).readDelta(
+ any(KernelCpuUidUserSysTimeReader.Callback.class));
// RUN
final SparseLongArray updatedUids = new SparseLongArray();
@@ -541,14 +552,14 @@ public class BatteryStatsCpuTimesTest {
{8, 25, 3, 0, 42}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false);
@@ -574,14 +585,14 @@ public class BatteryStatsCpuTimesTest {
{43, 3345, 2143, 123, 4554}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], deltasMs[i]);
+ callback.onUidCpuTime(testUids[i], deltasMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, true);
@@ -624,15 +635,15 @@ public class BatteryStatsCpuTimesTest {
{8, 25, 3, 0, 42}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
- when(mKernelUidCpuFreqTimeReader.perClusterTimesAvailable()).thenReturn(true);
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
+ when(mCpuUidFreqTimeReader.perClusterTimesAvailable()).thenReturn(true);
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false);
@@ -668,14 +679,14 @@ public class BatteryStatsCpuTimesTest {
{43, 3345, 2143, 123, 4554}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], deltasMs[i]);
+ callback.onUidCpuTime(testUids[i], deltasMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, true);
@@ -734,15 +745,15 @@ public class BatteryStatsCpuTimesTest {
{8, 25, 3, 0, 42}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
- when(mKernelUidCpuFreqTimeReader.perClusterTimesAvailable()).thenReturn(true);
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
+ when(mCpuUidFreqTimeReader.perClusterTimesAvailable()).thenReturn(true);
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(partialTimers, true, false);
@@ -824,14 +835,14 @@ public class BatteryStatsCpuTimesTest {
{8, 25, 3, 0, 42}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false);
@@ -857,14 +868,14 @@ public class BatteryStatsCpuTimesTest {
{43, 3345, 2143, 123, 4554, 9374983794839l, 979875}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], deltasMs[i]);
+ callback.onUidCpuTime(testUids[i], deltasMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, true);
@@ -901,14 +912,14 @@ public class BatteryStatsCpuTimesTest {
{8, 25, 3, 0, 42}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false);
@@ -927,7 +938,7 @@ public class BatteryStatsCpuTimesTest {
assertNull("Unexpected screen-off cpu times for uid=" + testUids[i],
u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED));
}
- verify(mKernelUidCpuFreqTimeReader).removeUid(isolatedUid);
+ verify(mCpuUidFreqTimeReader).removeUid(isolatedUid);
// Add an isolated uid mapping and repeat the test.
@@ -941,14 +952,14 @@ public class BatteryStatsCpuTimesTest {
{43, 3345, 2143, 123, 4554}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], deltasMs[i]);
+ callback.onUidCpuTime(testUids[i], deltasMs[i]);
}
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false);
@@ -996,16 +1007,16 @@ public class BatteryStatsCpuTimesTest {
{8, 25, 3, 0, 42}
};
doAnswer(invocation -> {
- final KernelUidCpuFreqTimeReader.Callback callback =
- (KernelUidCpuFreqTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidFreqTimeReader.Callback callback =
+ (KernelCpuUidFreqTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuFreqTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
// And one for the invalid uid
- callback.onUidCpuFreqTime(invalidUid, new long[]{12, 839, 32, 34, 21});
+ callback.onUidCpuTime(invalidUid, new long[]{12, 839, 32, 34, 21});
return null;
- }).when(mKernelUidCpuFreqTimeReader).readDelta(
- any(KernelUidCpuFreqTimeReader.Callback.class));
+ }).when(mCpuUidFreqTimeReader).readDelta(
+ any(KernelCpuUidFreqTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false);
@@ -1022,7 +1033,7 @@ public class BatteryStatsCpuTimesTest {
}
assertNull("There shouldn't be an entry for invalid uid=" + invalidUid,
mBatteryStatsImpl.getUidStats().get(invalidUid));
- verify(mKernelUidCpuFreqTimeReader).removeUid(invalidUid);
+ verify(mCpuUidFreqTimeReader).removeUid(invalidUid);
}
@Test
@@ -1039,14 +1050,14 @@ public class BatteryStatsCpuTimesTest {
});
final long[] uidTimesMs = {8000, 25000, 3000, 0, 42000};
doAnswer(invocation -> {
- final KernelUidCpuActiveTimeReader.Callback callback =
- (KernelUidCpuActiveTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidActiveTimeReader.Callback callback =
+ (KernelCpuUidActiveTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuActiveTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
return null;
- }).when(mKernelUidCpuActiveTimeReader).readDelta(
- any(KernelUidCpuActiveTimeReader.Callback.class));
+ }).when(mCpuUidActiveTimeReader).readDelta(
+ any(KernelCpuUidActiveTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true);
@@ -1065,14 +1076,14 @@ public class BatteryStatsCpuTimesTest {
updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
final long[] deltasMs = {43000, 3345000, 2143000, 123000, 4554000};
doAnswer(invocation -> {
- final KernelUidCpuActiveTimeReader.Callback callback =
- (KernelUidCpuActiveTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidActiveTimeReader.Callback callback =
+ (KernelCpuUidActiveTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuActiveTime(testUids[i], deltasMs[i]);
+ callback.onUidCpuTime(testUids[i], deltasMs[i]);
}
return null;
- }).when(mKernelUidCpuActiveTimeReader).readDelta(
- any(KernelUidCpuActiveTimeReader.Callback.class));
+ }).when(mCpuUidActiveTimeReader).readDelta(
+ any(KernelCpuUidActiveTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true);
@@ -1103,16 +1114,16 @@ public class BatteryStatsCpuTimesTest {
});
final long[] uidTimesMs = {8000, 25000, 3000, 0, 42000};
doAnswer(invocation -> {
- final KernelUidCpuActiveTimeReader.Callback callback =
- (KernelUidCpuActiveTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidActiveTimeReader.Callback callback =
+ (KernelCpuUidActiveTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuActiveTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
// And one for the invalid uid
- callback.onUidCpuActiveTime(invalidUid, 1200L);
+ callback.onUidCpuTime(invalidUid, 1200L);
return null;
- }).when(mKernelUidCpuActiveTimeReader).readDelta(
- any(KernelUidCpuActiveTimeReader.Callback.class));
+ }).when(mCpuUidActiveTimeReader).readDelta(
+ any(KernelCpuUidActiveTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true);
@@ -1126,7 +1137,7 @@ public class BatteryStatsCpuTimesTest {
}
assertNull("There shouldn't be an entry for invalid uid=" + invalidUid,
mBatteryStatsImpl.getUidStats().get(invalidUid));
- verify(mKernelUidCpuActiveTimeReader).removeUid(invalidUid);
+ verify(mCpuUidActiveTimeReader).removeUid(invalidUid);
}
@Test
@@ -1147,14 +1158,14 @@ public class BatteryStatsCpuTimesTest {
{8000, 0}
};
doAnswer(invocation -> {
- final KernelUidCpuClusterTimeReader.Callback callback =
- (KernelUidCpuClusterTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidClusterTimeReader.Callback callback =
+ (KernelCpuUidClusterTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuPolicyTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
return null;
- }).when(mKernelUidCpuClusterTimeReader).readDelta(
- any(KernelUidCpuClusterTimeReader.Callback.class));
+ }).when(mCpuUidClusterTimeReader).readDelta(
+ any(KernelCpuUidClusterTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuClusterTimesLocked(true);
@@ -1177,14 +1188,14 @@ public class BatteryStatsCpuTimesTest {
{43000, 3345000}
};
doAnswer(invocation -> {
- final KernelUidCpuClusterTimeReader.Callback callback =
- (KernelUidCpuClusterTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidClusterTimeReader.Callback callback =
+ (KernelCpuUidClusterTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuPolicyTime(testUids[i], deltasMs[i]);
+ callback.onUidCpuTime(testUids[i], deltasMs[i]);
}
return null;
- }).when(mKernelUidCpuClusterTimeReader).readDelta(
- any(KernelUidCpuClusterTimeReader.Callback.class));
+ }).when(mCpuUidClusterTimeReader).readDelta(
+ any(KernelCpuUidClusterTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuClusterTimesLocked(true);
@@ -1193,7 +1204,8 @@ public class BatteryStatsCpuTimesTest {
for (int i = 0; i < testUids.length; ++i) {
final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
assertNotNull("No entry for uid=" + testUids[i], u);
- assertArrayEquals("Unexpected cpu cluster time for uid=" + testUids[i], sum(uidTimesMs[i], deltasMs[i]),
+ assertArrayEquals("Unexpected cpu cluster time for uid=" + testUids[i],
+ sum(uidTimesMs[i], deltasMs[i]),
u.getCpuClusterTimes());
}
}
@@ -1219,16 +1231,16 @@ public class BatteryStatsCpuTimesTest {
{8000, 0}
};
doAnswer(invocation -> {
- final KernelUidCpuClusterTimeReader.Callback callback =
- (KernelUidCpuClusterTimeReader.Callback) invocation.getArguments()[0];
+ final KernelCpuUidClusterTimeReader.Callback callback =
+ (KernelCpuUidClusterTimeReader.Callback) invocation.getArguments()[0];
for (int i = 0; i < testUids.length; ++i) {
- callback.onUidCpuPolicyTime(testUids[i], uidTimesMs[i]);
+ callback.onUidCpuTime(testUids[i], uidTimesMs[i]);
}
// And one for the invalid uid
- callback.onUidCpuPolicyTime(invalidUid, new long[] {400, 1000});
+ callback.onUidCpuTime(invalidUid, new long[]{400, 1000});
return null;
- }).when(mKernelUidCpuClusterTimeReader).readDelta(
- any(KernelUidCpuClusterTimeReader.Callback.class));
+ }).when(mCpuUidClusterTimeReader).readDelta(
+ any(KernelCpuUidClusterTimeReader.Callback.class));
// RUN
mBatteryStatsImpl.readKernelUidCpuClusterTimesLocked(true);
@@ -1242,7 +1254,7 @@ public class BatteryStatsCpuTimesTest {
}
assertNull("There shouldn't be an entry for invalid uid=" + invalidUid,
mBatteryStatsImpl.getUidStats().get(invalidUid));
- verify(mKernelUidCpuClusterTimeReader).removeUid(invalidUid);
+ verify(mCpuUidClusterTimeReader).removeUid(invalidUid);
}
@Test
@@ -1268,25 +1280,25 @@ public class BatteryStatsCpuTimesTest {
mClocks.realtime = mClocks.uptime = 400_000;
mBatteryStatsImpl.clearPendingRemovedUids();
assertEquals(1, mBatteryStatsImpl.getPendingRemovedUids().size());
- verify(mKernelUidCpuActiveTimeReader).removeUid(1);
- verify(mKernelUidCpuActiveTimeReader).removeUidsInRange(5, 10);
- verify(mKernelUidCpuClusterTimeReader).removeUid(1);
- verify(mKernelUidCpuClusterTimeReader).removeUidsInRange(5, 10);
- verify(mKernelUidCpuFreqTimeReader).removeUid(1);
- verify(mKernelUidCpuFreqTimeReader).removeUidsInRange(5, 10);
- verify(mKernelUidCpuTimeReader).removeUid(1);
- verify(mKernelUidCpuTimeReader).removeUidsInRange(5, 10);
+ verify(mCpuUidActiveTimeReader).removeUid(1);
+ verify(mCpuUidActiveTimeReader).removeUidsInRange(5, 10);
+ verify(mCpuUidClusterTimeReader).removeUid(1);
+ verify(mCpuUidClusterTimeReader).removeUidsInRange(5, 10);
+ verify(mCpuUidFreqTimeReader).removeUid(1);
+ verify(mCpuUidFreqTimeReader).removeUidsInRange(5, 10);
+ verify(mCpuUidUserSysTimeReader).removeUid(1);
+ verify(mCpuUidUserSysTimeReader).removeUidsInRange(5, 10);
mClocks.realtime = mClocks.uptime = 800_000;
mBatteryStatsImpl.clearPendingRemovedUids();
assertEquals(0, mBatteryStatsImpl.getPendingRemovedUids().size());
- verify(mKernelUidCpuActiveTimeReader).removeUid(100);
- verify(mKernelUidCpuClusterTimeReader).removeUid(100);
- verify(mKernelUidCpuFreqTimeReader).removeUid(100);
- verify(mKernelUidCpuTimeReader).removeUid(100);
+ verify(mCpuUidActiveTimeReader).removeUid(100);
+ verify(mCpuUidClusterTimeReader).removeUid(100);
+ verify(mCpuUidFreqTimeReader).removeUid(100);
+ verify(mCpuUidUserSysTimeReader).removeUid(100);
- verifyNoMoreInteractions(mKernelUidCpuActiveTimeReader, mKernelUidCpuClusterTimeReader,
- mKernelUidCpuFreqTimeReader, mKernelUidCpuTimeReader);
+ verifyNoMoreInteractions(mCpuUidActiveTimeReader, mCpuUidClusterTimeReader,
+ mCpuUidFreqTimeReader, mCpuUidUserSysTimeReader);
}
private void updateTimeBasesLocked(boolean unplugged, int screenState,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java
index dc9367557f9f..077182921118 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java
@@ -39,6 +39,7 @@ import android.view.Display;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
import com.android.internal.util.ArrayUtils;
import org.junit.Before;
@@ -54,7 +55,7 @@ import java.util.Arrays;
@RunWith(AndroidJUnit4.class)
public class BatteryStatsImplTest {
@Mock
- private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader;
+ private KernelCpuUidFreqTimeReader mKernelUidCpuFreqTimeReader;
@Mock
private KernelSingleUidTimeReader mKernelSingleUidTimeReader;
@@ -67,7 +68,7 @@ public class BatteryStatsImplTest {
when(mKernelUidCpuFreqTimeReader.allUidTimesAvailable()).thenReturn(true);
when(mKernelSingleUidTimeReader.singleUidCpuTimesAvailable()).thenReturn(true);
mBatteryStatsImpl = new MockBatteryStatsImpl()
- .setKernelUidCpuFreqTimeReader(mKernelUidCpuFreqTimeReader)
+ .setKernelCpuUidFreqTimeReader(mKernelUidCpuFreqTimeReader)
.setKernelSingleUidTimeReader(mKernelSingleUidTimeReader);
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index d69e1d131731..a6329298b0f9 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -38,7 +38,6 @@ import org.junit.runners.Suite;
BatteryStatsTimerTest.class,
BatteryStatsUidTest.class,
BatteryStatsUserLifecycleTests.class,
- KernelCpuProcReaderTest.class,
KernelCpuProcStringReaderTest.class,
KernelCpuUidActiveTimeReaderTest.class,
KernelCpuUidClusterTimeReaderTest.class,
@@ -46,9 +45,6 @@ import org.junit.runners.Suite;
KernelCpuUidUserSysTimeReaderTest.class,
KernelMemoryBandwidthStatsTest.class,
KernelSingleUidTimeReaderTest.class,
- KernelUidCpuFreqTimeReaderTest.class,
- KernelUidCpuActiveTimeReaderTest.class,
- KernelUidCpuClusterTimeReaderTest.class,
KernelWakelockReaderTest.class,
LongSamplingCounterTest.class,
LongSamplingCounterArrayTest.class,
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java
deleted file mode 100644
index a25a74890029..000000000000
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.os.FileUtils;
-import android.os.SystemClock;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Random;
-
-/**
- * Test class for {@link KernelCpuProcReader}.
- *
- * $ atest FrameworksCoreTests:com.android.internal.os.KernelCpuProcReaderTest
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class KernelCpuProcReaderTest {
-
- private File mRoot;
- private File mTestDir;
- private File mTestFile;
- private Random mRand = new Random();
-
- private KernelCpuProcReader mKernelCpuProcReader;
-
- private Context getContext() {
- return InstrumentationRegistry.getContext();
- }
-
- @Before
- public void setUp() {
- mTestDir = getContext().getDir("test", Context.MODE_PRIVATE);
- mRoot = getContext().getFilesDir();
- mTestFile = new File(mTestDir, "test.file");
- mKernelCpuProcReader = new KernelCpuProcReader(mTestFile.getAbsolutePath());
- }
-
- @After
- public void tearDown() throws Exception {
- FileUtils.deleteContents(mTestDir);
- FileUtils.deleteContents(mRoot);
- }
-
-
- /**
- * Tests that reading will return null if the file does not exist.
- */
- @Test
- public void testReadInvalidFile() throws Exception {
- assertEquals(null, mKernelCpuProcReader.readBytes());
- }
-
- /**
- * Tests that reading will always return null after 5 failures.
- */
- @Test
- public void testReadErrorsLimit() throws Exception {
- mKernelCpuProcReader.setThrottleInterval(0);
- for (int i = 0; i < 3; i++) {
- assertNull(mKernelCpuProcReader.readBytes());
- SystemClock.sleep(50);
- }
-
- final byte[] data = new byte[1024];
- mRand.nextBytes(data);
- try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
- os.write(data);
- }
- assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
-
- assertTrue(mTestFile.delete());
- for (int i = 0; i < 3; i++) {
- assertNull(mKernelCpuProcReader.readBytes());
- SystemClock.sleep(50);
- }
- try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
- os.write(data);
- }
- assertNull(mKernelCpuProcReader.readBytes());
- }
-
- /**
- * Tests reading functionality.
- */
- @Test
- public void testSimpleRead() throws Exception {
- final byte[] data = new byte[1024];
- mRand.nextBytes(data);
- try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
- os.write(data);
- }
- assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
- }
-
- /**
- * Tests multiple reading functionality.
- */
- @Test
- public void testMultipleRead() throws Exception {
- mKernelCpuProcReader.setThrottleInterval(0);
- for (int i = 0; i < 100; i++) {
- final byte[] data = new byte[mRand.nextInt(102400) + 4];
- mRand.nextBytes(data);
- try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
- os.write(data);
- }
- assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
- assertTrue(mTestFile.delete());
- }
- }
-
- /**
- * Tests reading with resizing.
- */
- @Test
- public void testReadWithResize() throws Exception {
- final byte[] data = new byte[128001];
- mRand.nextBytes(data);
- try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
- os.write(data);
- }
- assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
- }
-
- /**
- * Tests that reading a file over the limit (1MB) will return null.
- */
- @Test
- public void testReadOverLimit() throws Exception {
- final byte[] data = new byte[1228800];
- mRand.nextBytes(data);
- try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
- os.write(data);
- }
- assertNull(mKernelCpuProcReader.readBytes());
- }
-
- /**
- * Tests throttling. Deleting underlying file should not affect cache.
- */
- @Test
- public void testThrottle() throws Exception {
- mKernelCpuProcReader.setThrottleInterval(3000);
- final byte[] data = new byte[20001];
- mRand.nextBytes(data);
- try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
- os.write(data);
- }
- assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
- assertTrue(mTestFile.delete());
- for (int i = 0; i < 5; i++) {
- assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
- SystemClock.sleep(10);
- }
- SystemClock.sleep(5000);
- assertNull(mKernelCpuProcReader.readBytes());
- }
-
- private byte[] toArray(ByteBuffer buffer) {
- assertNotNull(buffer);
- byte[] arr = new byte[buffer.remaining()];
- buffer.get(arr);
- return arr;
- }
-}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
index 7a316056429a..cbd2ba4eeabc 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
@@ -299,9 +299,10 @@ public class KernelCpuProcStringReaderTest {
assertTrue(mTestFile.delete());
try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
w.write(data1);
- modify.countDown();
} catch (Throwable e) {
errs.add(e);
+ } finally {
+ modify.countDown();
}
}, 600, TimeUnit.MILLISECONDS);
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java
deleted file mode 100644
index 12f6c188f18f..000000000000
--- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Random;
-
-/**
- * Test class for {@link KernelUidCpuActiveTimeReader}.
- *
- * To run it:
- * bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuActiveTimeReaderTest
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class KernelUidCpuActiveTimeReaderTest {
- @Mock
- private KernelCpuProcReader mProcReader;
- @Mock
- private KernelUidCpuActiveTimeReader.Callback mCallback;
- private KernelUidCpuActiveTimeReader mReader;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mReader = new KernelUidCpuActiveTimeReader(mProcReader);
- mReader.setThrottleInterval(0);
- }
-
- @Test
- public void testReadDelta() {
- final int cores = 8;
- final int[] uids = {1, 22, 333, 4444, 5555};
-
- final long[][] times = increaseTime(new long[uids.length][cores]);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length; i++) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times[i]));
- }
- verifyNoMoreInteractions(mCallback);
-
- // Verify that a second call will only return deltas.
- Mockito.reset(mCallback);
- final long[][] times1 = increaseTime(times);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length; i++) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times1[i], times[i])));
- }
- verifyNoMoreInteractions(mCallback);
-
- // Verify that there won't be a callback if the proc file values didn't change.
- Mockito.reset(mCallback);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1));
- mReader.readDelta(mCallback);
- verifyNoMoreInteractions(mCallback);
-
- // Verify that calling with a null callback doesn't result in any crashes
- Mockito.reset(mCallback);
- final long[][] times2 = increaseTime(times1);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times2));
- mReader.readDelta(null);
-
- // Verify that the readDelta call will only return deltas when
- // the previous call had null callback.
- Mockito.reset(mCallback);
- final long[][] times3 = increaseTime(times2);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times3));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length; ++i) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times3[i], times2[i])));
- }
- verifyNoMoreInteractions(mCallback);
- }
-
- @Test
- public void testReadAbsolute() {
- final int cores = 8;
- final int[] uids = {1, 22, 333, 4444, 5555};
-
- final long[][] times = increaseTime(new long[uids.length][cores]);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
- mReader.readAbsolute(mCallback);
- for (int i = 0; i < uids.length; i++) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times[i]));
- }
- verifyNoMoreInteractions(mCallback);
-
- // Verify that a second call still returns absolute values
- Mockito.reset(mCallback);
- final long[][] times1 = increaseTime(times);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1));
- mReader.readAbsolute(mCallback);
- for (int i = 0; i < uids.length; i++) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times1[i]));
- }
- verifyNoMoreInteractions(mCallback);
- }
-
- @Test
- public void testReadDelta_malformedData() {
- final int cores = 8;
- final int[] uids = {1, 22, 333, 4444, 5555};
- final long[][] times = increaseTime(new long[uids.length][cores]);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length; i++) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times[i]));
- }
- verifyNoMoreInteractions(mCallback);
-
- // Verify that there is no callback if subsequent call is in wrong format.
- Mockito.reset(mCallback);
- final long[][] times1 = increaseTime(times);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1).putInt(0, 5));
- mReader.readDelta(mCallback);
- verifyNoMoreInteractions(mCallback);
-
- // Verify that the internal state was not modified if the given core count does not match
- // the following # of entries.
- Mockito.reset(mCallback);
- final long[][] times2 = increaseTime(times);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times2));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length; i++) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times2[i], times[i])));
- }
- verifyNoMoreInteractions(mCallback);
-
- // Verify that there is no callback if any value in the proc file is -ve.
- Mockito.reset(mCallback);
- final long[][] times3 = increaseTime(times2);
- times3[uids.length - 1][cores - 1] *= -1;
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times3));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length - 1; ++i) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times3[i], times2[i])));
- }
- verifyNoMoreInteractions(mCallback);
-
- // Verify that the internal state was not modified when the proc file had -ve value.
- Mockito.reset(mCallback);
- for (int i = 0; i < cores; i++) {
- times3[uids.length - 1][i] = times2[uids.length - 1][i] + uids[uids.length - 1] * 2520;
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times3));
- mReader.readDelta(mCallback);
- verify(mCallback).onUidCpuActiveTime(uids[uids.length - 1],
- getTotal(subtract(times3[uids.length - 1], times2[uids.length - 1])));
- verifyNoMoreInteractions(mCallback);
-
- // Verify that there is no callback if the values in the proc file are decreased.
- Mockito.reset(mCallback);
- final long[][] times4 = increaseTime(times3);
- System.arraycopy(times3[uids.length - 1], 0, times4[uids.length - 1], 0, cores);
- times4[uids.length - 1][cores - 1] -= 100;
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times4));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length - 1; ++i) {
- verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times4[i], times3[i])));
- }
- verifyNoMoreInteractions(mCallback);
-
- // Verify that the internal state was not modified when the proc file had decreased values.
- Mockito.reset(mCallback);
- for (int i = 0; i < cores; i++) {
- times4[uids.length - 1][i] = times3[uids.length - 1][i] + uids[uids.length - 1] * 2520;
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times4));
- mReader.readDelta(mCallback);
- verify(mCallback).onUidCpuActiveTime(uids[uids.length - 1],
- getTotal(subtract(times4[uids.length - 1], times3[uids.length - 1])));
- verifyNoMoreInteractions(mCallback);
- }
-
- private long[] subtract(long[] a1, long[] a2) {
- long[] val = new long[a1.length];
- for (int i = 0; i < val.length; ++i) {
- val[i] = a1[i] - a2[i];
- }
- return val;
- }
-
- /**
- * Unit of original and return value is 10ms. What's special about 2520? 2520 is LCM of 1, 2, 3,
- * ..., 10. So that when wedivide shared cpu time by concurrent thread count, we always get a
- * nice integer, avoiding rounding errors.
- */
- private long[][] increaseTime(long[][] original) {
- long[][] newTime = new long[original.length][original[0].length];
- Random rand = new Random();
- for (int i = 0; i < original.length; i++) {
- for (int j = 0; j < original[0].length; j++) {
- newTime[i][j] = original[i][j] + rand.nextInt(1000) * 2520 + 2520;
- }
- }
- return newTime;
- }
-
- // Unit of times is 10ms
- private long getTotal(long[] times) {
- long sum = 0;
- for (int i = 0; i < times.length; i++) {
- sum += times[i] * 10 / (i + 1);
- }
- return sum;
- }
-
- /**
- * Format uids and times (in 10ms) into the following format:
- * [n, uid0, time0a, time0b, ..., time0n,
- * uid1, time1a, time1b, ..., time1n,
- * uid2, time2a, time2b, ..., time2n, etc.]
- * where n is the total number of cpus (num_possible_cpus)
- */
- private ByteBuffer getUidTimesBytes(int[] uids, long[][] times) {
- int size = (1 + uids.length * (times[0].length + 1)) * 4;
- ByteBuffer buf = ByteBuffer.allocate(size);
- buf.order(ByteOrder.nativeOrder());
- buf.putInt(times[0].length);
- for (int i = 0; i < uids.length; i++) {
- buf.putInt(uids[i]);
- for (int j = 0; j < times[i].length; j++) {
- buf.putInt((int) times[i][j]);
- }
- }
- buf.flip();
- return buf.order(ByteOrder.nativeOrder());
- }
-}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java
deleted file mode 100644
index 532f337fe2e1..000000000000
--- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.when;
-
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.Random;
-
-/**
- * Test class for {@link KernelUidCpuClusterTimeReader}.
- *
- * To run it:
- * bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuClusterTimeReaderTest
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class KernelUidCpuClusterTimeReaderTest {
- @Mock
- private KernelCpuProcReader mProcReader;
- private KernelUidCpuClusterTimeReader mReader;
- private VerifiableCallback mCallback;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mReader = new KernelUidCpuClusterTimeReader(mProcReader);
- mCallback = new VerifiableCallback();
- mReader.setThrottleInterval(0);
- }
-
- @Test
- public void testReadDelta() throws Exception {
- VerifiableCallback cb = new VerifiableCallback();
- final int cores = 6;
- final int[] clusters = {2, 4};
- final int[] uids = {1, 22, 333, 4444, 5555};
-
- // Verify initial call
- final long[][] times = increaseTime(new long[uids.length][cores]);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times));
- mReader.readDelta(cb);
- for (int i = 0; i < uids.length; i++) {
- cb.verify(uids[i], getTotal(clusters, times[i]));
- }
- cb.verifyNoMoreInteractions();
-
- // Verify that a second call will only return deltas.
- cb.clear();
- Mockito.reset(mProcReader);
- final long[][] times1 = increaseTime(times);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1));
- mReader.readDelta(cb);
- for (int i = 0; i < uids.length; i++) {
- cb.verify(uids[i], getTotal(clusters, subtract(times1[i], times[i])));
- }
- cb.verifyNoMoreInteractions();
-
- // Verify that there won't be a callback if the proc file values didn't change.
- cb.clear();
- Mockito.reset(mProcReader);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1));
- mReader.readDelta(cb);
- cb.verifyNoMoreInteractions();
-
- // Verify that calling with a null callback doesn't result in any crashes
- Mockito.reset(mProcReader);
- final long[][] times2 = increaseTime(times1);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times2));
- mReader.readDelta(null);
-
- // Verify that the readDelta call will only return deltas when
- // the previous call had null callback.
- cb.clear();
- Mockito.reset(mProcReader);
- final long[][] times3 = increaseTime(times2);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times3));
- mReader.readDelta(cb);
- for (int i = 0; i < uids.length; i++) {
- cb.verify(uids[i], getTotal(clusters, subtract(times3[i], times2[i])));
- }
- cb.verifyNoMoreInteractions();
-
- }
-
- @Test
- public void testReadAbsolute() throws Exception {
- VerifiableCallback cb = new VerifiableCallback();
- final int cores = 6;
- final int[] clusters = {2, 4};
- final int[] uids = {1, 22, 333, 4444, 5555};
-
- // Verify return absolute value
- final long[][] times = increaseTime(new long[uids.length][cores]);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times));
- mReader.readAbsolute(cb);
- for (int i = 0; i < uids.length; i++) {
- cb.verify(uids[i], getTotal(clusters, times[i]));
- }
- cb.verifyNoMoreInteractions();
-
- // Verify that a second call should return the same absolute value
- cb.clear();
- Mockito.reset(mProcReader);
- final long[][] times1 = increaseTime(times);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1));
- mReader.readAbsolute(cb);
- for (int i = 0; i < uids.length; i++) {
- cb.verify(uids[i], getTotal(clusters, times1[i]));
- }
- cb.verifyNoMoreInteractions();
- }
-
- @Test
- public void testReadDelta_malformedData() throws Exception {
- final int cores = 6;
- final int[] clusters = {2, 4};
- final int[] uids = {1, 22, 333, 4444, 5555};
-
- // Verify initial call
- final long[][] times = increaseTime(new long[uids.length][cores]);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length; i++) {
- mCallback.verify(uids[i], getTotal(clusters, times[i]));
- }
- mCallback.verifyNoMoreInteractions();
-
- // Verify that there is no callback if a call has wrong format
- mCallback.clear();
- Mockito.reset(mProcReader);
- final long[][] temp = increaseTime(times);
- final long[][] times1 = new long[uids.length][];
- for (int i = 0; i < temp.length; i++) {
- times1[i] = Arrays.copyOfRange(temp[i], 0, 4);
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1));
- mReader.readDelta(mCallback);
- mCallback.verifyNoMoreInteractions();
-
- // Verify that the internal state was not modified if the given core count does not match
- // the following # of entries.
- mCallback.clear();
- Mockito.reset(mProcReader);
- final long[][] times2 = increaseTime(times);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times2));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length; i++) {
- mCallback.verify(uids[i], getTotal(clusters, subtract(times2[i], times[i])));
- }
- mCallback.verifyNoMoreInteractions();
-
- // Verify that there is no callback if any value in the proc file is -ve.
- mCallback.clear();
- Mockito.reset(mProcReader);
- final long[][] times3 = increaseTime(times2);
- times3[uids.length - 1][cores - 1] *= -1;
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times3));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length - 1; i++) {
- mCallback.verify(uids[i], getTotal(clusters, subtract(times3[i], times2[i])));
- }
- mCallback.verifyNoMoreInteractions();
-
- // Verify that the internal state was not modified when the proc file had -ve value.
- mCallback.clear();
- Mockito.reset(mProcReader);
- for (int i = 0; i < cores; i++) {
- times3[uids.length - 1][i] = times2[uids.length - 1][i] + uids[uids.length - 1] * 2520;
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times3));
- mReader.readDelta(mCallback);
- mCallback.verify(uids[uids.length - 1],
- getTotal(clusters, subtract(times3[uids.length - 1], times2[uids.length - 1])));
-
- // Verify that there is no callback if the values in the proc file are decreased.
- mCallback.clear();
- Mockito.reset(mProcReader);
- final long[][] times4 = increaseTime(times3);
- System.arraycopy(times3[uids.length - 1], 0, times4[uids.length - 1], 0, cores);
- times4[uids.length - 1][cores - 1] -= 100;
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times4));
- mReader.readDelta(mCallback);
- for (int i = 0; i < uids.length - 1; i++) {
- mCallback.verify(uids[i], getTotal(clusters, subtract(times4[i], times3[i])));
- }
- mCallback.verifyNoMoreInteractions();
-
- // Verify that the internal state was not modified when the proc file had decreased values.
- mCallback.clear();
- Mockito.reset(mProcReader);
- for (int i = 0; i < cores; i++) {
- times4[uids.length - 1][i] = times3[uids.length - 1][i] + uids[uids.length - 1] * 2520;
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times4));
- mReader.readDelta(mCallback);
- mCallback.verify(uids[uids.length - 1],
- getTotal(clusters, subtract(times3[uids.length - 1], times2[uids.length - 1])));
- mCallback.verifyNoMoreInteractions();
- }
-
-
- private long[] subtract(long[] a1, long[] a2) {
- long[] val = new long[a1.length];
- for (int i = 0; i < val.length; ++i) {
- val[i] = a1[i] - a2[i];
- }
- return val;
- }
-
- /**
- * Unit is 10ms. What's special about 2520? 2520 is LCM of 1, 2, 3, ..., 10. So that when we
- * divide shared cpu time by concurrent thread count, we always get a nice integer, avoiding
- * rounding errors.
- */
- private long[][] increaseTime(long[][] original) {
- long[][] newTime = new long[original.length][original[0].length];
- Random rand = new Random();
- for (int i = 0; i < original.length; i++) {
- for (int j = 0; j < original[0].length; j++) {
- newTime[i][j] = original[i][j] + rand.nextInt(1000) * 2520 + 2520;
- }
- }
- return newTime;
- }
-
- // Format an array of cluster times according to the algorithm in KernelUidCpuClusterTimeReader
- private long[] getTotal(int[] cluster, long[] times) {
- int core = 0;
- long[] sumTimes = new long[cluster.length];
- for (int i = 0; i < cluster.length; i++) {
- double sum = 0;
- for (int j = 0; j < cluster[i]; j++) {
- sum += (double) times[core++] * 10 / (j + 1);
- }
- sumTimes[i] = (long) sum;
- }
- return sumTimes;
- }
-
- private class VerifiableCallback implements KernelUidCpuClusterTimeReader.Callback {
-
- SparseArray<long[]> mData = new SparseArray<>();
- int count = 0;
-
- public void verify(int uid, long[] cpuClusterTimeMs) {
- long[] array = mData.get(uid);
- assertNotNull(array);
- assertArrayEquals(cpuClusterTimeMs, array);
- count++;
- }
-
- public void clear() {
- mData.clear();
- count = 0;
- }
-
- @Override
- public void onUidCpuPolicyTime(int uid, long[] cpuClusterTimeMs) {
- long[] array = new long[cpuClusterTimeMs.length];
- System.arraycopy(cpuClusterTimeMs, 0, array, 0, array.length);
- mData.put(uid, array);
- }
-
- public void verifyNoMoreInteractions() {
- assertEquals(mData.size(), count);
- }
- }
-
- /**
- * Format uids and times (in 10ms) into the following format:
- * [n, x0, ..., xn, uid0, time0a, time0b, ..., time0n,
- * uid1, time1a, time1b, ..., time1n,
- * uid2, time2a, time2b, ..., time2n, etc.]
- * where n is the number of policies
- * xi is the number cpus on a particular policy
- */
- private ByteBuffer getUidTimesBytes(int[] uids, int[] clusters, long[][] times) {
- int size = (1 + clusters.length + uids.length * (times[0].length + 1)) * 4;
- ByteBuffer buf = ByteBuffer.allocate(size);
- buf.order(ByteOrder.nativeOrder());
- buf.putInt(clusters.length);
- for (int i = 0; i < clusters.length; i++) {
- buf.putInt(clusters[i]);
- }
- for (int i = 0; i < uids.length; i++) {
- buf.putInt(uids[i]);
- for (int j = 0; j < times[i].length; j++) {
- buf.putInt((int) (times[i][j]));
- }
- }
- buf.flip();
- return buf.order(ByteOrder.nativeOrder());
- }
-}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
deleted file mode 100644
index 6d2980b8bed0..000000000000
--- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.util.SparseArray;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.BufferedReader;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-
-/**
- * Test class for {@link KernelUidCpuFreqTimeReader}.
- *
- * To run the tests, use
- *
- * runtest -c com.android.internal.os.KernelUidCpuFreqTimeReaderTest frameworks-core
- *
- * or the following steps:
- *
- * Build: m FrameworksCoreTests
- * Install: adb install -r \
- * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
- * Run: adb shell am instrument -e class com.android.internal.os.KernelUidCpuFreqTimeReaderTest -w \
- * com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
- *
- * or
- *
- * bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuFreqTimeReaderTest
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class KernelUidCpuFreqTimeReaderTest {
- @Mock
- private BufferedReader mBufferedReader;
- @Mock
- private KernelUidCpuFreqTimeReader.Callback mCallback;
- @Mock
- private PowerProfile mPowerProfile;
- @Mock
- private KernelCpuProcReader mProcReader;
-
- private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mKernelUidCpuFreqTimeReader = new KernelUidCpuFreqTimeReader(mProcReader);
- mKernelUidCpuFreqTimeReader.setThrottleInterval(0);
- }
-
- @Test
- public void testReadFreqs_perClusterTimesNotAvailable() throws Exception {
- final long[][] freqs = {
- {1, 12, 123, 1234},
- {1, 12, 123, 23, 123, 1234, 12345, 123456},
- {1, 12, 123, 23, 123, 1234, 12345, 123456, 12, 123, 12345},
- {1, 12, 123, 23, 2345, 234567}
- };
- final int[] numClusters = {2, 2, 3, 1};
- final int[][] numFreqs = {{3, 6}, {4, 5}, {3, 5, 4}, {3}};
- for (int i = 0; i < freqs.length; ++i) {
- setCpuClusterFreqs(numClusters[i], numFreqs[i]);
- when(mBufferedReader.readLine()).thenReturn(getFreqsLine(freqs[i]));
- long[] actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(
- mBufferedReader, mPowerProfile);
- assertArrayEquals(freqs[i], actualFreqs);
- verifyZeroInteractions(mCallback);
- final String errMsg = String.format("Freqs=%s, nClusters=%d, nFreqs=%s",
- Arrays.toString(freqs[i]), numClusters[i], Arrays.toString(numFreqs[i]));
- assertFalse(errMsg, mKernelUidCpuFreqTimeReader.perClusterTimesAvailable());
-
- // Verify that a second call won't read the proc file again
- Mockito.reset(mBufferedReader);
- actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile);
- assertArrayEquals(freqs[i], actualFreqs);
- assertFalse(errMsg, mKernelUidCpuFreqTimeReader.perClusterTimesAvailable());
-
- // Prepare for next iteration
- Mockito.reset(mBufferedReader, mPowerProfile);
- }
- }
-
- @Test
- public void testReadFreqs_perClusterTimesAvailable() throws Exception {
- final long[][] freqs = {
- {1, 12, 123, 1234},
- {1, 12, 123, 23, 123, 1234, 12345, 123456},
- {1, 12, 123, 23, 123, 1234, 12345, 123456, 12, 123, 12345, 1234567}
- };
- final int[] numClusters = {1, 2, 3};
- final int[][] numFreqs = {{4}, {3, 5}, {3, 5, 4}};
- for (int i = 0; i < freqs.length; ++i) {
- setCpuClusterFreqs(numClusters[i], numFreqs[i]);
- when(mBufferedReader.readLine()).thenReturn(getFreqsLine(freqs[i]));
- long[] actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(
- mBufferedReader, mPowerProfile);
- assertArrayEquals(freqs[i], actualFreqs);
- verifyZeroInteractions(mCallback);
- final String errMsg = String.format("Freqs=%s, nClusters=%d, nFreqs=%s",
- Arrays.toString(freqs[i]), numClusters[i], Arrays.toString(numFreqs[i]));
- assertTrue(errMsg, mKernelUidCpuFreqTimeReader.perClusterTimesAvailable());
-
- // Verify that a second call won't read the proc file again
- Mockito.reset(mBufferedReader);
- actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile);
- assertArrayEquals(freqs[i], actualFreqs);
- assertTrue(errMsg, mKernelUidCpuFreqTimeReader.perClusterTimesAvailable());
-
- // Prepare for next iteration
- Mockito.reset(mBufferedReader, mPowerProfile);
- }
- }
-
- @Test
- public void testReadDelta_Binary() throws Exception {
- VerifiableCallback cb = new VerifiableCallback();
- final long[] freqs = {110, 123, 145, 167, 289, 997};
- final int[] uids = {1, 22, 333, 444, 555};
- final long[][] times = new long[uids.length][freqs.length];
- for (int i = 0; i < uids.length; ++i) {
- for (int j = 0; j < freqs.length; ++j) {
- times[i][j] = uids[i] * freqs[j] * 10;
- }
- }
- when(mBufferedReader.readLine()).thenReturn(getFreqsLine(freqs));
- long[] actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mBufferedReader, mPowerProfile);
-
- assertArrayEquals(freqs, actualFreqs);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
- mKernelUidCpuFreqTimeReader.readDeltaImpl(cb);
- for (int i = 0; i < uids.length; ++i) {
- cb.verify(uids[i], times[i]);
- }
- cb.verifyNoMoreInteractions();
-
- // Verify that a second call will only return deltas.
- cb.clear();
- Mockito.reset(mProcReader);
- final long[][] newTimes1 = new long[uids.length][freqs.length];
- for (int i = 0; i < uids.length; ++i) {
- for (int j = 0; j < freqs.length; ++j) {
- newTimes1[i][j] = times[i][j] + (uids[i] + freqs[j]) * 50;
- }
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes1));
- mKernelUidCpuFreqTimeReader.readDeltaImpl(cb);
- for (int i = 0; i < uids.length; ++i) {
- cb.verify(uids[i], subtract(newTimes1[i], times[i]));
- }
- cb.verifyNoMoreInteractions();
-
- // Verify that there won't be a callback if the proc file values didn't change.
- cb.clear();
- Mockito.reset(mProcReader);
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes1));
- mKernelUidCpuFreqTimeReader.readDeltaImpl(cb);
- cb.verifyNoMoreInteractions();
-
- // Verify that calling with a null callback doesn't result in any crashes
- cb.clear();
- Mockito.reset(mProcReader);
- final long[][] newTimes2 = new long[uids.length][freqs.length];
- for (int i = 0; i < uids.length; ++i) {
- for (int j = 0; j < freqs.length; ++j) {
- newTimes2[i][j] = newTimes1[i][j] + (uids[i] * freqs[j]) * 30;
- }
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes2));
- mKernelUidCpuFreqTimeReader.readDeltaImpl(null);
- cb.verifyNoMoreInteractions();
-
- // Verify that the readDelta call will only return deltas when
- // the previous call had null callback.
- cb.clear();
- Mockito.reset(mProcReader);
- final long[][] newTimes3 = new long[uids.length][freqs.length];
- for (int i = 0; i < uids.length; ++i) {
- for (int j = 0; j < freqs.length; ++j) {
- newTimes3[i][j] = newTimes2[i][j] + (uids[i] + freqs[j]) * 40;
- }
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes3));
- mKernelUidCpuFreqTimeReader.readDeltaImpl(cb);
- for (int i = 0; i < uids.length; ++i) {
- cb.verify(uids[i], subtract(newTimes3[i], newTimes2[i]));
- }
- cb.verifyNoMoreInteractions();
- }
-
- @Test
- public void testReadAbsolute() throws Exception {
- VerifiableCallback cb = new VerifiableCallback();
- final long[] freqs = {110, 123, 145, 167, 289, 997};
- final int[] uids = {1, 22, 333, 444, 555};
- final long[][] times = new long[uids.length][freqs.length];
- for (int i = 0; i < uids.length; ++i) {
- for (int j = 0; j < freqs.length; ++j) {
- times[i][j] = uids[i] * freqs[j] * 10;
- }
- }
- when(mBufferedReader.readLine()).thenReturn(getFreqsLine(freqs));
- long[] actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mBufferedReader, mPowerProfile);
-
- assertArrayEquals(freqs, actualFreqs);
- // Verify that the absolute values are returned
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
- mKernelUidCpuFreqTimeReader.readAbsolute(cb);
- for (int i = 0; i < uids.length; ++i) {
- cb.verify(uids[i], times[i]);
- }
- cb.verifyNoMoreInteractions();
-
- // Verify that a second call should still return absolute values
- cb.clear();
- Mockito.reset(mProcReader);
- final long[][] newTimes1 = new long[uids.length][freqs.length];
- for (int i = 0; i < uids.length; ++i) {
- for (int j = 0; j < freqs.length; ++j) {
- newTimes1[i][j] = times[i][j] + (uids[i] + freqs[j]) * 50;
- }
- }
- when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes1));
- mKernelUidCpuFreqTimeReader.readAbsolute(cb);
- for (int i = 0; i < uids.length; ++i) {
- cb.verify(uids[i], newTimes1[i]);
- }
- cb.verifyNoMoreInteractions();
- }
-
- private long[] subtract(long[] a1, long[] a2) {
- long[] val = new long[a1.length];
- for (int i = 0; i < val.length; ++i) {
- val[i] = a1[i] - a2[i];
- }
- return val;
- }
-
- private String getFreqsLine(long[] freqs) {
- final StringBuilder sb = new StringBuilder();
- sb.append("uid:");
- for (int i = 0; i < freqs.length; ++i) {
- sb.append(" " + freqs[i]);
- }
- return sb.toString();
- }
-
- private ByteBuffer getUidTimesBytes(int[] uids, long[][] times) {
- int size = (1 + uids.length + uids.length * times[0].length) * 4;
- ByteBuffer buf = ByteBuffer.allocate(size);
- buf.order(ByteOrder.nativeOrder());
- buf.putInt(times[0].length);
- for (int i = 0; i < uids.length; i++) {
- buf.putInt(uids[i]);
- for (int j = 0; j < times[i].length; j++) {
- buf.putInt((int) (times[i][j] / 10));
- }
- }
- buf.flip();
- return buf.asReadOnlyBuffer().order(ByteOrder.nativeOrder());
- }
-
- private void setCpuClusterFreqs(int numClusters, int... clusterFreqs) {
- assertEquals(numClusters, clusterFreqs.length);
- when(mPowerProfile.getNumCpuClusters()).thenReturn(numClusters);
- for (int i = 0; i < numClusters; ++i) {
- when(mPowerProfile.getNumSpeedStepsInCpuCluster(i)).thenReturn(clusterFreqs[i]);
- }
- }
-
- private class VerifiableCallback implements KernelUidCpuFreqTimeReader.Callback {
-
- SparseArray<long[]> mData = new SparseArray<>();
- int count = 0;
-
- public void verify(int uid, long[] cpuFreqTimeMs) {
- long[] array = mData.get(uid);
- assertNotNull(array);
- assertArrayEquals(cpuFreqTimeMs, array);
- count++;
- }
-
- public void clear() {
- mData.clear();
- count = 0;
- }
-
- @Override
- public void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs) {
- long[] array = new long[cpuFreqTimeMs.length];
- System.arraycopy(cpuFreqTimeMs, 0, array, 0, array.length);
- mData.put(uid, array);
- }
-
- public void verifyNoMoreInteractions() {
- assertEquals(mData.size(), count);
- }
- }
-}
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 c18445e26173..bc0e0a496d80 100644
--- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
+++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
@@ -21,6 +21,10 @@ import android.os.Looper;
import android.util.SparseIntArray;
import com.android.internal.location.gnssmetrics.GnssMetrics;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
import java.util.ArrayList;
import java.util.Queue;
@@ -43,13 +47,14 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
setExternalStatsSyncLocked(new DummyExternalStatsSync());
- for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
- mGpsSignalQualityTimer[i] = new StopwatchTimer(clocks, null, -1000-i, null,
- mOnBatteryTimeBase);
+ for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
+ mGpsSignalQualityTimer[i] = new StopwatchTimer(clocks, null, -1000 - i, null,
+ mOnBatteryTimeBase);
}
// A no-op handler.
- mHandler = new Handler(Looper.getMainLooper()) {};
+ mHandler = new Handler(Looper.getMainLooper()) {
+ };
}
MockBatteryStatsImpl() {
@@ -95,23 +100,26 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
return this;
}
- public MockBatteryStatsImpl setKernelUidCpuFreqTimeReader(KernelUidCpuFreqTimeReader reader) {
- mKernelUidCpuFreqTimeReader = reader;
+ public MockBatteryStatsImpl setKernelCpuUidFreqTimeReader(KernelCpuUidFreqTimeReader reader) {
+ mCpuUidFreqTimeReader = reader;
return this;
}
- public MockBatteryStatsImpl setKernelUidCpuActiveTimeReader(KernelUidCpuActiveTimeReader reader) {
- mKernelUidCpuActiveTimeReader = reader;
+ public MockBatteryStatsImpl setKernelCpuUidActiveTimeReader(
+ KernelCpuUidActiveTimeReader reader) {
+ mCpuUidActiveTimeReader = reader;
return this;
}
- public MockBatteryStatsImpl setKernelUidCpuClusterTimeReader(KernelUidCpuClusterTimeReader reader) {
- mKernelUidCpuClusterTimeReader = reader;
+ public MockBatteryStatsImpl setKernelCpuUidClusterTimeReader(
+ KernelCpuUidClusterTimeReader reader) {
+ mCpuUidClusterTimeReader = reader;
return this;
}
- public MockBatteryStatsImpl setKernelUidCpuTimeReader(KernelUidCpuTimeReader reader) {
- mKernelUidCpuTimeReader = reader;
+ public MockBatteryStatsImpl setKernelCpuUidUserSysTimeReader(
+ KernelCpuUidUserSysTimeReader reader) {
+ mCpuUidUserSysTimeReader = reader;
return this;
}
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 4e71a054fa80..40664fef2825 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -96,10 +96,10 @@ import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BinderCallsStats.ExportedCallStat;
import com.android.internal.os.KernelCpuSpeedReader;
import com.android.internal.os.KernelCpuThreadReader;
-import com.android.internal.os.KernelUidCpuActiveTimeReader;
-import com.android.internal.os.KernelUidCpuClusterTimeReader;
-import com.android.internal.os.KernelUidCpuFreqTimeReader;
-import com.android.internal.os.KernelUidCpuTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
+import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
import com.android.internal.os.KernelWakelockReader;
import com.android.internal.os.KernelWakelockStats;
import com.android.internal.os.LooperStats;
@@ -231,14 +231,16 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private final HashMap<Long, String> mDeletedFiles = new HashMap<>();
private final CompanionHandler mHandler;
- private KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
+ // Disables throttler on CPU time readers.
+ private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader =
+ new KernelCpuUidUserSysTimeReader(false);
private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
- private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader =
- new KernelUidCpuFreqTimeReader();
- private KernelUidCpuActiveTimeReader mKernelUidCpuActiveTimeReader =
- new KernelUidCpuActiveTimeReader();
- private KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader =
- new KernelUidCpuClusterTimeReader();
+ private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader =
+ new KernelCpuUidFreqTimeReader(false);
+ private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader =
+ new KernelCpuUidActiveTimeReader(false);
+ private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader =
+ new KernelCpuUidClusterTimeReader(false);
private StoragedUidIoStatsReader mStoragedUidIoStatsReader =
new StoragedUidIoStatsReader();
@Nullable
@@ -294,12 +296,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
numSpeedSteps);
firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
}
- // use default throttling in
- // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
- mKernelUidCpuFreqTimeReader.setThrottleInterval(0);
- long[] freqs = mKernelUidCpuFreqTimeReader.readFreqs(powerProfile);
- mKernelUidCpuClusterTimeReader.setThrottleInterval(0);
- mKernelUidCpuActiveTimeReader.setThrottleInterval(0);
// Enable push notifications of throttling from vendor thermal
// management subsystem via thermalservice.
@@ -914,7 +910,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private void pullKernelUidCpuTime(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
- mKernelUidCpuTimeReader.readAbsolute((uid, userTimeUs, systemTimeUs) -> {
+ mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> {
+ long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeInt(uid);
e.writeLong(userTimeUs);
@@ -926,7 +923,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private void pullKernelUidCpuFreqTime(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
- mKernelUidCpuFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
+ mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
if (cpuFreqTimeMs[freqIndex] != 0) {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
@@ -943,7 +940,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private void pullKernelUidCpuClusterTime(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
- mKernelUidCpuClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
+ mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
for (int i = 0; i < cpuClusterTimesMs.length; i++) {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
wallClockNanos);
@@ -958,7 +955,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private void pullKernelUidCpuActiveTime(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
- mKernelUidCpuActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
+ mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeInt(uid);
e.writeLong((long) cpuActiveTimesMs);