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

Commit a5312bc2 authored by Mike Ma's avatar Mike Ma Committed by android-build-merger
Browse files

Merge "Resolve STATSD and batterystats race condition" into pi-dev am: 1639c330

am: a2a3d4ce

Change-Id: I2eb4b3c1406be38021b262d424910a9af6a020af
parents 34be60db a2a3d4ce
Loading
Loading
Loading
Loading
+153 −48
Original line number Diff line number Diff line
@@ -33,9 +33,6 @@ import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Build;
import android.os.connectivity.CellularBatteryStats;
import android.os.connectivity.WifiBatteryStats;
import android.os.connectivity.GpsBatteryStats;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBatteryPropertiesRegistrar;
@@ -53,6 +50,9 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.os.WorkSource.WorkChain;
import android.os.connectivity.CellularBatteryStats;
import android.os.connectivity.GpsBatteryStats;
import android.os.connectivity.WifiBatteryStats;
import android.provider.Settings;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.ModemActivityInfo;
@@ -90,8 +90,8 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
import java.util.List;
import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -109,11 +109,11 @@ import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Queue;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
@@ -234,11 +234,15 @@ public class BatteryStatsImpl extends BatteryStats {
    protected final SparseIntArray mPendingUids = new SparseIntArray();
    @GuardedBy("this")
    private long mNumCpuTimeReads;
    private long mNumSingleUidCpuTimeReads;
    @GuardedBy("this")
    private long mNumBatchedCpuTimeReads;
    private long mNumBatchedSingleUidCpuTimeReads;
    @GuardedBy("this")
    private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis();
    @GuardedBy("this")
    private int mNumUidsRemoved;
    @GuardedBy("this")
    private int mNumAllUidCpuTimeReads;
    /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */
    private final RpmStats mTmpRpmStats = new RpmStats();
@@ -246,6 +250,67 @@ public class BatteryStatsImpl extends BatteryStats {
    private static final long RPM_STATS_UPDATE_FREQ_MS = 1000;
    /** 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.
     *
     * 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
     * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is
     * implemented so that STATSD can capture those UID times before they are deleted.
     */
    @GuardedBy("this")
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>();
    @VisibleForTesting
    public final class UidToRemove {
        int startUid;
        int endUid;
        long timeAddedInQueue;
        /** Remove just one UID */
        public UidToRemove(int uid, long timestamp) {
            this(uid, uid, timestamp);
        }
        /** Remove a range of UIDs, startUid must be smaller than endUid. */
        public UidToRemove(int startUid, int endUid, long timestamp) {
            this.startUid = startUid;
            this.endUid = endUid;
            timeAddedInQueue = timestamp;
        }
        void remove() {
            if (startUid == endUid) {
                mKernelUidCpuTimeReader.removeUid(startUid);
                mKernelUidCpuFreqTimeReader.removeUid(startUid);
                if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
                    mKernelUidCpuActiveTimeReader.removeUid(startUid);
                    mKernelUidCpuClusterTimeReader.removeUid(startUid);
                }
                if (mKernelSingleUidTimeReader != null) {
                    mKernelSingleUidTimeReader.removeUid(startUid);
                }
                mNumUidsRemoved++;
            } else if (startUid < endUid) {
                mKernelUidCpuFreqTimeReader.removeUidsInRange(startUid, endUid);
                mKernelUidCpuTimeReader.removeUidsInRange(startUid, endUid);
                if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
                    mKernelUidCpuActiveTimeReader.removeUidsInRange(startUid, endUid);
                    mKernelUidCpuClusterTimeReader.removeUidsInRange(startUid, endUid);
                }
                if (mKernelSingleUidTimeReader != null) {
                    mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid);
                }
                // Treat as one. We don't know how many uids there are in between.
                mNumUidsRemoved++;
            } else {
                Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid);
            }
        }
    }
    public interface BatteryCallback {
        public void batteryNeedsCpuUpdate();
@@ -376,6 +441,14 @@ public class BatteryStatsImpl extends BatteryStats {
        }
    }
    public void clearPendingRemovedUids() {
        long cutOffTime = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS;
        while (!mPendingRemovedUids.isEmpty()
                && mPendingRemovedUids.peek().timeAddedInQueue < cutOffTime) {
            mPendingRemovedUids.poll().remove();
        }
    }
    public void copyFromAllUidsCpuTimes() {
        synchronized (BatteryStatsImpl.this) {
            copyFromAllUidsCpuTimes(
@@ -3961,12 +4034,7 @@ public class BatteryStatsImpl extends BatteryStats {
            u.removeIsolatedUid(isolatedUid);
            mIsolatedUids.removeAt(idx);
        }
        mKernelUidCpuTimeReader.removeUid(isolatedUid);
        mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
        if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
            mKernelUidCpuActiveTimeReader.removeUid(isolatedUid);
            mKernelUidCpuClusterTimeReader.removeUid(isolatedUid);
        }
        mPendingRemovedUids.add(new UidToRemove(isolatedUid, mClocks.elapsedRealtime()));
    }
    public int mapUid(int uid) {
@@ -9860,9 +9928,9 @@ public class BatteryStatsImpl extends BatteryStats {
                                    mBsi.mOnBatteryTimeBase.isRunning(),
                                    mBsi.mOnBatteryScreenOffTimeBase.isRunning(),
                                    mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS);
                            mBsi.mNumCpuTimeReads++;
                            mBsi.mNumSingleUidCpuTimeReads++;
                        } else {
                            mBsi.mNumBatchedCpuTimeReads++;
                            mBsi.mNumBatchedSingleUidCpuTimeReads++;
                        }
                        if (mBsi.mPendingUids.indexOfKey(mUid) < 0
                                || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) {
@@ -11024,6 +11092,9 @@ public class BatteryStatsImpl extends BatteryStats {
        mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
        mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
        mNumAllUidCpuTimeReads = 0;
        mNumUidsRemoved = 0;
        initDischarge();
        clearHistoryLocked();
@@ -12009,9 +12080,11 @@ public class BatteryStatsImpl extends BatteryStats {
        if (!onBattery) {
            mKernelUidCpuTimeReader.readDelta(null);
            mKernelUidCpuFreqTimeReader.readDelta(null);
            mNumAllUidCpuTimeReads += 2;
            if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
                mKernelUidCpuActiveTimeReader.readDelta(null);
                mKernelUidCpuClusterTimeReader.readDelta(null);
                mNumAllUidCpuTimeReads += 2;
            }
            for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) {
                mKernelCpuSpeedReaders[cluster].readDelta();
@@ -12029,9 +12102,11 @@ public class BatteryStatsImpl extends BatteryStats {
            updateClusterSpeedTimes(updatedUids, onBattery);
        }
        readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff);
        mNumAllUidCpuTimeReads += 2;
        if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) {
            readKernelUidCpuActiveTimesLocked(onBattery);
            readKernelUidCpuClusterTimesLocked(onBattery);
            mNumAllUidCpuTimeReads += 2;
        }
    }
@@ -13256,11 +13331,8 @@ public class BatteryStatsImpl extends BatteryStats {
    public void onCleanupUserLocked(int userId) {
        final int firstUidForUser = UserHandle.getUid(userId, 0);
        final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
        mKernelUidCpuFreqTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
        mKernelUidCpuTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
        if (mKernelSingleUidTimeReader != null) {
            mKernelSingleUidTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
        }
        mPendingRemovedUids.add(
                new UidToRemove(firstUidForUser, lastUidForUser, mClocks.elapsedRealtime()));
    }
    public void onUserRemovedLocked(int userId) {
@@ -13277,12 +13349,8 @@ public class BatteryStatsImpl extends BatteryStats {
     * Remove the statistics object for a particular uid.
     */
    public void removeUidStatsLocked(int uid) {
        mKernelUidCpuTimeReader.removeUid(uid);
        mKernelUidCpuFreqTimeReader.removeUid(uid);
        if (mKernelSingleUidTimeReader != null) {
            mKernelSingleUidTimeReader.removeUid(uid);
        }
        mUidStats.remove(uid);
        mPendingRemovedUids.add(new UidToRemove(uid, mClocks.elapsedRealtime()));
    }
    /**
@@ -13335,24 +13403,24 @@ public class BatteryStatsImpl extends BatteryStats {
                = "track_cpu_times_by_proc_state";
        public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME
                = "track_cpu_active_cluster_time";
        public static final String KEY_READ_BINARY_CPU_TIME
                = "read_binary_cpu_time";
        public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS
                = "proc_state_cpu_times_read_delay_ms";
        public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME
                = "kernel_uid_readers_throttle_time";
        public static final String KEY_UID_REMOVE_DELAY_MS
                = "uid_remove_delay_ms";
        private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true;
        private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
        private static final boolean DEFAULT_READ_BINARY_CPU_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_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L;
        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 boolean READ_BINARY_CPU_TIME = DEFAULT_READ_BINARY_CPU_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;
        public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS;
        private ContentResolver mResolver;
        private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -13390,14 +13458,14 @@ public class BatteryStatsImpl extends BatteryStats {
                                DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE));
                TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean(
                        KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME);
                updateReadBinaryCpuTime(READ_BINARY_CPU_TIME,
                        mParser.getBoolean(KEY_READ_BINARY_CPU_TIME, DEFAULT_READ_BINARY_CPU_TIME));
                updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS,
                        mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS,
                                DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS));
                updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME,
                        mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME,
                                DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME));
                updateUidRemoveDelay(
                        mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS));
            }
        }
@@ -13407,24 +13475,17 @@ public class BatteryStatsImpl extends BatteryStats {
                mKernelSingleUidTimeReader.markDataAsStale(true);
                mExternalSync.scheduleCpuSyncDueToSettingChange();
                mNumCpuTimeReads = 0;
                mNumBatchedCpuTimeReads = 0;
                mNumSingleUidCpuTimeReads = 0;
                mNumBatchedSingleUidCpuTimeReads = 0;
                mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
            }
        }
        private void updateReadBinaryCpuTime(boolean oldEnabled, boolean isEnabled) {
            READ_BINARY_CPU_TIME = isEnabled;
            if (oldEnabled != isEnabled) {
                mKernelUidCpuFreqTimeReader.setReadBinary(isEnabled);
            }
        }
        private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) {
            PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis;
            if (oldDelayMillis != newDelayMillis) {
                mNumCpuTimeReads = 0;
                mNumBatchedCpuTimeReads = 0;
                mNumSingleUidCpuTimeReads = 0;
                mNumBatchedSingleUidCpuTimeReads = 0;
                mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis();
            }
        }
@@ -13440,13 +13501,16 @@ public class BatteryStatsImpl extends BatteryStats {
            }
        }
        private void updateUidRemoveDelay(long newTimeMs) {
            UID_REMOVE_DELAY_MS = newTimeMs;
            clearPendingRemovedUids();
        }
        public void dumpLocked(PrintWriter pw) {
            pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("=");
            pw.println(TRACK_CPU_TIMES_BY_PROC_STATE);
            pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("=");
            pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME);
            pw.print(KEY_READ_BINARY_CPU_TIME); pw.print("=");
            pw.println(READ_BINARY_CPU_TIME);
            pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("=");
            pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS);
            pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("=");
@@ -13459,6 +13523,43 @@ public class BatteryStatsImpl extends BatteryStats {
        mConstants.dumpLocked(pw);
    }
    @GuardedBy("this")
    public void dumpCpuStatsLocked(PrintWriter pw) {
        int size = mUidStats.size();
        pw.println("Per UID CPU user & system time in ms:");
        for (int i = 0; i < size; i++) {
            int u = mUidStats.keyAt(i);
            Uid uid = mUidStats.get(u);
            pw.print("  "); pw.print(u); pw.print(": ");
            pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" ");
            pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000);
        }
        pw.println("Per UID CPU active time in ms:");
        for (int i = 0; i < size; i++) {
            int u = mUidStats.keyAt(i);
            Uid uid = mUidStats.get(u);
            if (uid.getCpuActiveTime() > 0) {
                pw.print("  "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime());
            }
        }
        pw.println("Per UID CPU cluster time in ms:");
        for (int i = 0; i < size; i++) {
            int u = mUidStats.keyAt(i);
            long[] times = mUidStats.get(u).getCpuClusterTimes();
            if (times != null) {
                pw.print("  "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times));
            }
        }
        pw.println("Per UID CPU frequency time in ms:");
        for (int i = 0; i < size; i++) {
            int u = mUidStats.keyAt(i);
            long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED);
            if (times != null) {
                pw.print("  "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times));
            }
        }
    }
    Parcel mPendingWrite = null;
    final ReentrantLock mWriteLock = new ReentrantLock();
@@ -15183,10 +15284,14 @@ public class BatteryStatsImpl extends BatteryStats {
        }
        super.dumpLocked(context, pw, flags, reqUid, histStart);
        pw.print("Total cpu time reads: ");
        pw.println(mNumCpuTimeReads);
        pw.println(mNumSingleUidCpuTimeReads);
        pw.print("Batched cpu time reads: ");
        pw.println(mNumBatchedCpuTimeReads);
        pw.println(mNumBatchedSingleUidCpuTimeReads);
        pw.print("Batching Duration (min): ");
        pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000));
        pw.print("All UID cpu time reads since the later of device start or stats reset: ");
        pw.println(mNumAllUidCpuTimeReads);
        pw.print("UIDs removed since the later of device start or stats reset: ");
        pw.println(mNumUidsRemoved);
    }
}
+62 −35
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ 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
@@ -54,6 +55,7 @@ public class KernelUidCpuActiveTimeReader extends

    private final KernelCpuProcReader mProcReader;
    private SparseArray<Double> mLastUidCpuActiveTimeMs = new SparseArray<>();
    private int mCores;

    public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
        /**
@@ -75,7 +77,60 @@ public class KernelUidCpuActiveTimeReader extends
    }

    @Override
    protected void readDeltaImpl(@Nullable Callback cb) {
    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) {
@@ -89,6 +144,11 @@ public class KernelUidCpuActiveTimeReader extends
            }
            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
@@ -97,25 +157,7 @@ public class KernelUidCpuActiveTimeReader extends
            }
            int numUids = buf.remaining() / (cores + 1);
            for (int i = 0; i < numUids; i++) {
                int uid = buf.get();
                boolean corrupted = false;
                double curTime = 0;
                for (int j = 1; j <= cores; j++) {
                    int time = buf.get();
                    if (time < 0) {
                        Slog.e(TAG, "Corrupted data from active time proc: " + time);
                        corrupted = true;
                    } else {
                        curTime += (double) time * 10 / j; // Unit is 10ms.
                    }
                }
                double delta = curTime - mLastUidCpuActiveTimeMs.get(uid, 0.0);
                if (delta > 0 && !corrupted) {
                    mLastUidCpuActiveTimeMs.put(uid, curTime);
                    if (cb != null) {
                        cb.onUidCpuActiveTime(uid, (long) delta);
                    }
                }
                processUid.accept(buf);
            }
            if (DEBUG) {
                Slog.d(TAG, "Read uids: " + numUids);
@@ -123,26 +165,11 @@ public class KernelUidCpuActiveTimeReader extends
        }
    }

    public void readAbsolute(Callback cb) {
        synchronized (mProcReader) {
            readDelta(null);
            int total = mLastUidCpuActiveTimeMs.size();
            for (int i = 0; i < total; i ++){
                int uid = mLastUidCpuActiveTimeMs.keyAt(i);
                cb.onUidCpuActiveTime(uid, mLastUidCpuActiveTimeMs.get(uid).longValue());
            }
        }
    }

    public void removeUid(int uid) {
        mLastUidCpuActiveTimeMs.delete(uid);
    }

    public void removeUidsInRange(int startUid, int endUid) {
        if (endUid < startUid) {
            Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid);
            return;
        }
        mLastUidCpuActiveTimeMs.put(startUid, null);
        mLastUidCpuActiveTimeMs.put(endUid, null);
        final int firstIndex = mLastUidCpuActiveTimeMs.indexOfKey(startUid);
+68 −56

File changed.

Preview size limit exceeded, changes collapsed.

+85 −157

File changed.

Preview size limit exceeded, changes collapsed.

+134 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading