FileDocCategorySizeDatePackage
BatteryStatsImpl.javaAPI DocAndroid 1.5 API96893Wed May 06 22:41:56 BST 2009com.android.internal.os

BatteryStatsImpl

public final class BatteryStatsImpl extends android.os.BatteryStats
All information we are collecting about things that can happen that impact battery life. All times are represented in microseconds except where indicated otherwise.

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final int
MAGIC
private static final int
VERSION
private final File
mFile
private final File
mBackupFile
final android.util.SparseArray
mUidStats
The statistics we have collected organized by uids.
final ArrayList
mPartialTimers
final ArrayList
mFullTimers
final ArrayList
mWindowTimers
final android.util.SparseArray
mSensorTimers
final ArrayList
mUnpluggables
int
mStartCount
long
mBatteryUptime
long
mBatteryLastUptime
long
mBatteryRealtime
long
mBatteryLastRealtime
long
mUptime
long
mUptimeStart
long
mLastUptime
long
mRealtime
long
mRealtimeStart
long
mLastRealtime
boolean
mScreenOn
Timer
mScreenOnTimer
int
mScreenBrightnessBin
final Timer[]
mScreenBrightnessTimer
Counter
mInputEventCounter
boolean
mPhoneOn
Timer
mPhoneOnTimer
int
mPhoneSignalStrengthBin
final Timer[]
mPhoneSignalStrengthsTimer
int
mPhoneDataConnectionType
final Timer[]
mPhoneDataConnectionsTimer
boolean
mWifiOn
Timer
mWifiOnTimer
int
mWifiOnUid
boolean
mWifiRunning
Timer
mWifiRunningTimer
boolean
mBluetoothOn
Timer
mBluetoothOnTimer
boolean
mOnBattery
These provide time bases that discount the time the device is plugged in to power.
boolean
mOnBatteryInternal
long
mTrackBatteryPastUptime
long
mTrackBatteryUptimeStart
long
mTrackBatteryPastRealtime
long
mTrackBatteryRealtimeStart
long
mUnpluggedBatteryUptime
long
mUnpluggedBatteryRealtime
int
mUnpluggedStartLevel
int
mPluggedStartLevel
long
mLastWriteTime
public static final Parcelable.Creator
CREATOR
Constructors Summary
public BatteryStatsImpl()

 // Milliseconds

    // For debugging
      
        mFile = mBackupFile = null;
    
public BatteryStatsImpl(String filename)

        mFile = new File(filename);
        mBackupFile = new File(filename + ".bak");
        mStartCount++;
        mScreenOnTimer = new Timer(-1, null, mUnpluggables);
        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
            mScreenBrightnessTimer[i] = new Timer(-100-i, null, mUnpluggables);
        }
        mInputEventCounter = new Counter(mUnpluggables);
        mPhoneOnTimer = new Timer(-2, null, mUnpluggables);
        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
            mPhoneSignalStrengthsTimer[i] = new Timer(-200-i, null, mUnpluggables);
        }
        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
            mPhoneDataConnectionsTimer[i] = new Timer(-300-i, null, mUnpluggables);
        }
        mWifiOnTimer = new Timer(-3, null, mUnpluggables);
        mWifiRunningTimer = new Timer(-4, null, mUnpluggables);
        mBluetoothOnTimer = new Timer(-5, null, mUnpluggables);
        mOnBattery = mOnBatteryInternal = false;
        mTrackBatteryPastUptime = 0;
        mTrackBatteryPastRealtime = 0;
        mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
        mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
        mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
        mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
        mUnpluggedStartLevel = 0;
        mPluggedStartLevel = 0;
    
public BatteryStatsImpl(android.os.Parcel p)

        mFile = mBackupFile = null;
        readFromParcel(p);
    
Methods Summary
public longcomputeBatteryRealtime(long curTime, int which)

        switch (which) {
            case STATS_TOTAL:
                return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
            case STATS_LAST:
                return mBatteryLastRealtime;
            case STATS_CURRENT:
                return getBatteryRealtimeLocked(curTime);
            case STATS_UNPLUGGED:
                return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
        }
        return 0;
    
public longcomputeBatteryUptime(long curTime, int which)

        switch (which) {
            case STATS_TOTAL:
                return mBatteryUptime + getBatteryUptime(curTime);
            case STATS_LAST:
                return mBatteryLastUptime;
            case STATS_CURRENT:
                return getBatteryUptime(curTime);
            case STATS_UNPLUGGED:
                return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
        }
        return 0;
    
public longcomputeRealtime(long curTime, int which)

        switch (which) {
            case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
            case STATS_LAST: return mLastRealtime;
            case STATS_CURRENT: return (curTime-mRealtimeStart);
            case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
        }
        return 0;
    
public longcomputeUptime(long curTime, int which)

        switch (which) {
            case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
            case STATS_LAST: return mLastUptime;
            case STATS_CURRENT: return (curTime-mUptimeStart);
            case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
        }
        return 0;
    
public intdescribeContents()

        return 0;
    
public voiddoPlug(long batteryUptime, long batteryRealtime)

        for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
            Uid u = mUidStats.valueAt(iu);
            if (u.mStartedTcpBytesReceived >= 0) {
                u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
                u.mStartedTcpBytesReceived = -1;
            }
            if (u.mStartedTcpBytesSent >= 0) {
                u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
                u.mStartedTcpBytesSent = -1;
            }
        }
        for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
            mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
        }
    
public voiddoUnplug(long batteryUptime, long batteryRealtime)

        for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
            Uid u = mUidStats.valueAt(iu);
            u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
            u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
            u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
            u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
        }
        for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
            mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
        }
    
public voiddumpLocked(android.util.Printer pw)

    
        
        if (DEBUG) {
            pw.println("*** Screen timer:");
            mScreenOnTimer.logState(pw, "  ");
            for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
                pw.println("*** Screen brightness #" + i + ":");
                mScreenBrightnessTimer[i].logState(pw, "  ");
            }
            pw.println("*** Input event counter:");
            mInputEventCounter.logState(pw, "  ");
            pw.println("*** Phone timer:");
            mPhoneOnTimer.logState(pw, "  ");
            for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
                pw.println("*** Signal strength #" + i + ":");
                mPhoneSignalStrengthsTimer[i].logState(pw, "  ");
            }
            for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
                pw.println("*** Data connection type #" + i + ":");
                mPhoneDataConnectionsTimer[i].logState(pw, "  ");
            }
            pw.println("*** Wifi timer:");
            mWifiOnTimer.logState(pw, "  ");
            pw.println("*** WifiRunning timer:");
            mWifiRunningTimer.logState(pw, "  ");
            pw.println("*** Bluetooth timer:");
            mBluetoothOnTimer.logState(pw, "  ");
        }
        super.dumpLocked(pw);
    
public longgetAwakeTimeBattery()

        return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
    
public longgetAwakeTimePlugged()

        return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
    
public longgetBatteryRealtime(long curTime)

        return getBatteryRealtimeLocked(curTime);
    
longgetBatteryRealtimeLocked(long curTime)

        long time = mTrackBatteryPastRealtime;
        if (mOnBatteryInternal) {
            time += curTime - mTrackBatteryRealtimeStart;
        }
        return time;
    
public longgetBatteryUptime(long curTime)

        return getBatteryUptimeLocked(curTime);
    
longgetBatteryUptimeLocked(long curTime)

        long time = mTrackBatteryPastUptime;
        if (mOnBatteryInternal) {
            time += curTime - mTrackBatteryUptimeStart;
        }
        return time;
    
longgetBatteryUptimeLocked()

        return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
    
public longgetBluetoothOnTime(long batteryRealtime, int which)

        return mBluetoothOnTimer.getTotalTime(batteryRealtime, which);
    
public intgetInputEventCount(int which)

        return mInputEventCounter.getCount(which);
    
public booleangetIsOnBattery()

        return mOnBattery;
    
public Uid.PkggetPackageStatsLocked(int uid, java.lang.String pkg)
Retrieve the statistics object for a particular process, creating if needed.

        Uid u = getUidStatsLocked(uid);
        return u.getPackageStatsLocked(pkg);
    
public intgetPhoneDataConnectionCount(int dataType, int which)

        return mPhoneDataConnectionsTimer[dataType].getCount(which);
    
public longgetPhoneDataConnectionTime(int dataType, long batteryRealtime, int which)

        return mPhoneDataConnectionsTimer[dataType].getTotalTime(
                batteryRealtime, which);
    
public longgetPhoneOnTime(long batteryRealtime, int which)

        return mPhoneOnTimer.getTotalTime(batteryRealtime, which);
    
public intgetPhoneSignalStrengthCount(int dataType, int which)

        return mPhoneDataConnectionsTimer[dataType].getCount(which);
    
public longgetPhoneSignalStrengthTime(int strengthBin, long batteryRealtime, int which)

        return mPhoneSignalStrengthsTimer[strengthBin].getTotalTime(
                batteryRealtime, which);
    
public intgetPluggedStartLevel()

        synchronized(this) {
            return getPluggedStartLevelLocked();
        }
    
public intgetPluggedStartLevelLocked()

            return mPluggedStartLevel;
    
public Uid.ProcgetProcessStatsLocked(int uid, java.lang.String name)
Retrieve the statistics object for a particular process, creating if needed.

        Uid u = getUidStatsLocked(uid);
        return u.getProcessStatsLocked(name);
    
public longgetScreenBrightnessTime(int brightnessBin, long batteryRealtime, int which)

        return mScreenBrightnessTimer[brightnessBin].getTotalTime(
                batteryRealtime, which);
    
public longgetScreenOnTime(long batteryRealtime, int which)

        return mScreenOnTimer.getTotalTime(batteryRealtime, which);
    
public Uid.Pkg.ServgetServiceStatsLocked(int uid, java.lang.String pkg, java.lang.String name)
Retrieve the statistics object for a particular service, creating if needed.

        Uid u = getUidStatsLocked(uid);
        return u.getServiceStatsLocked(pkg, name);
    
public intgetStartCount()

        return mStartCount;
    
public android.util.SparseArraygetUidStats()

        return mUidStats;
    
public com.android.internal.os.BatteryStatsImpl$UidgetUidStatsLocked(int uid)
Retrieve the statistics object for a particular uid, creating if needed.

        Uid u = mUidStats.get(uid);
        if (u == null) {
            u = new Uid(uid);
            mUidStats.put(uid, u);
        }
        return u;
    
public intgetUnluggedStartLevelLocked()

            return mUnpluggedStartLevel;
    
public intgetUnpluggedStartLevel()

        synchronized(this) {
            return getUnluggedStartLevelLocked();
        }
    
public longgetWifiOnTime(long batteryRealtime, int which)

        return mWifiOnTimer.getTotalTime(batteryRealtime, which);
    
public longgetWifiRunningTime(long batteryRealtime, int which)

        return mWifiRunningTimer.getTotalTime(batteryRealtime, which);
    
public booleanisOnBattery()

        return mOnBattery;
    
public voidnoteBluetoothOffLocked()

        if (mBluetoothOn) {
            mBluetoothOn = false;
            mBluetoothOnTimer.stopRunningLocked(this);
        }
    
public voidnoteBluetoothOnLocked()

        if (!mBluetoothOn) {
            mBluetoothOn = true;
            mBluetoothOnTimer.startRunningLocked(this);
        }
    
public voidnoteFullWifiLockAcquiredLocked(int uid)

        Uid u = mUidStats.get(uid);
        if (u != null) {
            u.noteFullWifiLockAcquiredLocked();
        }
    
public voidnoteFullWifiLockReleasedLocked(int uid)

        Uid u = mUidStats.get(uid);
        if (u != null) {
            u.noteFullWifiLockReleasedLocked();
        }
    
public voidnoteInputEventLocked()

        mInputEventCounter.stepLocked();
    
public voidnotePhoneDataConnectionStateLocked(int dataType, boolean hasData)

        int bin = DATA_CONNECTION_NONE;
        if (hasData) {
            switch (dataType) {
                case TelephonyManager.NETWORK_TYPE_EDGE:
                    bin = DATA_CONNECTION_EDGE;
                    break;
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    bin = DATA_CONNECTION_GPRS;
                    break;
                case TelephonyManager.NETWORK_TYPE_UMTS:
                    bin = DATA_CONNECTION_UMTS;
                    break;
                default:
                    bin = DATA_CONNECTION_OTHER;
                    break;
            }
        }
        if (mPhoneDataConnectionType != bin) {
            if (mPhoneDataConnectionType >= 0) {
                mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
            }
            mPhoneDataConnectionType = bin;
            mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
        }
    
public voidnotePhoneOffLocked()

        if (mPhoneOn) {
            mPhoneOn = false;
            mPhoneOnTimer.stopRunningLocked(this);
        }
    
public voidnotePhoneOnLocked()

        if (!mPhoneOn) {
            mPhoneOn = true;
            mPhoneOnTimer.startRunningLocked(this);
        }
    
public voidnotePhoneSignalStrengthLocked(int asu)

        // Bin the strength.
        int bin;
        if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
        else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
        else if (asu >= 8)  bin = SIGNAL_STRENGTH_GOOD;
        else if (asu >= 4)  bin = SIGNAL_STRENGTH_MODERATE;
        else bin = SIGNAL_STRENGTH_POOR;
        if (mPhoneSignalStrengthBin != bin) {
            if (mPhoneSignalStrengthBin >= 0) {
                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
            }
            mPhoneSignalStrengthBin = bin;
            mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
        }
    
public voidnoteScanWifiLockAcquiredLocked(int uid)

        Uid u = mUidStats.get(uid);
        if (u != null) {
            u.noteScanWifiLockAcquiredLocked();
        }
    
public voidnoteScanWifiLockReleasedLocked(int uid)

        Uid u = mUidStats.get(uid);
        if (u != null) {
            u.noteScanWifiLockReleasedLocked();
        }
    
public voidnoteScreenBrightnessLocked(int brightness)

        // Bin the brightness.
        int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
        if (bin < 0) bin = 0;
        else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
        if (mScreenBrightnessBin != bin) {
            if (mScreenOn) {
                if (mScreenBrightnessBin >= 0) {
                    mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
                }
                mScreenBrightnessTimer[bin].startRunningLocked(this);
            }
            mScreenBrightnessBin = bin;
        }
    
public voidnoteScreenOffLocked()

        if (mScreenOn) {
            mScreenOn = false;
            mScreenOnTimer.stopRunningLocked(this);
            if (mScreenBrightnessBin >= 0) {
                mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
            }
        }
    
public voidnoteScreenOnLocked()

        if (!mScreenOn) {
            mScreenOn = true;
            mScreenOnTimer.startRunningLocked(this);
            if (mScreenBrightnessBin >= 0) {
                mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
            }
        }
    
public voidnoteStartGps(int uid)

        mUidStats.get(uid).noteStartGps();
    
public voidnoteStopGps(int uid)

        mUidStats.get(uid).noteStopGps();
    
public voidnoteUserActivityLocked(int uid, int event)

        Uid u = mUidStats.get(uid);
        if (u != null) {
            u.noteUserActivityLocked(event);
        }
    
public voidnoteWifiOffLocked(int uid)

        if (mWifiOn) {
            mWifiOn = false;
            mWifiOnTimer.stopRunningLocked(this);
        }
        if (mWifiOnUid >= 0) {
            Uid u = mUidStats.get(mWifiOnUid);
            if (u != null) {
                u.noteWifiTurnedOffLocked();
            }
            mWifiOnUid = -1;
        }
    
public voidnoteWifiOnLocked(int uid)

        if (!mWifiOn) {
            mWifiOn = true;
            mWifiOnTimer.startRunningLocked(this);
        }
        if (mWifiOnUid != uid) {
            if (mWifiOnUid >= 0) {
                Uid u = mUidStats.get(mWifiOnUid);
                if (u != null) {
                    u.noteWifiTurnedOffLocked();
                }
            }
            mWifiOnUid = uid;
            Uid u = mUidStats.get(uid);
            if (u != null) {
                u.noteWifiTurnedOnLocked();
            }
        }
    
public voidnoteWifiRunningLocked()

        if (!mWifiRunning) {
            mWifiRunning = true;
            mWifiRunningTimer.startRunningLocked(this);
        }
    
public voidnoteWifiStoppedLocked()

        if (mWifiRunning) {
            mWifiRunning = false;
            mWifiRunningTimer.stopRunningLocked(this);
        }
    
public voidreadFromParcel(android.os.Parcel in)

        readFromParcelLocked(in);
    
voidreadFromParcelLocked(android.os.Parcel in)

        int magic = in.readInt();
        if (magic != MAGIC) {
            throw new ParcelFormatException("Bad magic number");
        }

        mStartCount = in.readInt();
        mBatteryUptime = in.readLong();
        mBatteryLastUptime = in.readLong();
        mBatteryRealtime = in.readLong();
        mBatteryLastRealtime = in.readLong();
        mScreenOn = false;
        mScreenOnTimer = new Timer(-1, null, mUnpluggables, in);
        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
            mScreenBrightnessTimer[i] = new Timer(-100-i, null, mUnpluggables, in);
        }
        mInputEventCounter = new Counter(mUnpluggables, in);
        mPhoneOn = false;
        mPhoneOnTimer = new Timer(-2, null, mUnpluggables, in);
        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
            mPhoneSignalStrengthsTimer[i] = new Timer(-200-i, null, mUnpluggables, in);
        }
        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
            mPhoneDataConnectionsTimer[i] = new Timer(-300-i, null, mUnpluggables, in);
        }
        mWifiOn = false;
        mWifiOnTimer = new Timer(-2, null, mUnpluggables, in);
        mWifiRunning = false;
        mWifiRunningTimer = new Timer(-2, null, mUnpluggables, in);
        mBluetoothOn = false;
        mBluetoothOnTimer = new Timer(-2, null, mUnpluggables, in);
        mUptime = in.readLong();
        mUptimeStart = in.readLong();
        mLastUptime = in.readLong();
        mRealtime = in.readLong();
        mRealtimeStart = in.readLong();
        mLastRealtime = in.readLong();
        mOnBattery = in.readInt() != 0;
        mOnBatteryInternal = false; // we are no longer really running.
        mTrackBatteryPastUptime = in.readLong();
        mTrackBatteryUptimeStart = in.readLong();
        mTrackBatteryPastRealtime = in.readLong();
        mTrackBatteryRealtimeStart = in.readLong();
        mUnpluggedBatteryUptime = in.readLong();
        mUnpluggedBatteryRealtime = in.readLong();
        mUnpluggedStartLevel = in.readInt();
        mPluggedStartLevel = in.readInt();
        mLastWriteTime = in.readLong();

        mPartialTimers.clear();
        mFullTimers.clear();
        mWindowTimers.clear();

        int numUids = in.readInt();
        mUidStats.clear();
        for (int i = 0; i < numUids; i++) {
            int uid = in.readInt();
            Uid u = new Uid(uid);
            u.readFromParcelLocked(mUnpluggables, in);
            mUidStats.append(uid, u);
        }
    
static byte[]readFully(java.io.FileInputStream stream)

        int pos = 0;
        int avail = stream.available();
        byte[] data = new byte[avail];
        while (true) {
            int amt = stream.read(data, pos, data.length-pos);
            //Log.i("foo", "Read " + amt + " bytes at " + pos
            //        + " of avail " + data.length);
            if (amt <= 0) {
                //Log.i("foo", "**** FINISHED READING: pos=" + pos
                //        + " len=" + data.length);
                return data;
            }
            pos += amt;
            avail = stream.available();
            if (avail > data.length-pos) {
                byte[] newData = new byte[pos+avail];
                System.arraycopy(data, 0, newData, 0, pos);
                data = newData;
            }
        }
    
public voidreadLocked()

        if ((mFile == null) || (mBackupFile == null)) {
            Log.w("BatteryStats", "readLocked: no file associated with this instance");
            return;
        }

        mUidStats.clear();

        FileInputStream stream = null;
        if (mBackupFile.exists()) {
            try {
                stream = new FileInputStream(mBackupFile);
            } catch (java.io.IOException e) {
                // We'll try for the normal settings file.
            }
        }

        try {
            if (stream == null) {
                if (!mFile.exists()) {
                    return;
                }
                stream = new FileInputStream(mFile);
            }

            byte[] raw = readFully(stream);
            Parcel in = Parcel.obtain();
            in.unmarshall(raw, 0, raw.length);
            in.setDataPosition(0);
            stream.close();

            readSummaryFromParcel(in);
        } catch(java.io.IOException e) {
            Log.e("BatteryStats", "Error reading battery statistics", e);
        }
    
private voidreadSummaryFromParcel(android.os.Parcel in)

        final int version = in.readInt();
        if (version != VERSION) {
            Log.w("BatteryStats", "readFromParcel: version got " + version
                + ", expected " + VERSION + "; erasing old stats");
            return;
        }

        mStartCount = in.readInt();
        mBatteryUptime = in.readLong();
        mBatteryLastUptime = in.readLong();
        mBatteryRealtime = in.readLong();
        mBatteryLastRealtime = in.readLong();
        mUptime = in.readLong();
        mLastUptime = in.readLong();
        mRealtime = in.readLong();
        mLastRealtime = in.readLong();
        mUnpluggedStartLevel = in.readInt();
        mPluggedStartLevel = in.readInt();
        
        mStartCount++;
        
        mScreenOn = false;
        mScreenOnTimer.readSummaryFromParcelLocked(in);
        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
            mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
        }
        mInputEventCounter.readSummaryFromParcelLocked(in);
        mPhoneOn = false;
        mPhoneOnTimer.readSummaryFromParcelLocked(in);
        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
            mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
        }
        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
            mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
        }
        mWifiOn = false;
        mWifiOnTimer.readSummaryFromParcelLocked(in);
        mWifiRunning = false;
        mWifiRunningTimer.readSummaryFromParcelLocked(in);
        mBluetoothOn = false;
        mBluetoothOnTimer.readSummaryFromParcelLocked(in);

        final int NU = in.readInt();
        for (int iu = 0; iu < NU; iu++) {
            int uid = in.readInt();
            Uid u = new Uid(uid);
            mUidStats.put(uid, u);

            u.mWifiTurnedOn = false;
            u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
            u.mFullWifiLockOut = false;
            u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
            u.mScanWifiLockOut = false;
            u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
            
            if (in.readInt() != 0) {
                if (u.mUserActivityCounters == null) {
                    u.initUserActivityLocked();
                }
                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
                    u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
                }
            }
            
            int NW = in.readInt();
            for (int iw = 0; iw < NW; iw++) {
                String wlName = in.readString();
                if (in.readInt() != 0) {
                    u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
                }
                if (in.readInt() != 0) {
                    u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
                }
                if (in.readInt() != 0) {
                    u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
                }
            }

            int NP = in.readInt();
            for (int is = 0; is < NP; is++) {
                int seNumber = in.readInt();
                if (in.readInt() != 0) {
                    u.getSensorTimerLocked(seNumber, true)
                            .readSummaryFromParcelLocked(in);
                }
            }

            NP = in.readInt();
            for (int ip = 0; ip < NP; ip++) {
                String procName = in.readString();
                Uid.Proc p = u.getProcessStatsLocked(procName);
                p.mUserTime = p.mLoadedUserTime = in.readLong();
                p.mLastUserTime = in.readLong();
                p.mSystemTime = p.mLoadedSystemTime = in.readLong();
                p.mLastSystemTime = in.readLong();
                p.mStarts = p.mLoadedStarts = in.readInt();
                p.mLastStarts = in.readInt();
            }

            NP = in.readInt();
            for (int ip = 0; ip < NP; ip++) {
                String pkgName = in.readString();
                Uid.Pkg p = u.getPackageStatsLocked(pkgName);
                p.mWakeups = p.mLoadedWakeups = in.readInt();
                p.mLastWakeups = in.readInt();
                final int NS = in.readInt();
                for (int is = 0; is < NS; is++) {
                    String servName = in.readString();
                    Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
                    s.mStartTime = s.mLoadedStartTime = in.readLong();
                    s.mLastStartTime = in.readLong();
                    s.mStarts = s.mLoadedStarts = in.readInt();
                    s.mLastStarts = in.readInt();
                    s.mLaunches = s.mLoadedLaunches = in.readInt();
                    s.mLastLaunches = in.readInt();
                }
            }

            u.mLoadedTcpBytesReceived = in.readLong();
            u.mLoadedTcpBytesSent = in.readLong();
        }
    
public voidremoveUidStatsLocked(int uid)
Remove the statistics object for a particular uid.

        mUidStats.remove(uid);
    
public voidsetOnBattery(boolean onBattery, int level)

        synchronized(this) {
            if (mOnBattery != onBattery) {
                mOnBattery = mOnBatteryInternal = onBattery;
                
                long uptime = SystemClock.uptimeMillis() * 1000;
                long mSecRealtime = SystemClock.elapsedRealtime();
                long realtime = mSecRealtime * 1000;
                if (onBattery) {
                    mTrackBatteryUptimeStart = uptime;
                    mTrackBatteryRealtimeStart = realtime;
                    mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
                    mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
                    mUnpluggedStartLevel = level;
                    doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
                } else {
                    mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
                    mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
                    mPluggedStartLevel = level;
                    doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
                }
                if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
                    if (mFile != null) {
                        writeLocked();
                    }
                }
            }
        }
    
public voidwriteLocked()

        if ((mFile == null) || (mBackupFile == null)) {
            Log.w("BatteryStats", "writeLocked: no file associated with this instance");
            return;
        }

        // Keep the old file around until we know the new one has
        // been successfully written.
        if (mFile.exists()) {
            if (mBackupFile.exists()) {
                mBackupFile.delete();
            }
            mFile.renameTo(mBackupFile);
        }

        try {
            FileOutputStream stream = new FileOutputStream(mFile);
            Parcel out = Parcel.obtain();
            writeSummaryToParcel(out);
            stream.write(out.marshall());
            out.recycle();

            stream.flush();
            stream.close();
            mBackupFile.delete();

            mLastWriteTime = SystemClock.elapsedRealtime();
        } catch (IOException e) {
            Log.e("BatteryStats", "Error writing battery statistics", e);
        }
    
public voidwriteSummaryToParcel(android.os.Parcel out)
Writes a summary of the statistics to a Parcel, in a format suitable to be written to disk. This format does not allow a lossless round-trip.

param
out the Parcel to be written to.

        final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
        final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
        final long NOW = getBatteryUptimeLocked(NOW_SYS);
        final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);

        out.writeInt(VERSION);

        out.writeInt(mStartCount);
        out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL));
        out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT));
        out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL));
        out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT));
        out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL));
        out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT));
        out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL));
        out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT));
        out.writeInt(mUnpluggedStartLevel);
        out.writeInt(mPluggedStartLevel);
        
        
        mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
            mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
        }
        mInputEventCounter.writeSummaryFromParcelLocked(out);
        mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
            mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
        }
        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
            mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
        }
        mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
        mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
        mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);

        final int NU = mUidStats.size();
        out.writeInt(NU);
        for (int iu = 0; iu < NU; iu++) {
            out.writeInt(mUidStats.keyAt(iu));
            Uid u = mUidStats.valueAt(iu);
            
            u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
            u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
            u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);

            if (u.mUserActivityCounters == null) {
                out.writeInt(0);
            } else {
                out.writeInt(1);
                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
                    u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
                }
            }
            
            int NW = u.mWakelockStats.size();
            out.writeInt(NW);
            if (NW > 0) {
                for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
                        : u.mWakelockStats.entrySet()) {
                    out.writeString(ent.getKey());
                    Uid.Wakelock wl = ent.getValue();
                    if (wl.mTimerFull != null) {
                        out.writeInt(1);
                        wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
                    } else {
                        out.writeInt(0);
                    }
                    if (wl.mTimerPartial != null) {
                        out.writeInt(1);
                        wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
                    } else {
                        out.writeInt(0);
                    }
                    if (wl.mTimerWindow != null) {
                        out.writeInt(1);
                        wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
                    } else {
                        out.writeInt(0);
                    }
                }
            }

            int NSE = u.mSensorStats.size();
            out.writeInt(NSE);
            if (NSE > 0) {
                for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
                        : u.mSensorStats.entrySet()) {
                    out.writeInt(ent.getKey());
                    Uid.Sensor se = ent.getValue();
                    if (se.mTimer != null) {
                        out.writeInt(1);
                        se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
                    } else {
                        out.writeInt(0);
                    }
                }
            }

            int NP = u.mProcessStats.size();
            out.writeInt(NP);
            if (NP > 0) {
                for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
                    : u.mProcessStats.entrySet()) {
                    out.writeString(ent.getKey());
                    Uid.Proc ps = ent.getValue();
                    out.writeLong(ps.mUserTime);
                    out.writeLong(ps.mUserTime - ps.mLoadedUserTime);
                    out.writeLong(ps.mSystemTime);
                    out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime);
                    out.writeInt(ps.mStarts);
                    out.writeInt(ps.mStarts - ps.mLoadedStarts);
                }
            }

            NP = u.mPackageStats.size();
            out.writeInt(NP);
            if (NP > 0) {
                for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
                    : u.mPackageStats.entrySet()) {
                    out.writeString(ent.getKey());
                    Uid.Pkg ps = ent.getValue();
                    out.writeInt(ps.mWakeups);
                    out.writeInt(ps.mWakeups - ps.mLoadedWakeups);
                    final int NS = ps.mServiceStats.size();
                    out.writeInt(NS);
                    if (NS > 0) {
                        for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
                                : ps.mServiceStats.entrySet()) {
                            out.writeString(sent.getKey());
                            BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
                            long time = ss.getStartTimeToNowLocked(NOW);
                            out.writeLong(time);
                            out.writeLong(time - ss.mLoadedStartTime);
                            out.writeInt(ss.mStarts);
                            out.writeInt(ss.mStarts - ss.mLoadedStarts);
                            out.writeInt(ss.mLaunches);
                            out.writeInt(ss.mLaunches - ss.mLoadedLaunches);
                        }
                    }
                }
            }
            
            out.writeLong(u.getTcpBytesReceived(STATS_TOTAL));
            out.writeLong(u.getTcpBytesSent(STATS_TOTAL));
        }
    
public voidwriteToParcel(android.os.Parcel out, int flags)

        writeToParcelLocked(out, flags);
    
voidwriteToParcelLocked(android.os.Parcel out, int flags)

        final long uSecUptime = SystemClock.uptimeMillis() * 1000;
        final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
        final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
        final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
        
        out.writeInt(MAGIC);
        out.writeInt(mStartCount);
        out.writeLong(mBatteryUptime);
        out.writeLong(mBatteryLastUptime);
        out.writeLong(mBatteryRealtime);
        out.writeLong(mBatteryLastRealtime);
        mScreenOnTimer.writeToParcel(out, batteryRealtime);
        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
            mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
        }
        mInputEventCounter.writeToParcel(out);
        mPhoneOnTimer.writeToParcel(out, batteryRealtime);
        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
            mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
        }
        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
            mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
        }
        mWifiOnTimer.writeToParcel(out, batteryRealtime);
        mWifiRunningTimer.writeToParcel(out, batteryRealtime);
        mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
        out.writeLong(mUptime);
        out.writeLong(mUptimeStart);
        out.writeLong(mLastUptime);
        out.writeLong(mRealtime);
        out.writeLong(mRealtimeStart);
        out.writeLong(mLastRealtime);
        out.writeInt(mOnBattery ? 1 : 0);
        out.writeLong(batteryUptime);
        out.writeLong(mTrackBatteryUptimeStart);
        out.writeLong(batteryRealtime);
        out.writeLong(mTrackBatteryRealtimeStart);
        out.writeLong(mUnpluggedBatteryUptime);
        out.writeLong(mUnpluggedBatteryRealtime);
        out.writeInt(mUnpluggedStartLevel);
        out.writeInt(mPluggedStartLevel);
        out.writeLong(mLastWriteTime);

        int size = mUidStats.size();
        out.writeInt(size);
        for (int i = 0; i < size; i++) {
            out.writeInt(mUidStats.keyAt(i));
            Uid uid = mUidStats.valueAt(i);

            uid.writeToParcelLocked(out, batteryRealtime);
        }