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

Commit 14b57010 authored by Adam Lesinski's avatar Adam Lesinski Committed by Android (Google) Code Review
Browse files

Merge "BatteryStats: Record cpu power usage from /proc/uid_cputime" into mnc-dev

parents ca2f2fed a7a4cccf
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ public abstract class BatteryStats implements Parcelable {
    private static final String UID_DATA = "uid";
    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 SENSOR_DATA = "sr";
    private static final String VIBRATOR_DATA = "vib";
    private static final String FOREGROUND_DATA = "fg";
@@ -456,9 +457,14 @@ public abstract class BatteryStats implements Parcelable {
         */
        public abstract long getSystemCpuTimeUs(int which);

        /**
         * Get the total cpu power consumed (in milli-ampere-microseconds).
         */
        public abstract long getCpuPowerMaUs(int which);

        /**
         * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
         * @param speedStep the index of the CPU speed. This is not the actual speed of the CPU.
         * @param step the index of the CPU speed. This is not the actual speed of the CPU.
         * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
         * @see BatteryStats#getCpuSpeedSteps()
         */
@@ -2905,6 +2911,14 @@ public abstract class BatteryStats implements Parcelable {
                dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
            }

            final long userCpuTimeUs = u.getUserCpuTimeUs(which);
            final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
            final long powerCpuMaUs = u.getCpuPowerMaUs(which);
            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
                dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000,
                        powerCpuMaUs / 1000);
            }

            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
                    = u.getProcessStats();
            for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
@@ -2970,6 +2984,10 @@ public abstract class BatteryStats implements Parcelable {
        printer.print(BatteryStatsHelper.makemAh(power));
    }

    private void printmAh(StringBuilder sb, double power) {
        sb.append(BatteryStatsHelper.makemAh(power));
    }

    /**
     * Temporary for settings.
     */
@@ -4028,13 +4046,17 @@ public abstract class BatteryStats implements Parcelable {

            final long userCpuTimeUs = u.getUserCpuTimeUs(which);
            final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
            final long powerCpuMaUs = u.getCpuPowerMaUs(which);
            if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
                sb.setLength(0);
                sb.append(prefix);
                sb.append("    Total cpu time: u=");
                formatTimeMs(sb, userCpuTimeUs / 1000);
                sb.append("s=");
                formatTimeMs(sb, systemCpuTimeUs / 1000);
                sb.append("p=");
                printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0));
                sb.append("mAh");
                pw.println(sb.toString());
            }

+18 −3
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ public final class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'

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

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

        LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
        LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
        LongSamplingCounter mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase);
        LongSamplingCounter[] mSpeedBins;

        /**
@@ -4977,6 +4978,11 @@ public final class BatteryStatsImpl extends BatteryStats {
            return mSystemCpuTime.getCountLocked(which);
        }

        @Override
        public long getCpuPowerMaUs(int which) {
            return mCpuPower.getCountLocked(which);
        }

        @Override
        public long getTimeAtCpuSpeed(int step, int which) {
            if (step >= 0 && step < mSpeedBins.length) {
@@ -5097,6 +5103,7 @@ public final class BatteryStatsImpl extends BatteryStats {

            mUserCpuTime.reset(false);
            mSystemCpuTime.reset(false);
            mCpuPower.reset(false);
            for (int i = 0; i < mSpeedBins.length; i++) {
                LongSamplingCounter c = mSpeedBins[i];
                if (c != null) {
@@ -5248,6 +5255,7 @@ public final class BatteryStatsImpl extends BatteryStats {

                mUserCpuTime.detach();
                mSystemCpuTime.detach();
                mCpuPower.detach();
                for (int i = 0; i < mSpeedBins.length; i++) {
                    LongSamplingCounter c = mSpeedBins[i];
                    if (c != null) {
@@ -5427,6 +5435,7 @@ public final class BatteryStatsImpl extends BatteryStats {

            mUserCpuTime.writeToParcel(out);
            mSystemCpuTime.writeToParcel(out);
            mCpuPower.writeToParcel(out);

            out.writeInt(mSpeedBins.length);
            for (int i = 0; i < mSpeedBins.length; i++) {
@@ -5618,6 +5627,7 @@ public final class BatteryStatsImpl extends BatteryStats {

            mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
            mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
            mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase, in);

            int bins = in.readInt();
            int steps = getCpuSpeedSteps();
@@ -7964,7 +7974,8 @@ public final class BatteryStatsImpl extends BatteryStats {
        mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null :
                new KernelUidCpuTimeReader.Callback() {
                    @Override
                    public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
                    public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs,
                                             long powerMaUs) {
                        final Uid u = getUidStatsLocked(mapUid(uid));

                        // Accumulate the total system and user time.
@@ -7978,7 +7989,7 @@ public final class BatteryStatsImpl extends BatteryStats {
                            TimeUtils.formatDuration(userTimeUs / 1000, sb);
                            sb.append(" s=");
                            TimeUtils.formatDuration(systemTimeUs / 1000, sb);
                            sb.append("\n");
                            sb.append(" p=").append(powerMaUs / 1000).append("mAms\n");
                        }

                        if (numWakelocksF > 0) {
@@ -7994,11 +8005,13 @@ public final class BatteryStatsImpl extends BatteryStats {
                            TimeUtils.formatDuration(userTimeUs / 1000, sb);
                            sb.append(" s=");
                            TimeUtils.formatDuration(systemTimeUs / 1000, sb);
                            sb.append(" p=").append(powerMaUs / 1000).append("mAms");
                            Slog.d(TAG, sb.toString());
                        }

                        u.mUserCpuTime.addCountLocked(userTimeUs);
                        u.mSystemCpuTime.addCountLocked(systemTimeUs);
                        u.mCpuPower.addCountLocked(powerMaUs);

                        // Add the cpu speeds to this UID. These are used as a ratio
                        // for computing the power this UID used.
@@ -9229,6 +9242,7 @@ public final class BatteryStatsImpl extends BatteryStats {

            u.mUserCpuTime.readSummaryFromParcelLocked(in);
            u.mSystemCpuTime.readSummaryFromParcelLocked(in);
            u.mCpuPower.readSummaryFromParcelLocked(in);

            int NSB = in.readInt();
            if (NSB > 100) {
@@ -9575,6 +9589,7 @@ public final class BatteryStatsImpl extends BatteryStats {

            u.mUserCpuTime.writeSummaryFromParcelLocked(out);
            u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
            u.mCpuPower.writeSummaryFromParcelLocked(out);

            out.writeInt(u.mSpeedBins.length);
            for (int i = 0; i < u.mSpeedBins.length; i++) {
+31 −14
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import java.io.IOException;
/**
 * Reads /proc/uid_cputime/show_uid_stat which has the line format:
 *
 * uid: user_time_micro_seconds system_time_micro_seconds
 * uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-micro_seconds
 *
 * This provides the time a UID's processes spent executing in user-space and kernel-space.
 * The file contains a monotonically increasing count of time for a single boot. This class
@@ -46,11 +46,18 @@ public class KernelUidCpuTimeReader {
     * Callback interface for processing each line of the proc file.
     */
    public interface Callback {
        void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
        /**
         * @param uid UID of the app
         * @param userTimeUs time spent executing in user space in microseconds
         * @param systemTimeUs time spent executing in kernel space in microseconds
         * @param powerMaUs power consumed executing, in milli-ampere microseconds
         */
        void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs, long powerMaUs);
    }

    private SparseLongArray mLastUserTimeUs = new SparseLongArray();
    private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
    private SparseLongArray mLastPowerMaUs = new SparseLongArray();
    private long mLastTimeReadUs = 0;

    /**
@@ -70,50 +77,60 @@ public class KernelUidCpuTimeReader {
                final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10);
                final long userTimeUs = Long.parseLong(splitter.next(), 10);
                final long systemTimeUs = Long.parseLong(splitter.next(), 10);
                final long powerMaUs = Long.parseLong(splitter.next(), 10) / 1000;

                if (callback != null) {
                    long userTimeDeltaUs = userTimeUs;
                    long systemTimeDeltaUs = systemTimeUs;
                    long powerDeltaMaUs = powerMaUs;
                    int index = mLastUserTimeUs.indexOfKey(uid);
                    if (index >= 0) {
                        userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
                        systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
                        powerDeltaMaUs -= mLastPowerMaUs.valueAt(index);

                        final long timeDiffUs = nowUs - mLastTimeReadUs;
                        if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 ||
                        if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 || powerDeltaMaUs < 0 ||
                                userTimeDeltaUs > timeDiffUs || systemTimeDeltaUs > timeDiffUs) {
                            StringBuilder sb = new StringBuilder("Malformed cpu data!\n");
                            StringBuilder sb = new StringBuilder("Malformed cpu data for UID=");
                            sb.append(uid).append("!\n");
                            sb.append("Time between reads: ");
                            TimeUtils.formatDuration(timeDiffUs / 1000, sb);
                            sb.append("ms\n");
                            sb.append("\n");
                            sb.append("Previous times: u=");
                            TimeUtils.formatDuration(mLastUserTimeUs.valueAt(index) / 1000, sb);
                            sb.append("ms s=");
                            sb.append(" s=");
                            TimeUtils.formatDuration(mLastSystemTimeUs.valueAt(index) / 1000, sb);
                            sb.append("ms\n");
                            sb.append(" p=").append(mLastPowerMaUs.valueAt(index) / 1000);
                            sb.append("mAms\n");

                            sb.append("Current times: u=");
                            TimeUtils.formatDuration(userTimeUs / 1000, sb);
                            sb.append("ms s=");
                            sb.append(" s=");
                            TimeUtils.formatDuration(systemTimeUs / 1000, sb);
                            sb.append("ms\n");
                            sb.append("Delta for UID=").append(uid).append(": u=");
                            sb.append(" p=").append(powerMaUs / 1000);
                            sb.append("mAms\n");
                            sb.append("Delta: u=");
                            TimeUtils.formatDuration(userTimeDeltaUs / 1000, sb);
                            sb.append("ms s=");
                            sb.append(" s=");
                            TimeUtils.formatDuration(systemTimeDeltaUs / 1000, sb);
                            sb.append("ms");
                            sb.append(" p=").append(powerDeltaMaUs / 1000).append("mAms");
                            Slog.wtf(TAG, sb.toString());

                            userTimeDeltaUs = 0;
                            systemTimeDeltaUs = 0;
                            powerDeltaMaUs = 0;
                        }
                    }

                    if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0) {
                        callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs);
                    if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0 || powerDeltaMaUs != 0) {
                        callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs,
                                powerDeltaMaUs);
                    }
                }
                mLastUserTimeUs.put(uid, userTimeUs);
                mLastSystemTimeUs.put(uid, systemTimeUs);
                mLastPowerMaUs.put(uid, powerMaUs);
            }
        } catch (IOException e) {
            Slog.e(TAG, "Failed to read uid_cputime", e);