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

Commit 1639c330 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Resolve STATSD and batterystats race condition" into pi-dev

parents 75cd1c03 234d1828
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