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

Commit a90f9e43 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Battery stats tweaks."

parents e9289573 37de0989
Loading
Loading
Loading
Loading
+150 −69
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@@ -30,6 +31,8 @@ import android.telephony.SignalStrength;
import android.text.format.DateFormat;
import android.util.Printer;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
@@ -537,6 +540,7 @@ public abstract class BatteryStats implements Parcelable {
        public static final byte CMD_START = 4;
        public static final byte CMD_CURRENT_TIME = 5;
        public static final byte CMD_OVERFLOW = 6;
        public static final byte CMD_RESET = 7;

        public byte cmd = CMD_NULL;
        
@@ -620,6 +624,8 @@ public abstract class BatteryStats implements Parcelable {
        public static final int EVENT_SYNC = 0x0004;
        // Number of event types.
        public static final int EVENT_COUNT = 0x0005;
        // Mask to extract out only the type part of the event.
        public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);

        public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
        public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
@@ -684,7 +690,7 @@ public abstract class BatteryStats implements Parcelable {
                dest.writeInt(eventCode);
                eventTag.writeToParcel(dest, flags);
            }
            if (cmd == CMD_CURRENT_TIME) {
            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
                dest.writeLong(currentTime);
            }
        }
@@ -722,7 +728,7 @@ public abstract class BatteryStats implements Parcelable {
                eventCode = EVENT_NONE;
                eventTag = null;
            }
            if (cmd == CMD_CURRENT_TIME) {
            if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
                currentTime = src.readLong();
            } else {
                currentTime = 0;
@@ -834,6 +840,58 @@ public abstract class BatteryStats implements Parcelable {
        }
    }

    public final static class HistoryEventTracker {
        private final HashMap<String, SparseIntArray>[] mActiveEvents
                = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];

        public boolean updateState(int code, String name, int uid, int poolIdx) {
            if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
                int idx = code&HistoryItem.EVENT_TYPE_MASK;
                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
                if (active == null) {
                    active = new HashMap<String, SparseIntArray>();
                    mActiveEvents[idx] = active;
                }
                SparseIntArray uids = active.get(name);
                if (uids == null) {
                    uids = new SparseIntArray();
                    active.put(name, uids);
                }
                if (uids.indexOfKey(uid) >= 0) {
                    // Already set, nothing to do!
                    return false;
                }
                uids.put(uid, poolIdx);
            } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
                int idx = code&HistoryItem.EVENT_TYPE_MASK;
                HashMap<String, SparseIntArray> active = mActiveEvents[idx];
                if (active == null) {
                    // not currently active, nothing to do.
                    return false;
                }
                SparseIntArray uids = active.get(name);
                if (uids == null) {
                    // not currently active, nothing to do.
                    return false;
                }
                idx = uids.indexOfKey(uid);
                if (idx < 0) {
                    // not currently active, nothing to do.
                    return false;
                }
                uids.removeAt(idx);
                if (uids.size() <= 0) {
                    active.remove(name);
                }
            }
            return true;
        }

        public HashMap<String, SparseIntArray> getStateForEvent(int code) {
            return mActiveEvents[code];
        }
    }

    public static final class BitDescription {
        public final int mask;
        public final int shift;
@@ -2958,10 +3016,14 @@ public abstract class BatteryStats implements Parcelable {
                    pw.print(":");
                }
                pw.println("START");
            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
                    || rec.cmd == HistoryItem.CMD_RESET) {
                if (checkin) {
                    pw.print(":");
                }
                if (rec.cmd == HistoryItem.CMD_RESET) {
                    pw.print("RESET:");
                }
                pw.print("TIME:");
                if (checkin) {
                    pw.println(rec.currentTime);
@@ -3187,6 +3249,86 @@ public abstract class BatteryStats implements Parcelable {
    public static final int DUMP_INCLUDE_HISTORY = 1<<3;
    public static final int DUMP_VERBOSE = 1<<4;

    private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
        final HistoryPrinter hprinter = new HistoryPrinter();
        final HistoryItem rec = new HistoryItem();
        long lastTime = -1;
        long baseTime = -1;
        boolean printed = false;
        HistoryEventTracker tracker = null;
        while (getNextHistoryLocked(rec)) {
            lastTime = rec.time;
            if (baseTime < 0) {
                baseTime = lastTime;
            }
            if (rec.time >= histStart) {
                if (histStart >= 0 && !printed) {
                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
                            || rec.cmd == HistoryItem.CMD_RESET) {
                        printed = true;
                    } else if (rec.currentTime != 0) {
                        printed = true;
                        byte cmd = rec.cmd;
                        rec.cmd = HistoryItem.CMD_CURRENT_TIME;
                        if (checkin) {
                            pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                            pw.print(HISTORY_DATA); pw.print(',');
                        }
                        hprinter.printNextItem(pw, rec, baseTime, checkin,
                                (flags&DUMP_VERBOSE) != 0);
                        rec.cmd = cmd;
                    }
                    if (tracker != null) {
                        int oldCode = rec.eventCode;
                        HistoryTag oldTag = rec.eventTag;
                        rec.eventTag = new HistoryTag();
                        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
                            HashMap<String, SparseIntArray> active
                                    = tracker.getStateForEvent(i);
                            if (active == null) {
                                continue;
                            }
                            for (HashMap.Entry<String, SparseIntArray> ent
                                    : active.entrySet()) {
                                SparseIntArray uids = ent.getValue();
                                for (int j=0; j<uids.size(); j++) {
                                    rec.eventCode = i;
                                    rec.eventTag.string = ent.getKey();
                                    rec.eventTag.uid = uids.keyAt(j);
                                    rec.eventTag.poolIdx = uids.valueAt(j);
                                    if (checkin) {
                                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                                        pw.print(HISTORY_DATA); pw.print(',');
                                    }
                                    hprinter.printNextItem(pw, rec, baseTime, checkin,
                                            (flags&DUMP_VERBOSE) != 0);
                                }
                            }
                        }
                        rec.eventCode = oldCode;
                        rec.eventTag = oldTag;
                        tracker = null;
                    }
                }
                if (checkin) {
                    pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                    pw.print(HISTORY_DATA); pw.print(',');
                }
                hprinter.printNextItem(pw, rec, baseTime, checkin,
                        (flags&DUMP_VERBOSE) != 0);
            } else if (rec.eventCode != HistoryItem.EVENT_NONE) {
                if (tracker == null) {
                    tracker = new HistoryEventTracker();
                }
                tracker.updateState(rec.eventCode, rec.eventTag.string,
                        rec.eventTag.uid, rec.eventTag.poolIdx);
            }
        }
        if (histStart >= 0) {
            pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
        }
    }

    /**
     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
     *
@@ -3200,9 +3342,6 @@ public abstract class BatteryStats implements Parcelable {
                (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;

        if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
            long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();

            final HistoryItem rec = new HistoryItem();
            final long historyTotalSize = getHistoryTotalSize();
            final long historyUsedSize = getHistoryUsedSize();
            if (startIteratingHistoryLocked()) {
@@ -3218,35 +3357,7 @@ public abstract class BatteryStats implements Parcelable {
                    pw.print(" strings using ");
                    printSizeValue(pw, getHistoryStringPoolBytes());
                    pw.println("):");
                    HistoryPrinter hprinter = new HistoryPrinter();
                    long lastTime = -1;
                    long baseTime = -1;
                    boolean printed = false;
                    while (getNextHistoryLocked(rec)) {
                        lastTime = rec.time;
                        if (baseTime < 0) {
                            baseTime = lastTime;
                        }
                        if (rec.time >= histStart) {
                            if (histStart >= 0 && !printed) {
                                if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
                                    printed = true;
                                } else if (rec.currentTime != 0) {
                                    printed = true;
                                    byte cmd = rec.cmd;
                                    rec.cmd = HistoryItem.CMD_CURRENT_TIME;
                                    hprinter.printNextItem(pw, rec, baseTime, false,
                                            (flags&DUMP_VERBOSE) != 0);
                                    rec.cmd = cmd;
                                }
                            }
                            hprinter.printNextItem(pw, rec, baseTime, false,
                                    (flags&DUMP_VERBOSE) != 0);
                        }
                    }
                    if (histStart >= 0) {
                        pw.print("  NEXT: "); pw.println(lastTime+1);
                    }
                    dumpHistoryLocked(pw, flags, histStart, false);
                    pw.println();
                } finally {
                    finishIteratingHistoryLocked();
@@ -3255,6 +3366,7 @@ public abstract class BatteryStats implements Parcelable {

            if (startIteratingOldHistoryLocked()) {
                try {
                    final HistoryItem rec = new HistoryItem();
                    pw.println("Old battery History:");
                    HistoryPrinter hprinter = new HistoryPrinter();
                    long baseTime = -1;
@@ -3348,7 +3460,6 @@ public abstract class BatteryStats implements Parcelable {
                (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;

        if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
            final HistoryItem rec = new HistoryItem();
            if (startIteratingHistoryLocked()) {
                try {
                    for (int i=0; i<getHistoryStringPoolSize(); i++) {
@@ -3365,37 +3476,7 @@ public abstract class BatteryStats implements Parcelable {
                        pw.print("\"");
                        pw.println();
                    }
                    HistoryPrinter hprinter = new HistoryPrinter();
                    long lastTime = -1;
                    long baseTime = -1;
                    boolean printed = false;
                    while (getNextHistoryLocked(rec)) {
                        lastTime = rec.time;
                        if (baseTime < 0) {
                            baseTime = lastTime;
                        }
                        if (rec.time >= histStart) {
                            if (histStart >= 0 && !printed) {
                                if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
                                    printed = true;
                                } else if (rec.currentTime != 0) {
                                    printed = true;
                                    byte cmd = rec.cmd;
                                    rec.cmd = HistoryItem.CMD_CURRENT_TIME;
                                    pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                                    pw.print(HISTORY_DATA); pw.print(',');
                                    hprinter.printNextItem(pw, rec, baseTime, true, false);
                                    rec.cmd = cmd;
                                }
                            }
                            pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                            pw.print(HISTORY_DATA); pw.print(',');
                            hprinter.printNextItem(pw, rec, baseTime, true, false);
                        }
                    }
                    if (histStart >= 0) {
                        pw.print("NEXT: "); pw.println(lastTime+1);
                    }
                    dumpHistoryLocked(pw, flags, histStart, true);
                } finally {
                    finishIteratingHistoryLocked();
                }
+29 −53
Original line number Diff line number Diff line
@@ -188,8 +188,7 @@ public final class BatteryStatsImpl extends BatteryStats {

    boolean mShuttingDown;

    HashMap<String, SparseBooleanArray>[] mActiveEvents
            = (HashMap<String, SparseBooleanArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
    final HistoryEventTracker mActiveEvents = new HistoryEventTracker();

    long mHistoryBaseTime;
    boolean mHaveBatteryLevel = false;
@@ -2297,45 +2296,9 @@ public final class BatteryStatsImpl extends BatteryStats {

    public void noteEventLocked(int code, String name, int uid) {
        uid = mapUid(uid);
        if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
            int idx = code&~HistoryItem.EVENT_FLAG_START;
            HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
            if (active == null) {
                active = new HashMap<String, SparseBooleanArray>();
                mActiveEvents[idx] = active;
            }
            SparseBooleanArray uids = active.get(name);
            if (uids == null) {
                uids = new SparseBooleanArray();
                active.put(name, uids);
            }
            if (uids.get(uid)) {
                // Already set, nothing to do!
                return;
            }
            uids.put(uid, true);
        } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
            int idx = code&~HistoryItem.EVENT_FLAG_FINISH;
            HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
            if (active == null) {
                // not currently active, nothing to do.
                return;
            }
            SparseBooleanArray uids = active.get(name);
            if (uids == null) {
                // not currently active, nothing to do.
                return;
            }
            idx = uids.indexOfKey(uid);
            if (idx < 0 || !uids.valueAt(idx)) {
                // not currently active, nothing to do.
        if (!mActiveEvents.updateState(code, name, uid, 0)) {
            return;
        }
            uids.removeAt(idx);
            if (uids.size() <= 0) {
                active.remove(name);
            }
        }
        final long elapsedRealtime = SystemClock.elapsedRealtime();
        final long uptime = SystemClock.uptimeMillis();
        addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
@@ -2348,6 +2311,9 @@ public final class BatteryStatsImpl extends BatteryStats {
        }
    }

    private String mInitialAcquireWakeName;
    private int mInitialAcquireWakeUid = -1;

    public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
            boolean unimportantForLogging, long elapsedRealtime, long uptime) {
        uid = mapUid(uid);
@@ -2360,8 +2326,9 @@ public final class BatteryStatsImpl extends BatteryStats {
                if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
                        + Integer.toHexString(mHistoryCur.states));
                mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
                mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
                mHistoryCur.wakelockTag.uid = uid;
                mHistoryCur.wakelockTag.string = mInitialAcquireWakeName
                        = historyName != null ? historyName : name;
                mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
                mWakeLockImportant = !unimportantForLogging;
                addHistoryRecordLocked(elapsedRealtime, uptime);
            } else if (!mWakeLockImportant && !unimportantForLogging) {
@@ -2369,8 +2336,9 @@ public final class BatteryStatsImpl extends BatteryStats {
                    // We'll try to update the last tag.
                    mHistoryLastWritten.wakelockTag = null;
                    mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
                    mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
                    mHistoryCur.wakelockTag.uid = uid;
                    mHistoryCur.wakelockTag.string = mInitialAcquireWakeName
                            = historyName != null ? historyName : name;
                    mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
                    addHistoryRecordLocked(elapsedRealtime, uptime);
                }
                mWakeLockImportant = true;
@@ -2395,6 +2363,14 @@ public final class BatteryStatsImpl extends BatteryStats {
                mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
                if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
                        + Integer.toHexString(mHistoryCur.states));
                if ((name != null && !name.equals(mInitialAcquireWakeName))
                        || uid != mInitialAcquireWakeUid) {
                    mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
                    mHistoryCur.wakelockTag.string = name;
                    mHistoryCur.wakelockTag.uid = uid;
                }
                mInitialAcquireWakeName = null;
                mInitialAcquireWakeUid = -1;
                addHistoryRecordLocked(elapsedRealtime, uptime);
            }
        }
@@ -5699,7 +5675,8 @@ public final class BatteryStatsImpl extends BatteryStats {
        final long lastRealtime = out.time;
        final long lastWalltime = out.currentTime;
        readHistoryDelta(mHistoryBuffer, out);
        if (out.cmd != HistoryItem.CMD_CURRENT_TIME && lastWalltime != 0) {
        if (out.cmd != HistoryItem.CMD_CURRENT_TIME
                && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
            out.currentTime = lastWalltime + (out.time - lastRealtime);
        }
        return true;
@@ -5845,21 +5822,19 @@ public final class BatteryStatsImpl extends BatteryStats {

    private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
            HashMap<String, SparseBooleanArray> active = mActiveEvents[i];
            HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
            if (active == null) {
                continue;
            }
            for (HashMap.Entry<String, SparseBooleanArray> ent : active.entrySet()) {
                SparseBooleanArray uids = ent.getValue();
            for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
                SparseIntArray uids = ent.getValue();
                for (int j=0; j<uids.size(); j++) {
                    if (uids.valueAt(j)) {
                    addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
                            uids.keyAt(j));
                }
            }
        }
    }
    }

    void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
        if (oldScreenOn) {
@@ -5971,7 +5946,8 @@ public final class BatteryStatsImpl extends BatteryStats {
            boolean reset) {
        mRecordingHistory = true;
        mHistoryCur.currentTime = System.currentTimeMillis();
        addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
        addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
                reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
                mHistoryCur);
        mHistoryCur.currentTime = 0;
        if (reset) {