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

Commit 7ab7fcd5 authored by Mike Ma's avatar Mike Ma
Browse files

Switch to new CPU UID time readers

Switch to new per-UID CPU concurrent active, concurrent cluster, and
per-frequency time readers added in ag/5516062, used to read CPU times
info from the kernel via proc files in order to calculate per-UID CPU
power consumption.

These readers acquire constant amount of memory space during the first
read, thus do not leave garbage over time. Also, they read the text
version of these CPU time proc files, instead of the binary version
introduced in P, encouraging all kernels to implement a standard
human-readable CPU time proc interface:
* /proc/uid_time_in_state
* /proc/uid_concurrent_active_time
* /proc/uid_concurrent_policy_time
* /proc/uid_cputime/show_uid_stat

Remove old readers that read the binary version, since they are no
longer in use.

Bug: 111216804
Test: atest FrameworksCoreTests:com.android.internal.os.BatteryStatsTests
Test: verified that it works end to end. BatteryStats dumpsys output is
      similar to proc file output.
Change-Id: Iaa1321e1facabece1c777eaeb79187cf081436ae
parent 56f53225
Loading
Loading
Loading
Loading
+57 −48
Original line number Diff line number Diff line
@@ -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);
            }
        }
+0 −162
Original line number Diff line number Diff line
/*
 * 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;
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -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";
+5 −5
Original line number Diff line number Diff line
@@ -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;
+0 −179

File deleted.

Preview size limit exceeded, changes collapsed.

Loading