diff options
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); |