Merge "Fix KernelCpuUidUserSysTimeReaderTest#testThrottler by injecting a mock clock"
This commit is contained in:
committed by
Android (Google) Code Review
commit
bf55fd64ff
File diff suppressed because it is too large
Load Diff
@@ -256,7 +256,7 @@ public class BatteryUsageStatsProvider {
|
||||
|
||||
private long elapsedRealtime() {
|
||||
if (mStats instanceof BatteryStatsImpl) {
|
||||
return ((BatteryStatsImpl) mStats).mClocks.elapsedRealtime();
|
||||
return ((BatteryStatsImpl) mStats).mClock.elapsedRealtime();
|
||||
} else {
|
||||
return SystemClock.elapsedRealtime();
|
||||
}
|
||||
@@ -264,7 +264,7 @@ public class BatteryUsageStatsProvider {
|
||||
|
||||
private long uptimeMillis() {
|
||||
if (mStats instanceof BatteryStatsImpl) {
|
||||
return ((BatteryStatsImpl) mStats).mClocks.uptimeMillis();
|
||||
return ((BatteryStatsImpl) mStats).mClock.uptimeMillis();
|
||||
} else {
|
||||
return SystemClock.uptimeMillis();
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class BatteryUsageStatsProvider {
|
||||
|
||||
private long currentTimeMillis() {
|
||||
if (mStats instanceof BatteryStatsImpl) {
|
||||
return ((BatteryStatsImpl) mStats).mClocks.currentTimeMillis();
|
||||
return ((BatteryStatsImpl) mStats).mClock.currentTimeMillis();
|
||||
} else {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
57
core/java/com/android/internal/os/Clock.java
Normal file
57
core/java/com/android/internal/os/Clock.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.SystemClock;
|
||||
|
||||
/**
|
||||
* A wrapper for SystemClock, intended for mocking in unit tests.
|
||||
*/
|
||||
public abstract class Clock {
|
||||
/** Elapsed Realtime, see SystemClock.elapsedRealtime() */
|
||||
public long elapsedRealtime() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/** Uptime, see SystemClock.uptimeMillis() */
|
||||
public long uptimeMillis() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/** Wall-clock time as per System.currentTimeMillis() */
|
||||
public long currentTimeMillis() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static final Clock SYSTEM_CLOCK = new Clock() {
|
||||
|
||||
@Override
|
||||
public long elapsedRealtime() {
|
||||
return SystemClock.elapsedRealtime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long uptimeMillis() {
|
||||
return SystemClock.uptimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long currentTimeMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.internal.os;
|
||||
|
||||
import android.os.StrictMode;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -89,6 +88,7 @@ public class KernelCpuProcStringReader {
|
||||
|
||||
private int mErrors = 0;
|
||||
private final Path mFile;
|
||||
private final Clock mClock;
|
||||
private char[] mBuf;
|
||||
private int mSize;
|
||||
private long mLastReadTime = 0;
|
||||
@@ -97,7 +97,12 @@ public class KernelCpuProcStringReader {
|
||||
private final ReentrantReadWriteLock.WriteLock mWriteLock = mLock.writeLock();
|
||||
|
||||
public KernelCpuProcStringReader(String file) {
|
||||
this(file, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
public KernelCpuProcStringReader(String file, Clock clock) {
|
||||
mFile = Paths.get(file);
|
||||
mClock = clock;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +173,7 @@ public class KernelCpuProcStringReader {
|
||||
}
|
||||
}
|
||||
mSize = total;
|
||||
mLastReadTime = SystemClock.elapsedRealtime();
|
||||
mLastReadTime = mClock.elapsedRealtime();
|
||||
// ReentrantReadWriteLock allows lock downgrading.
|
||||
mReadLock.lock();
|
||||
return new ProcFileIterator(total);
|
||||
@@ -186,7 +191,7 @@ public class KernelCpuProcStringReader {
|
||||
}
|
||||
|
||||
private boolean dataValid() {
|
||||
return mSize > 0 && (SystemClock.elapsedRealtime() - mLastReadTime < FRESHNESS);
|
||||
return mSize > 0 && (mClock.elapsedRealtime() - mLastReadTime < FRESHNESS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,6 @@ import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.StrictMode;
|
||||
import android.os.SystemClock;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
@@ -60,6 +59,7 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
final boolean mThrottle;
|
||||
protected boolean mBpfTimesAvailable;
|
||||
final KernelCpuUidBpfMapReader mBpfReader;
|
||||
private final Clock mClock;
|
||||
private long mMinTimeBetweenRead = DEFAULT_MIN_TIME_BETWEEN_READ;
|
||||
private long mLastReadTimeMs = 0;
|
||||
|
||||
@@ -76,15 +76,17 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
void onUidCpuTime(int uid, T time);
|
||||
}
|
||||
|
||||
KernelCpuUidTimeReader(KernelCpuProcStringReader reader, @Nullable KernelCpuUidBpfMapReader bpfReader, boolean throttle) {
|
||||
KernelCpuUidTimeReader(KernelCpuProcStringReader reader,
|
||||
@Nullable KernelCpuUidBpfMapReader bpfReader, boolean throttle, Clock clock) {
|
||||
mReader = reader;
|
||||
mThrottle = throttle;
|
||||
mBpfReader = bpfReader;
|
||||
mClock = clock;
|
||||
mBpfTimesAvailable = (mBpfReader != null);
|
||||
}
|
||||
|
||||
KernelCpuUidTimeReader(KernelCpuProcStringReader reader, boolean throttle) {
|
||||
this(reader, null, throttle);
|
||||
KernelCpuUidTimeReader(KernelCpuProcStringReader reader, boolean throttle, Clock clock) {
|
||||
this(reader, null, throttle, clock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,17 +106,17 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
*/
|
||||
public void readDelta(boolean force, @Nullable Callback<T> cb) {
|
||||
if (!mThrottle) {
|
||||
readDeltaImpl(cb);
|
||||
readDeltaImpl(cb, force);
|
||||
return;
|
||||
}
|
||||
final long currTimeMs = SystemClock.elapsedRealtime();
|
||||
final long currTimeMs = mClock.elapsedRealtime();
|
||||
if (!force && currTimeMs < mLastReadTimeMs + mMinTimeBetweenRead) {
|
||||
if (DEBUG) {
|
||||
Slog.d(mTag, "Throttle readDelta");
|
||||
}
|
||||
return;
|
||||
}
|
||||
readDeltaImpl(cb);
|
||||
readDeltaImpl(cb, force);
|
||||
mLastReadTimeMs = currTimeMs;
|
||||
}
|
||||
|
||||
@@ -128,7 +130,7 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
readAbsoluteImpl(cb);
|
||||
return;
|
||||
}
|
||||
final long currTimeMs = SystemClock.elapsedRealtime();
|
||||
final long currTimeMs = mClock.elapsedRealtime();
|
||||
if (currTimeMs < mLastReadTimeMs + mMinTimeBetweenRead) {
|
||||
if (DEBUG) {
|
||||
Slog.d(mTag, "Throttle readAbsolute");
|
||||
@@ -139,7 +141,7 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
mLastReadTimeMs = currTimeMs;
|
||||
}
|
||||
|
||||
abstract void readDeltaImpl(@Nullable Callback<T> cb);
|
||||
abstract void readDeltaImpl(@Nullable Callback<T> cb, boolean forceRead);
|
||||
|
||||
abstract void readAbsoluteImpl(Callback<T> callback);
|
||||
|
||||
@@ -216,17 +218,22 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
private final long[] mUsrSysTime = new long[2];
|
||||
|
||||
public KernelCpuUidUserSysTimeReader(boolean throttle) {
|
||||
super(KernelCpuProcStringReader.getUserSysTimeReaderInstance(), throttle);
|
||||
this(throttle, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
public KernelCpuUidUserSysTimeReader(boolean throttle, Clock clock) {
|
||||
super(KernelCpuProcStringReader.getUserSysTimeReaderInstance(), throttle, clock);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public KernelCpuUidUserSysTimeReader(KernelCpuProcStringReader reader, boolean throttle) {
|
||||
super(reader, throttle);
|
||||
public KernelCpuUidUserSysTimeReader(KernelCpuProcStringReader reader, boolean throttle,
|
||||
Clock clock) {
|
||||
super(reader, throttle, clock);
|
||||
}
|
||||
|
||||
@Override
|
||||
void readDeltaImpl(@Nullable Callback<long[]> cb) {
|
||||
try (ProcFileIterator iter = mReader.open(!mThrottle)) {
|
||||
void readDeltaImpl(@Nullable Callback<long[]> cb, boolean forceRead) {
|
||||
try (ProcFileIterator iter = mReader.open(!mThrottle || forceRead)) {
|
||||
if (iter == null) {
|
||||
return;
|
||||
}
|
||||
@@ -348,14 +355,23 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
private boolean mAllUidTimesAvailable = true;
|
||||
|
||||
public KernelCpuUidFreqTimeReader(boolean throttle) {
|
||||
this(throttle, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
public KernelCpuUidFreqTimeReader(boolean throttle, Clock clock) {
|
||||
this(UID_TIMES_PROC_FILE, KernelCpuProcStringReader.getFreqTimeReaderInstance(),
|
||||
KernelCpuUidBpfMapReader.getFreqTimeReaderInstance(), throttle);
|
||||
KernelCpuUidBpfMapReader.getFreqTimeReaderInstance(), throttle, clock);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public KernelCpuUidFreqTimeReader(String procFile, KernelCpuProcStringReader reader,
|
||||
KernelCpuUidBpfMapReader bpfReader, boolean throttle) {
|
||||
super(reader, bpfReader, throttle);
|
||||
this(procFile, reader, bpfReader, throttle, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
private KernelCpuUidFreqTimeReader(String procFile, KernelCpuProcStringReader reader,
|
||||
KernelCpuUidBpfMapReader bpfReader, boolean throttle, Clock clock) {
|
||||
super(reader, bpfReader, throttle, clock);
|
||||
mProcFilePath = Paths.get(procFile);
|
||||
}
|
||||
|
||||
@@ -496,7 +512,7 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
void readDeltaImpl(@Nullable Callback<long[]> cb) {
|
||||
void readDeltaImpl(@Nullable Callback<long[]> cb, boolean forceRead) {
|
||||
if (mBpfTimesAvailable) {
|
||||
try (BpfMapIterator iter = mBpfReader.open(!mThrottle)) {
|
||||
if (checkPrecondition(iter)) {
|
||||
@@ -628,13 +644,18 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
private long[] mBuffer;
|
||||
|
||||
public KernelCpuUidActiveTimeReader(boolean throttle) {
|
||||
this(throttle, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
public KernelCpuUidActiveTimeReader(boolean throttle, Clock clock) {
|
||||
super(KernelCpuProcStringReader.getActiveTimeReaderInstance(),
|
||||
KernelCpuUidBpfMapReader.getActiveTimeReaderInstance(), throttle);
|
||||
KernelCpuUidBpfMapReader.getActiveTimeReaderInstance(), throttle, clock);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public KernelCpuUidActiveTimeReader(KernelCpuProcStringReader reader, KernelCpuUidBpfMapReader bpfReader, boolean throttle) {
|
||||
super(reader, bpfReader, throttle);
|
||||
public KernelCpuUidActiveTimeReader(KernelCpuProcStringReader reader,
|
||||
KernelCpuUidBpfMapReader bpfReader, boolean throttle) {
|
||||
super(reader, bpfReader, throttle, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
private void processUidDelta(@Nullable Callback<Long> cb) {
|
||||
@@ -655,7 +676,7 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
void readDeltaImpl(@Nullable Callback<Long> cb) {
|
||||
void readDeltaImpl(@Nullable Callback<Long> cb, boolean forceRead) {
|
||||
if (mBpfTimesAvailable) {
|
||||
try (BpfMapIterator iter = mBpfReader.open(!mThrottle)) {
|
||||
if (checkPrecondition(iter)) {
|
||||
@@ -800,14 +821,18 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
private long[] mDeltaTime;
|
||||
|
||||
public KernelCpuUidClusterTimeReader(boolean throttle) {
|
||||
this(throttle, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
public KernelCpuUidClusterTimeReader(boolean throttle, Clock clock) {
|
||||
super(KernelCpuProcStringReader.getClusterTimeReaderInstance(),
|
||||
KernelCpuUidBpfMapReader.getClusterTimeReaderInstance(), throttle);
|
||||
KernelCpuUidBpfMapReader.getClusterTimeReaderInstance(), throttle, clock);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public KernelCpuUidClusterTimeReader(KernelCpuProcStringReader reader,
|
||||
KernelCpuUidBpfMapReader bpfReader, boolean throttle) {
|
||||
super(reader, bpfReader, throttle);
|
||||
KernelCpuUidBpfMapReader bpfReader, boolean throttle) {
|
||||
super(reader, bpfReader, throttle, Clock.SYSTEM_CLOCK);
|
||||
}
|
||||
|
||||
void processUidDelta(@Nullable Callback<long[]> cb) {
|
||||
@@ -838,7 +863,7 @@ public abstract class KernelCpuUidTimeReader<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
void readDeltaImpl(@Nullable Callback<long[]> cb) {
|
||||
void readDeltaImpl(@Nullable Callback<long[]> cb, boolean forceRead) {
|
||||
if (mBpfTimesAvailable) {
|
||||
try (BpfMapIterator iter = mBpfReader.open(!mThrottle)) {
|
||||
if (checkPrecondition(iter)) {
|
||||
|
||||
Reference in New Issue
Block a user