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

Commit 5df9c557 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Add time spent by uid per cpu frequency to batterystats." into oc-dev

parents 3ad8c93e 9b735c5c
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
@@ -203,6 +203,8 @@ public abstract class BatteryStats implements Parcelable {
    private static final String APK_DATA = "apk";
    private static final String PROCESS_DATA = "pr";
    private static final String CPU_DATA = "cpu";
    private static final String GLOBAL_CPU_FREQ_DATA = "gcf";
    private static final String CPU_TIMES_AT_FREQ_DATA = "ctf";
    private static final String SENSOR_DATA = "sr";
    private static final String VIBRATOR_DATA = "vib";
    private static final String FOREGROUND_DATA = "fg";
@@ -264,6 +266,13 @@ public abstract class BatteryStats implements Parcelable {
    private final StringBuilder mFormatBuilder = new StringBuilder(32);
    private final Formatter mFormatter = new Formatter(mFormatBuilder);

    /**
     * Indicates times spent by the uid at each cpu frequency in all process states.
     *
     * Other types might include times spent in foreground, background etc.
     */
    private final String UID_TIMES_TYPE_ALL = "A";

    /**
     * State for keeping track of counting information.
     */
@@ -302,6 +311,24 @@ public abstract class BatteryStats implements Parcelable {
        public abstract void logState(Printer pw, String prefix);
    }

    /**
     * State for keeping track of array of long counting information.
     */
    public static abstract class LongCounterArray {
        /**
         * Returns the counts associated with this Counter for the
         * selected type of statistics.
         *
         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
         */
        public abstract long[] getCountsLocked(int which);

        /**
         * Temporary for debugging.
         */
        public abstract void logState(Printer pw, String prefix);
    }

    /**
     * Container class that aggregates counters for transmit, receive, and idle state of a
     * radio controller.
@@ -523,6 +550,9 @@ public abstract class BatteryStats implements Parcelable {
        public abstract Timer getBluetoothScanBackgroundTimer();
        public abstract Counter getBluetoothScanResultCounter();

        public abstract long[] getCpuFreqTimes(int which);
        public abstract long[] getScreenOffCpuFreqTimes(int which);

        // Note: the following times are disjoint.  They can be added together to find the
        // total time a uid has had any processes running at all.

@@ -1077,6 +1107,8 @@ public abstract class BatteryStats implements Parcelable {

    public abstract long getNextMaxDailyDeadline();

    public abstract long[] getCpuFreqs();

    public final static class HistoryTag {
        public String string;
        public int uid;
@@ -3274,6 +3306,15 @@ public abstract class BatteryStats implements Parcelable {
            }
        }

        final long[] cpuFreqs = getCpuFreqs();
        if (cpuFreqs != null) {
            sb.setLength(0);
            for (int i = 0; i < cpuFreqs.length; ++i) {
                sb.append((i == 0 ? "" : ",") + cpuFreqs[i]);
            }
            dumpLine(pw, 0 /* uid */, category, GLOBAL_CPU_FREQ_DATA, sb.toString());
        }

        for (int iu = 0; iu < NU; iu++) {
            final int uid = uidStats.keyAt(iu);
            if (reqUid >= 0 && uid != reqUid) {
@@ -3506,6 +3547,27 @@ public abstract class BatteryStats implements Parcelable {
                        0 /* old cpu power, keep for compatibility */);
            }

            final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
            // If total cpuFreqTimes is null, then we don't need to check for screenOffCpuFreqTimes.
            if (cpuFreqTimeMs != null) {
                sb.setLength(0);
                for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
                    sb.append((i == 0 ? "" : ",") + cpuFreqTimeMs[i]);
                }
                final long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
                if (screenOffCpuFreqTimeMs != null) {
                    for (int i = 0; i < screenOffCpuFreqTimeMs.length; ++i) {
                        sb.append("," + screenOffCpuFreqTimeMs[i]);
                    }
                } else {
                    for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
                        sb.append(",0");
                    }
                }
                dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA, UID_TIMES_TYPE_ALL,
                        cpuFreqTimeMs.length, sb.toString());
            }

            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
                    = u.getProcessStats();
            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
@@ -4373,6 +4435,16 @@ public abstract class BatteryStats implements Parcelable {
            pw.println(sb.toString());
        }

        final long[] cpuFreqs = getCpuFreqs();
        if (cpuFreqs != null) {
            sb.setLength(0);
            sb.append("CPU freqs:");
            for (int i = 0; i < cpuFreqs.length; ++i) {
                sb.append(" " + cpuFreqs[i]);
            }
            pw.println(sb.toString());
        }

        for (int iu=0; iu<NU; iu++) {
            final int uid = uidStats.keyAt(iu);
            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
@@ -4835,6 +4907,25 @@ public abstract class BatteryStats implements Parcelable {
                pw.println(sb.toString());
            }

            final long[] cpuFreqTimes = u.getCpuFreqTimes(which);
            if (cpuFreqTimes != null) {
                sb.setLength(0);
                sb.append("    Total cpu time per freq:");
                for (int i = 0; i < cpuFreqTimes.length; ++i) {
                    sb.append(" " + cpuFreqTimes[i]);
                }
                pw.println(sb.toString());
            }
            final long[] screenOffCpuFreqTimes = u.getScreenOffCpuFreqTimes(which);
            if (screenOffCpuFreqTimes != null) {
                sb.setLength(0);
                sb.append("    Total screen-off cpu time per freq:");
                for (int i = 0; i < screenOffCpuFreqTimes.length; ++i) {
                    sb.append(" " + screenOffCpuFreqTimes[i]);
                }
                pw.println(sb.toString());
            }

            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
                    = u.getProcessStats();
            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
+275 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.os;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.bluetooth.BluetoothActivityEnergyInfo;
@@ -87,6 +88,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
@@ -114,7 +116,7 @@ public class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'

    // Current on-disk Parcel version
    private static final int VERSION = 156 + (USE_OLD_HISTORY ? 1000 : 0);
    private static final int VERSION = 157 + (USE_OLD_HISTORY ? 1000 : 0);

    // Maximum number of items we will record in the history.
    private static final int MAX_HISTORY_ITEMS = 2000;
@@ -149,6 +151,8 @@ public class BatteryStatsImpl extends BatteryStats {

    private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
    private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
    private final KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader =
            new KernelUidCpuFreqTimeReader();

    private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats
            = new KernelMemoryBandwidthStats();
@@ -570,6 +574,8 @@ public class BatteryStatsImpl extends BatteryStats {

    private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();

    private long[] mCpuFreqs;

    private PowerProfile mPowerProfile;

    /*
@@ -957,6 +963,131 @@ public class BatteryStatsImpl extends BatteryStats {
        }
    }

    public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs {
        final TimeBase mTimeBase;
        long[] mCounts;
        long[] mLoadedCounts;
        long[] mUnpluggedCounts;
        long[] mPluggedCounts;

        LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
            mTimeBase = timeBase;
            mPluggedCounts = in.createLongArray();
            mCounts = copyArray(mPluggedCounts, mCounts);
            mLoadedCounts = in.createLongArray();
            mUnpluggedCounts = in.createLongArray();
            timeBase.add(this);
        }

        LongSamplingCounterArray(TimeBase timeBase) {
            mTimeBase = timeBase;
            timeBase.add(this);
        }

        public void writeToParcel(Parcel out) {
            out.writeLongArray(mCounts);
            out.writeLongArray(mLoadedCounts);
            out.writeLongArray(mUnpluggedCounts);
        }

        @Override
        public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
            mUnpluggedCounts = copyArray(mPluggedCounts, mUnpluggedCounts);
            mCounts = copyArray(mPluggedCounts, mCounts);
        }

        @Override
        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
            mPluggedCounts = copyArray(mCounts, mPluggedCounts);
        }

        @Override
        public long[] getCountsLocked(int which) {
            long[] val = copyArray(mTimeBase.isRunning() ? mCounts : mPluggedCounts, null);
            if (which == STATS_SINCE_UNPLUGGED) {
                subtract(val, mUnpluggedCounts);
            } else if (which != STATS_SINCE_CHARGED) {
                subtract(val, mLoadedCounts);
            }
            return val;
        }

        @Override
        public void logState(Printer pw, String prefix) {
            pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)
                    + " mLoadedCounts=" + Arrays.toString(mLoadedCounts)
                    + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts)
                    + " mPluggedCounts=" + Arrays.toString(mPluggedCounts));
        }

        void addCountLocked(long[] counts) {
            if (counts == null) {
                return;
            }
            if (mCounts == null) {
                mCounts = new long[counts.length];
            }
            for (int i = 0; i < counts.length; ++i) {
                mCounts[i] += counts[i];
            }
        }

        /**
         * Clear state of this counter.
         */
        void reset(boolean detachIfReset) {
            fillArray(mCounts, 0);
            fillArray(mLoadedCounts, 0);
            fillArray(mPluggedCounts, 0);
            fillArray(mUnpluggedCounts, 0);
            if (detachIfReset) {
                detach();
            }
        }

        void detach() {
            mTimeBase.remove(this);
        }

        void writeSummaryFromParcelLocked(Parcel out) {
            out.writeLongArray(mCounts);
        }

        void readSummaryFromParcelLocked(Parcel in) {
            mCounts = in.createLongArray();
            mLoadedCounts = copyArray(mCounts, mLoadedCounts);
            mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
            mPluggedCounts = copyArray(mCounts, mPluggedCounts);
        }

        private void fillArray(long[] a, long val) {
            if (a != null) {
                Arrays.fill(a, val);
            }
        }

        private void subtract(@NonNull long[] val, long[] toSubtract) {
            if (toSubtract == null) {
                return;
            }
            for (int i = 0; i < val.length; i++) {
                val[i] -= toSubtract[i];
            }
        }

        private long[] copyArray(long[] src, long[] dest) {
            if (src == null) {
                return null;
            } else {
                if (dest == null) {
                    dest = new long[src.length];
                }
                System.arraycopy(src, 0, dest, 0, src.length);
                return dest;
            }
        }
    }

    public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
        final TimeBase mTimeBase;
        long mCount;
@@ -5483,6 +5614,9 @@ public class BatteryStatsImpl extends BatteryStats {
        LongSamplingCounter mSystemCpuTime;
        LongSamplingCounter[][] mCpuClusterSpeed;

        LongSamplingCounterArray mCpuFreqTimeMs;
        LongSamplingCounterArray mScreenOffCpuFreqTimeMs;

        /**
         * The statistics we have collected for this uid's wake locks.
         */
@@ -5559,6 +5693,42 @@ public class BatteryStatsImpl extends BatteryStats {
            mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
        }

        @Override
        public long[] getCpuFreqTimes(int which) {
            if (mCpuFreqTimeMs == null) {
                return null;
            }
            final long[] cpuFreqTimes = mCpuFreqTimeMs.getCountsLocked(which);
            if (cpuFreqTimes == null) {
                return null;
            }
            // Return cpuFreqTimes only if atleast one of the elements in non-zero.
            for (int i = 0; i < cpuFreqTimes.length; ++i) {
                if (cpuFreqTimes[i] != 0) {
                    return cpuFreqTimes;
                }
            }
            return null;
        }

        @Override
        public long[] getScreenOffCpuFreqTimes(int which) {
            if (mScreenOffCpuFreqTimeMs == null) {
                return null;
            }
            final long[] cpuFreqTimes = mScreenOffCpuFreqTimeMs.getCountsLocked(which);
            if (cpuFreqTimes == null) {
                return null;
            }
            // Return cpuFreqTimes only if atleast one of the elements in non-zero.
            for (int i = 0; i < cpuFreqTimes.length; ++i) {
                if (cpuFreqTimes[i] != 0) {
                    return cpuFreqTimes;
                }
            }
            return null;
        }

        @Override
        public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
            return mWakelockStats.getMap();
@@ -6354,6 +6524,13 @@ public class BatteryStatsImpl extends BatteryStats {
                }
            }

            if (mCpuFreqTimeMs != null) {
                mCpuFreqTimeMs.reset(false);
            }
            if (mScreenOffCpuFreqTimeMs != null) {
                mScreenOffCpuFreqTimeMs.reset(false);
            }

            resetLongCounterIfNotNull(mMobileRadioApWakeupCount, false);
            resetLongCounterIfNotNull(mWifiRadioApWakeupCount, false);

@@ -6523,6 +6700,13 @@ public class BatteryStatsImpl extends BatteryStats {
                    }
                }

                if (mCpuFreqTimeMs != null) {
                    mCpuFreqTimeMs.detach();
                }
                if (mScreenOffCpuFreqTimeMs != null) {
                    mScreenOffCpuFreqTimeMs.detach();
                }

                detachLongCounterIfNotNull(mMobileRadioApWakeupCount);
                detachLongCounterIfNotNull(mWifiRadioApWakeupCount);
            }
@@ -6739,6 +6923,19 @@ public class BatteryStatsImpl extends BatteryStats {
                out.writeInt(0);
            }

            if (mCpuFreqTimeMs != null) {
                out.writeInt(1);
                mCpuFreqTimeMs.writeToParcel(out);
            } else {
                out.writeInt(0);
            }
            if (mScreenOffCpuFreqTimeMs != null) {
                out.writeInt(1);
                mScreenOffCpuFreqTimeMs.writeToParcel(out);
            } else {
                out.writeInt(0);
            }

            if (mMobileRadioApWakeupCount != null) {
                out.writeInt(1);
                mMobileRadioApWakeupCount.writeToParcel(out);
@@ -6986,6 +7183,18 @@ public class BatteryStatsImpl extends BatteryStats {
                mCpuClusterSpeed = null;
            }

            if (in.readInt() != 0) {
                mCpuFreqTimeMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in);
            } else {
                mCpuFreqTimeMs = null;
            }
            if (in.readInt() != 0) {
                mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
                        mBsi.mOnBatteryScreenOffTimeBase, in);
            } else {
                mScreenOffCpuFreqTimeMs = null;
            }

            if (in.readInt() != 0) {
                mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
            } else {
@@ -8192,6 +8401,10 @@ public class BatteryStatsImpl extends BatteryStats {
        }
    }

    public long[] getCpuFreqs() {
        return mCpuFreqs;
    }

    public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
        this(new SystemClocks(), systemDir, handler, externalSync, null);
    }
@@ -9812,6 +10025,8 @@ public class BatteryStatsImpl extends BatteryStats {
                    }
                });

        readKernelUidCpuFreqTimesLocked();

        final long elapse = (mClocks.elapsedRealtime() - startTimeMs);
        if (DEBUG_ENERGY_CPU || (elapse >= 100)) {
            Slog.d(TAG, "Reading cpu stats took " + elapse + " ms");
@@ -9900,6 +10115,30 @@ public class BatteryStatsImpl extends BatteryStats {
        }
    }

    void readKernelUidCpuFreqTimesLocked() {
        mKernelUidCpuFreqTimeReader.readDelta(!mOnBatteryInternal ? null :
                new KernelUidCpuFreqTimeReader.Callback() {
                    @Override
                    public void onCpuFreqs(long[] cpuFreqs) {
                        mCpuFreqs = cpuFreqs;
                    }

                    @Override
                    public void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs) {
                        final Uid u = getUidStatsLocked(uid);
                        if (u.mCpuFreqTimeMs == null) {
                            u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
                        }
                        u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs);
                        if (u.mScreenOffCpuFreqTimeMs == null) {
                            u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
                                    mOnBatteryScreenOffTimeBase);
                        }
                        u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs);
                    }
                });
    }

    boolean setChargingLocked(boolean charging) {
        if (mCharging != charging) {
            mCharging = charging;
@@ -10988,6 +11227,8 @@ public class BatteryStatsImpl extends BatteryStats {
            }
        }

        mCpuFreqs = in.createLongArray();

        final int NU = in.readInt();
        if (NU > 10000) {
            throw new ParcelFormatException("File corrupt: too many uids " + NU);
@@ -11110,6 +11351,20 @@ public class BatteryStatsImpl extends BatteryStats {
                u.mCpuClusterSpeed = null;
            }

            if (in.readInt() != 0) {
                u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
                u.mCpuFreqTimeMs.readSummaryFromParcelLocked(in);
            } else {
                u.mCpuFreqTimeMs = null;
            }
            if (in.readInt() != 0) {
                u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
                        mOnBatteryScreenOffTimeBase);
                u.mScreenOffCpuFreqTimeMs.readSummaryFromParcelLocked(in);
            } else {
                u.mScreenOffCpuFreqTimeMs = null;
            }

            if (in.readInt() != 0) {
                u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
                u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in);
@@ -11360,6 +11615,8 @@ public class BatteryStatsImpl extends BatteryStats {
            }
        }

        out.writeLongArray(mCpuFreqs);

        final int NU = mUidStats.size();
        out.writeInt(NU);
        for (int iu = 0; iu < NU; iu++) {
@@ -11504,6 +11761,19 @@ public class BatteryStatsImpl extends BatteryStats {
                out.writeInt(0);
            }

            if (u.mCpuFreqTimeMs != null) {
                out.writeInt(1);
                u.mCpuFreqTimeMs.writeSummaryFromParcelLocked(out);
            } else {
                out.writeInt(0);
            }
            if (u.mScreenOffCpuFreqTimeMs != null) {
                out.writeInt(1);
                u.mScreenOffCpuFreqTimeMs.writeSummaryFromParcelLocked(out);
            } else {
                out.writeInt(0);
            }

            if (u.mMobileRadioApWakeupCount != null) {
                out.writeInt(1);
                u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out);
@@ -11794,6 +12064,8 @@ public class BatteryStatsImpl extends BatteryStats {
        mFlashlightTurnedOnTimers.clear();
        mCameraTurnedOnTimers.clear();

        mCpuFreqs = in.createLongArray();

        int numUids = in.readInt();
        mUidStats.clear();
        for (int i = 0; i < numUids; i++) {
@@ -11953,6 +12225,8 @@ public class BatteryStatsImpl extends BatteryStats {
            }
        }

        out.writeLongArray(mCpuFreqs);

        if (inclUids) {
            int size = mUidStats.size();
            out.writeInt(size);
+117 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.annotation.Nullable;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Reads /proc/uid_time_in_state which has the format:
 *
 * uid: [freq1] [freq2] [freq3] ...
 * [uid1]: [time in freq1] [time in freq2] [time in freq3] ...
 * [uid2]: [time in freq1] [time in freq2] [time in freq3] ...
 * ...
 *
 * This provides the times a UID's processes spent executing at each different cpu frequency.
 * 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.
 */
public class KernelUidCpuFreqTimeReader {
    private static final String TAG = "KernelUidCpuFreqTimeReader";
    private static final String UID_TIMES_PROC_FILE = "/proc/uid_time_in_state";

    public interface Callback {
        void onCpuFreqs(long[] cpuFreqs);
        void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs);
    }

    private long[] mCpuFreqs;
    private int mCpuFreqsCount;

    private SparseArray<long[]> mLastUidCpuFreqTimeMs = new SparseArray<>();

    public void readDelta(@Nullable Callback callback) {
        try (BufferedReader reader = new BufferedReader(new FileReader(UID_TIMES_PROC_FILE))) {
            readDelta(reader, callback);
        } catch (IOException e) {
            Slog.e(TAG, "Failed to read " + UID_TIMES_PROC_FILE + ": " + e);
        }
    }

    @VisibleForTesting
    public void readDelta(BufferedReader reader, @Nullable Callback callback) throws IOException {
        String line = reader.readLine();
        if (line == null) {
            return;
        }
        readCpuFreqs(line, callback);
        while ((line = reader.readLine()) != null) {
            final int index = line.indexOf(' ');
            final int uid = Integer.parseInt(line.substring(0, index - 1), 10);
            readTimesForUid(uid, line.substring(index + 1, line.length()), callback);
        }
    }

    private void readTimesForUid(int uid, String line, Callback callback) {
        long[] uidTimeMs = mLastUidCpuFreqTimeMs.get(uid);
        if (uidTimeMs == null) {
            uidTimeMs = new long[mCpuFreqsCount];
            mLastUidCpuFreqTimeMs.put(uid, uidTimeMs);
        }
        final String[] timesStr = line.split(" ");
        final int size = timesStr.length;
        if (size != uidTimeMs.length) {
            Slog.e(TAG, "No. of readings don't match cpu freqs, readings: " + size
                    + " cpuFreqsCount: " + uidTimeMs.length);
            return;
        }
        final long[] deltaUidTimeMs = new long[size];
        for (int i = 0; i < size; ++i) {
            // Times read will be in units of 10ms
            final long totalTimeMs = Long.parseLong(timesStr[i], 10) * 10;
            deltaUidTimeMs[i] = totalTimeMs - uidTimeMs[i];
            uidTimeMs[i] = totalTimeMs;
        }
        if (callback != null) {
            callback.onUidCpuFreqTime(uid, deltaUidTimeMs);
        }
    }

    private void readCpuFreqs(String line, Callback callback) {
        if (mCpuFreqs == null) {
            final String[] freqStr = line.split(" ");
            // First item would be "uid:" which needs to be ignored
            mCpuFreqsCount = freqStr.length - 1;
            mCpuFreqs = new long[mCpuFreqsCount];
            for (int i = 0; i < mCpuFreqsCount; ++i) {
                mCpuFreqs[i] = Long.parseLong(freqStr[i + 1], 10);
            }
        }
        if (callback != null) {
            callback.onCpuFreqs(mCpuFreqs);
        }
    }
}
+109 −0

File added.

Preview size limit exceeded, changes collapsed.