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

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

Merge "Rewrite battery history storage."

parents 81f66862 0ffc988a
Loading
Loading
Loading
Loading
+171 −127
Original line number Original line Diff line number Diff line
@@ -412,6 +412,7 @@ public abstract class BatteryStats implements Parcelable {
        
        
        public long time;
        public long time;
        
        
        public static final byte CMD_NULL = -1;
        public static final byte CMD_UPDATE = 0;
        public static final byte CMD_UPDATE = 0;
        public static final byte CMD_START = 1;
        public static final byte CMD_START = 1;
        public static final byte CMD_OVERFLOW = 2;
        public static final byte CMD_OVERFLOW = 2;
@@ -466,16 +467,7 @@ public abstract class BatteryStats implements Parcelable {
        
        
        public HistoryItem(long time, Parcel src) {
        public HistoryItem(long time, Parcel src) {
            this.time = time;
            this.time = time;
            int bat = src.readInt();
            readFromParcel(src);
            cmd = (byte)(bat&0xff);
            batteryLevel = (byte)((bat>>8)&0xff);
            batteryStatus = (byte)((bat>>16)&0xf);
            batteryHealth = (byte)((bat>>20)&0xf);
            batteryPlugType = (byte)((bat>>24)&0xf);
            bat = src.readInt();
            batteryTemperature = (char)(bat&0xffff);
            batteryVoltage = (char)((bat>>16)&0xffff);
            states = src.readInt();
        }
        }
        
        
        public int describeContents() {
        public int describeContents() {
@@ -496,6 +488,28 @@ public abstract class BatteryStats implements Parcelable {
            dest.writeInt(states);
            dest.writeInt(states);
        }
        }
        
        
        public void writeDelta(Parcel dest, HistoryItem last) {
            writeToParcel(dest, 0);
        }

        private void readFromParcel(Parcel src) {
            int bat = src.readInt();
            cmd = (byte)(bat&0xff);
            batteryLevel = (byte)((bat>>8)&0xff);
            batteryStatus = (byte)((bat>>16)&0xf);
            batteryHealth = (byte)((bat>>20)&0xf);
            batteryPlugType = (byte)((bat>>24)&0xf);
            bat = src.readInt();
            batteryTemperature = (char)(bat&0xffff);
            batteryVoltage = (char)((bat>>16)&0xffff);
            states = src.readInt();
        }

        public void readDelta(Parcel src, HistoryItem last) {
            time = src.readLong();
            readFromParcel(src);
        }

        public void setTo(HistoryItem o) {
        public void setTo(HistoryItem o) {
            time = o.time;
            time = o.time;
            cmd = o.cmd;
            cmd = o.cmd;
@@ -556,10 +570,13 @@ public abstract class BatteryStats implements Parcelable {


    public abstract boolean getNextHistoryLocked(HistoryItem out);
    public abstract boolean getNextHistoryLocked(HistoryItem out);


    /**
    public abstract void finishIteratingHistoryLocked();
     * Return the current history of battery state changes.

     */
    public abstract boolean startIteratingOldHistoryLocked();
    public abstract HistoryItem getHistory();

    public abstract boolean getNextOldHistoryLocked(HistoryItem out);

    public abstract void finishIteratingOldHistoryLocked();


    /**
    /**
     * Return the base time offset for the battery history.
     * Return the base time offset for the battery history.
@@ -1729,7 +1746,7 @@ public abstract class BatteryStats implements Parcelable {
        }
        }
    }
    }


    void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) {
    static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) {
        int diff = oldval ^ newval;
        int diff = oldval ^ newval;
        if (diff == 0) return;
        if (diff == 0) return;
        for (int i=0; i<descriptions.length; i++) {
        for (int i=0; i<descriptions.length; i++) {
@@ -1753,24 +1770,18 @@ public abstract class BatteryStats implements Parcelable {
        }
        }
    }
    }
    
    
    /**
    public void prepareForDumpLocked() {
     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
    }
     *

     * @param pw a Printer to receive the dump output.
    public static class HistoryPrinter {
     */
    @SuppressWarnings("unused")
    public void dumpLocked(PrintWriter pw) {
        final HistoryItem rec = new HistoryItem();
        if (startIteratingHistoryLocked()) {
            pw.println("Battery History:");
            long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
        int oldState = 0;
        int oldState = 0;
        int oldStatus = -1;
        int oldStatus = -1;
        int oldHealth = -1;
        int oldHealth = -1;
        int oldPlug = -1;
        int oldPlug = -1;
        int oldTemp = -1;
        int oldTemp = -1;
        int oldVolt = -1;
        int oldVolt = -1;
            while (getNextHistoryLocked(rec)) {

        public void printNextItem(PrintWriter pw, HistoryItem rec, long now) {
            pw.print("  ");
            pw.print("  ");
            TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
            TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
            pw.print(" ");
            pw.print(" ");
@@ -1876,6 +1887,37 @@ public abstract class BatteryStats implements Parcelable {
            }
            }
            oldState = rec.states;
            oldState = rec.states;
        }
        }
    }

    /**
     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
     *
     * @param pw a Printer to receive the dump output.
     */
    @SuppressWarnings("unused")
    public void dumpLocked(PrintWriter pw) {
        prepareForDumpLocked();

        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();

        final HistoryItem rec = new HistoryItem();
        if (startIteratingHistoryLocked()) {
            pw.println("Battery History:");
            HistoryPrinter hprinter = new HistoryPrinter();
            while (getNextHistoryLocked(rec)) {
                hprinter.printNextItem(pw, rec, now);
            }
            finishIteratingHistoryLocked();
            pw.println("");
        }

        if (startIteratingOldHistoryLocked()) {
            pw.println("Old battery History:");
            HistoryPrinter hprinter = new HistoryPrinter();
            while (getNextOldHistoryLocked(rec)) {
                hprinter.printNextItem(pw, rec, now);
            }
            finishIteratingOldHistoryLocked();
            pw.println("");
            pw.println("");
        }
        }
        
        
@@ -1918,6 +1960,8 @@ public abstract class BatteryStats implements Parcelable {
    
    
    @SuppressWarnings("unused")
    @SuppressWarnings("unused")
    public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
    public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
        prepareForDumpLocked();

        boolean isUnpluggedOnly = false;
        boolean isUnpluggedOnly = false;
        
        
        for (String arg : args) {
        for (String arg : args) {
+214 −20
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Log;
import android.util.LogWriter;
import android.util.PrintWriterPrinter;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Printer;
import android.util.Slog;
import android.util.Slog;
@@ -70,7 +71,7 @@ public final class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'


    // Current on-disk Parcel version
    // Current on-disk Parcel version
    private static final int VERSION = 54;
    private static final int VERSION = 57;


    // Maximum number of items we will record in the history.
    // Maximum number of items we will record in the history.
    private static final int MAX_HISTORY_ITEMS = 2000;
    private static final int MAX_HISTORY_ITEMS = 2000;
@@ -154,11 +155,26 @@ public final class BatteryStatsImpl extends BatteryStats {
    boolean mHaveBatteryLevel = false;
    boolean mHaveBatteryLevel = false;
    boolean mRecordingHistory = true;
    boolean mRecordingHistory = true;
    int mNumHistoryItems;
    int mNumHistoryItems;

    static final int MAX_HISTORY_BUFFER = 64*1024; // 64KB
    static final int MAX_MAX_HISTORY_BUFFER = 92*1024; // 92KB
    final Parcel mHistoryBuffer = Parcel.obtain();
    final HistoryItem mHistoryLastWritten = new HistoryItem();
    final HistoryItem mHistoryLastLastWritten = new HistoryItem();
    int mHistoryBufferLastPos = -1;
    boolean mHistoryOverflow = false;
    long mLastHistoryTime = 0;

    final HistoryItem mHistoryCur = new HistoryItem();

    HistoryItem mHistory;
    HistoryItem mHistory;
    HistoryItem mHistoryEnd;
    HistoryItem mHistoryEnd;
    HistoryItem mHistoryLastEnd;
    HistoryItem mHistoryLastEnd;
    HistoryItem mHistoryCache;
    HistoryItem mHistoryCache;
    final HistoryItem mHistoryCur = new HistoryItem();

    private HistoryItem mHistoryIterator;
    private boolean mReadOverflow;
    private boolean mIteratingHistory;


    int mStartCount;
    int mStartCount;


@@ -1189,9 +1205,82 @@ public final class BatteryStatsImpl extends BatteryStats {
        mBtHeadset = headset;
        mBtHeadset = headset;
    }
    }


    int mChangedBufferStates = 0;

    void addHistoryBufferLocked(long curTime) {
        if (!mHaveBatteryLevel || !mRecordingHistory) {
            return;
        }

        if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
                && (mHistoryBaseTime+curTime) < (mHistoryLastWritten.time+2000)
                && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
            // If the current is the same as the one before, then we no
            // longer need the entry.
            mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
            mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
            mHistoryBufferLastPos = -1;
            if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
                    && mHistoryLastLastWritten.same(mHistoryCur)) {
                // If this results in us returning to the state written
                // prior to the last one, then we can just delete the last
                // written one and drop the new one.  Nothing more to do.
                mHistoryLastWritten.setTo(mHistoryLastLastWritten);
                mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
                return;
            }
            mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
            curTime = mHistoryLastWritten.time - mHistoryBaseTime;
        } else {
            mChangedBufferStates = 0;
        }

        final int dataSize = mHistoryBuffer.dataSize();
        if (dataSize >= MAX_HISTORY_BUFFER) {
            if (!mHistoryOverflow) {
                mHistoryOverflow = true;
                addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
            }

            // Once we've reached the maximum number of items, we only
            // record changes to the battery level and the most interesting states.
            // Once we've reached the maximum maximum number of items, we only
            // record changes to the battery level.
            if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
                    (dataSize >= MAX_MAX_HISTORY_BUFFER
                            || ((mHistoryEnd.states^mHistoryCur.states)
                                    & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
                return;
            }
        }

        addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
    }

    void addHistoryBufferLocked(long curTime, byte cmd) {
        int origPos = 0;
        if (mIteratingHistory) {
            origPos = mHistoryBuffer.dataPosition();
            mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
        }
        mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
        mHistoryLastLastWritten.setTo(mHistoryLastWritten);
        mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
        mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
        mLastHistoryTime = curTime;
        if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
                + " now " + mHistoryBuffer.dataPosition()
                + " size is now " + mHistoryBuffer.dataSize());
        if (mIteratingHistory) {
            mHistoryBuffer.setDataPosition(origPos);
        }
    }

    int mChangedStates = 0;
    int mChangedStates = 0;


    void addHistoryRecordLocked(long curTime) {
    void addHistoryRecordLocked(long curTime) {
        addHistoryBufferLocked(curTime);

        if (!mHaveBatteryLevel || !mRecordingHistory) {
        if (!mHaveBatteryLevel || !mRecordingHistory) {
            return;
            return;
        }
        }
@@ -1268,6 +1357,7 @@ public final class BatteryStatsImpl extends BatteryStats {
    }
    }


    void clearHistoryLocked() {
    void clearHistoryLocked() {
        if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
        if (mHistory != null) {
        if (mHistory != null) {
            mHistoryEnd.next = mHistoryCache;
            mHistoryEnd.next = mHistoryCache;
            mHistoryCache = mHistory;
            mHistoryCache = mHistory;
@@ -1275,6 +1365,15 @@ public final class BatteryStatsImpl extends BatteryStats {
        }
        }
        mNumHistoryItems = 0;
        mNumHistoryItems = 0;
        mHistoryBaseTime = 0;
        mHistoryBaseTime = 0;
        mLastHistoryTime = 0;

        mHistoryBuffer.setDataSize(0);
        mHistoryBuffer.setDataPosition(0);
        mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
        mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
        mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
        mHistoryBufferLastPos = -1;
        mHistoryOverflow = false;
    }
    }


    public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
    public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
@@ -3910,11 +4009,13 @@ public final class BatteryStatsImpl extends BatteryStats {
        mDischargeUnplugLevel = 0;
        mDischargeUnplugLevel = 0;
        mDischargeCurrentLevel = 0;
        mDischargeCurrentLevel = 0;
        initDischarge();
        initDischarge();
        clearHistoryLocked();
    }
    }


    public BatteryStatsImpl(Parcel p) {
    public BatteryStatsImpl(Parcel p) {
        mFile = null;
        mFile = null;
        mHandler = null;
        mHandler = null;
        clearHistoryLocked();
        readFromParcel(p);
        readFromParcel(p);
    }
    }


@@ -3932,25 +4033,79 @@ public final class BatteryStatsImpl extends BatteryStats {
        }
        }
    }
    }


    private HistoryItem mHistoryIterator;
    @Override

    public boolean startIteratingOldHistoryLocked() {
    public boolean startIteratingHistoryLocked() {
        if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
                + " pos=" + mHistoryBuffer.dataPosition());
        mHistoryBuffer.setDataPosition(0);
        mReadOverflow = false;
        mIteratingHistory = true;
        return (mHistoryIterator = mHistory) != null;
        return (mHistoryIterator = mHistory) != null;
    }
    }


    public boolean getNextHistoryLocked(HistoryItem out) {
    @Override
    public boolean getNextOldHistoryLocked(HistoryItem out) {
        boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
        if (!end) {
            mHistoryLastWritten.readDelta(mHistoryBuffer, null);
            mReadOverflow |= mHistoryLastWritten.cmd == HistoryItem.CMD_OVERFLOW;
        }
        HistoryItem cur = mHistoryIterator;
        HistoryItem cur = mHistoryIterator;
        if (cur == null) {
        if (cur == null) {
            if (!mReadOverflow && !end) {
                Slog.w(TAG, "Old history ends before new history!");
            }
            return false;
            return false;
        }
        }
        out.setTo(cur);
        out.setTo(cur);
        mHistoryIterator = cur.next;
        mHistoryIterator = cur.next;
        if (!mReadOverflow) {
            if (end) {
                Slog.w(TAG, "New history ends before old history!");
            } else if (!out.same(mHistoryLastWritten)) {
                long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
                PrintWriter pw = new PrintWriter(new LogWriter(android.util.Log.WARN, TAG));
                pw.println("Histories differ!");
                pw.println("Old history:");
                (new HistoryPrinter()).printNextItem(pw, out, now);
                pw.println("New history:");
                (new HistoryPrinter()).printNextItem(pw, mHistoryLastWritten, now);
            }
        }
        return true;
        return true;
    }
    }


    @Override
    @Override
    public HistoryItem getHistory() {
    public void finishIteratingOldHistoryLocked() {
        return mHistory;
        mIteratingHistory = false;
        mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
    }

    @Override
    public boolean startIteratingHistoryLocked() {
        if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
                + " pos=" + mHistoryBuffer.dataPosition());
        mHistoryBuffer.setDataPosition(0);
        mReadOverflow = false;
        mIteratingHistory = true;
        return mHistoryBuffer.dataSize() > 0;
    }

    @Override
    public boolean getNextHistoryLocked(HistoryItem out) {
        boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
        if (end) {
            return false;
        }

        out.readDelta(mHistoryBuffer, null);
        return true;
    }

    @Override
    public void finishIteratingHistoryLocked() {
        mIteratingHistory = false;
        mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
    }
    }


    @Override
    @Override
@@ -4697,7 +4852,9 @@ public final class BatteryStatsImpl extends BatteryStats {
            Slog.e("BatteryStats", "Error reading battery statistics", e);
            Slog.e("BatteryStats", "Error reading battery statistics", e);
        }
        }


        addHistoryRecordLocked(SystemClock.elapsedRealtime(), HistoryItem.CMD_START);
        long now = SystemClock.elapsedRealtime();
        addHistoryRecordLocked(now, HistoryItem.CMD_START);
        addHistoryBufferLocked(now, HistoryItem.CMD_START);
    }
    }


    public int describeContents() {
    public int describeContents() {
@@ -4705,30 +4862,54 @@ public final class BatteryStatsImpl extends BatteryStats {
    }
    }


    void readHistory(Parcel in) {
    void readHistory(Parcel in) {
        mHistory = mHistoryEnd = mHistoryCache = null;
        mHistoryBaseTime = in.readLong();
        mHistoryBaseTime = 0;

        long time;
        mHistoryBuffer.setDataSize(0);
        while ((time=in.readLong()) >= 0) {
        mHistoryBuffer.setDataPosition(0);
            HistoryItem rec = new HistoryItem(time, in);

            addHistoryRecordLocked(rec);
        int bufSize = in.readInt();
            if (rec.time > mHistoryBaseTime) {
        int curPos = in.dataPosition();
                mHistoryBaseTime = rec.time;
        if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
            }
            Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
        } else if ((bufSize&~3) != bufSize) {
            Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
        } else {
            if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
                    + " bytes at " + curPos);
            mHistoryBuffer.appendFrom(in, curPos, bufSize);
            in.setDataPosition(curPos + bufSize);
        }
        }


        long oldnow = SystemClock.elapsedRealtime() - (5*60*100);
        long oldnow = SystemClock.elapsedRealtime() - (5*60*1000);
        if (oldnow > 0) {
        if (oldnow > 0) {
            // If the system process has restarted, but not the entire
            // If the system process has restarted, but not the entire
            // system, then the mHistoryBaseTime already accounts for
            // system, then the mHistoryBaseTime already accounts for
            // much of the elapsed time.  We thus want to adjust it back,
            // much of the elapsed time.  We thus want to adjust it back,
            // to avoid large gaps in the data.  We determine we are
            // to avoid large gaps in the data.  We determine we are
            // in this case by arbitrarily saying it is so if at this
            // in this case by arbitrarily saying it is so if at this
            // point in boot the elapsed time is already more than 5 seconds.
            // point in boot the elapsed time is already more than 5 minutes.
            mHistoryBaseTime -= oldnow;
            mHistoryBaseTime -= oldnow;
        }
        }
    }
    }


    void readOldHistory(Parcel in) {
        mHistory = mHistoryEnd = mHistoryCache = null;
        long time;
        while ((time=in.readLong()) >= 0) {
            HistoryItem rec = new HistoryItem(time, in);
            addHistoryRecordLocked(rec);
        }
    }

    void writeHistory(Parcel out) {
    void writeHistory(Parcel out) {
        out.writeLong(mLastHistoryTime);
        out.writeInt(mHistoryBuffer.dataSize());
        if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
                + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
        out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
    }

    void writeOldHistory(Parcel out) {
        HistoryItem rec = mHistory;
        HistoryItem rec = mHistory;
        while (rec != null) {
        while (rec != null) {
            if (rec.time >= 0) rec.writeToParcel(out, 0);
            if (rec.time >= 0) rec.writeToParcel(out, 0);
@@ -4746,6 +4927,7 @@ public final class BatteryStatsImpl extends BatteryStats {
        }
        }


        readHistory(in);
        readHistory(in);
        readOldHistory(in);


        mStartCount = in.readInt();
        mStartCount = in.readInt();
        mBatteryUptime = in.readLong();
        mBatteryUptime = in.readLong();
@@ -4935,6 +5117,9 @@ public final class BatteryStatsImpl extends BatteryStats {
     * @param out the Parcel to be written to.
     * @param out the Parcel to be written to.
     */
     */
    public void writeSummaryToParcel(Parcel out) {
    public void writeSummaryToParcel(Parcel out) {
        // Need to update with current kernel wake lock counts.
        updateKernelWakelocksLocked();

        final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
        final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
        final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
        final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
        final long NOW = getBatteryUptimeLocked(NOW_SYS);
        final long NOW = getBatteryUptimeLocked(NOW_SYS);
@@ -4943,6 +5128,7 @@ public final class BatteryStatsImpl extends BatteryStats {
        out.writeInt(VERSION);
        out.writeInt(VERSION);


        writeHistory(out);
        writeHistory(out);
        writeOldHistory(out);


        out.writeInt(mStartCount);
        out.writeInt(mStartCount);
        out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
        out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
@@ -5256,6 +5442,9 @@ public final class BatteryStatsImpl extends BatteryStats {


    @SuppressWarnings("unused")
    @SuppressWarnings("unused")
    void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
    void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
        // Need to update with current kernel wake lock counts.
        updateKernelWakelocksLocked();

        final long uSecUptime = SystemClock.uptimeMillis() * 1000;
        final long uSecUptime = SystemClock.uptimeMillis() * 1000;
        final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
        final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
        final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
        final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
@@ -5358,6 +5547,11 @@ public final class BatteryStatsImpl extends BatteryStats {
        }
        }
    };
    };


    public void prepareForDumpLocked() {
        // Need to retrieve current kernel wake lock stats before printing.
        updateKernelWakelocksLocked();
    }

    public void dumpLocked(PrintWriter pw) {
    public void dumpLocked(PrintWriter pw) {
        if (DEBUG) {
        if (DEBUG) {
            Printer pr = new PrintWriterPrinter(pw);
            Printer pr = new PrintWriterPrinter(pw);
+11 −7
Original line number Original line Diff line number Diff line
@@ -338,7 +338,7 @@ void Parcel::setDataPosition(size_t pos) const


status_t Parcel::setDataCapacity(size_t size)
status_t Parcel::setDataCapacity(size_t size)
{
{
    if (size > mDataSize) return continueWrite(size);
    if (size > mDataCapacity) return continueWrite(size);
    return NO_ERROR;
    return NO_ERROR;
}
}


@@ -386,11 +386,13 @@ status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
    }
    }
    int numObjects = lastIndex - firstIndex + 1;
    int numObjects = lastIndex - firstIndex + 1;


    if ((mDataSize+len) > mDataCapacity) {
        // grow data
        // grow data
        err = growData(len);
        err = growData(len);
        if (err != NO_ERROR) {
        if (err != NO_ERROR) {
            return err;
            return err;
        }
        }
    }


    // append data
    // append data
    memcpy(mData + mDataPos, data + offset, len);
    memcpy(mData + mDataPos, data + offset, len);
@@ -1384,8 +1386,10 @@ status_t Parcel::continueWrite(size_t desired)
                return NO_MEMORY;
                return NO_MEMORY;
            }
            }
        } else {
        } else {
            if (mDataSize > desired) {
                mDataSize = desired;
                mDataSize = desired;
                LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
                LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
            }
            if (mDataPos > desired) {
            if (mDataPos > desired) {
                mDataPos = desired;
                mDataPos = desired;
                LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
                LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+13 −0
Original line number Original line Diff line number Diff line
@@ -449,6 +449,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
    @Override
    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        boolean isCheckin = false;
        boolean isCheckin = false;
        boolean noOutput = false;
        if (args != null) {
        if (args != null) {
            for (String arg : args) {
            for (String arg : args) {
                if ("--checkin".equals(arg)) {
                if ("--checkin".equals(arg)) {
@@ -457,10 +458,22 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
                    synchronized (mStats) {
                    synchronized (mStats) {
                        mStats.resetAllStatsLocked();
                        mStats.resetAllStatsLocked();
                        pw.println("Battery stats reset.");
                        pw.println("Battery stats reset.");
                        noOutput = true;
                    }
                    }
                } else if ("--write".equals(arg)) {
                    synchronized (mStats) {
                        mStats.writeSyncLocked();
                        pw.println("Battery stats written.");
                        noOutput = true;
                    }
                } else {
                    pw.println("Unknown option: " + arg);
                }
                }
            }
            }
        }
        }
        if (noOutput) {
            return;
        }
        if (isCheckin) {
        if (isCheckin) {
            List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
            List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
            synchronized (mStats) {
            synchronized (mStats) {