Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf55fd64 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Fix KernelCpuUidUserSysTimeReaderTest#testThrottler by injecting a mock clock"

parents 2b243592 d378715d
Loading
Loading
Loading
Loading
+404 −431

File changed.

Preview size limit exceeded, changes collapsed.

+3 −3
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
/*
 * 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();
        }
    };
}
+8 −3
Original line number Diff line number Diff line
@@ -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);
    }

    /**
+50 −25
Original line number Diff line number Diff line
@@ -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);
            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)) {
Loading