diff options
| author | Dianne Hackborn <hackbod@google.com> | 2014-03-22 00:26:19 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-03-22 00:26:19 +0000 |
| commit | e9c9c441346586e26eccc0523fcf12f5158e53f7 (patch) | |
| tree | ec879191d24c22bf326e5bad6655e4222317c740 | |
| parent | 18a65ad09d9a245266874015e5aacb05d868a534 (diff) | |
| parent | a1bd79268be693f04f4adee90673d6ed400cc9fd (diff) | |
| download | frameworks_base-e9c9c441346586e26eccc0523fcf12f5158e53f7.zip frameworks_base-e9c9c441346586e26eccc0523fcf12f5158e53f7.tar.gz frameworks_base-e9c9c441346586e26eccc0523fcf12f5158e53f7.tar.bz2 | |
Merge "Battery stats: track actually running time"
7 files changed, 430 insertions, 131 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index b0d94d5..87beb95 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -155,6 +155,7 @@ public abstract class BatteryStats implements Parcelable { private static final String FOREGROUND_DATA = "fg"; private static final String WAKELOCK_DATA = "wl"; private static final String KERNEL_WAKELOCK_DATA = "kwl"; + private static final String WAKEUP_REASON_DATA = "wr"; private static final String NETWORK_DATA = "nt"; private static final String USER_ACTIVITY_DATA = "ua"; private static final String BATTERY_DATA = "bt"; @@ -201,6 +202,25 @@ public abstract class BatteryStats implements Parcelable { } /** + * State for keeping track of long counting information. + */ + public static abstract class LongCounter { + + /** + * Returns the count associated with this Counter for the + * selected type of statistics. + * + * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT + */ + public abstract long getCountLocked(int which); + + /** + * Temporary for debugging. + */ + public abstract void logState(Printer pw, String prefix); + } + + /** * State for keeping track of timing information. */ public static abstract class Timer { @@ -552,8 +572,8 @@ public abstract class BatteryStats implements Parcelable { // These states always appear directly in the first int token // of a delta change; they should be ones that change relatively // frequently. - public static final int STATE_WAKE_LOCK_FLAG = 1<<31; - public static final int STATE_SENSOR_ON_FLAG = 1<<30; + public static final int STATE_CPU_RUNNING_FLAG = 1<<31; + public static final int STATE_WAKE_LOCK_FLAG = 1<<30; public static final int STATE_GPS_ON_FLAG = 1<<29; public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28; public static final int STATE_WIFI_SCAN_FLAG = 1<<27; @@ -562,9 +582,9 @@ public abstract class BatteryStats implements Parcelable { public static final int STATE_WIFI_RUNNING_FLAG = 1<<24; // These are on the lower bits used for the command; if they change // we need to write another int of data. - public static final int STATE_PHONE_SCANNING_FLAG = 1<<23; + public static final int STATE_SENSOR_ON_FLAG = 1<<23; public static final int STATE_AUDIO_ON_FLAG = 1<<22; - public static final int STATE_VIDEO_ON_FLAG = 1<<21; + public static final int STATE_PHONE_SCANNING_FLAG = 1<<21; public static final int STATE_SCREEN_ON_FLAG = 1<<20; public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18; @@ -577,6 +597,7 @@ public abstract class BatteryStats implements Parcelable { public int states; + public static final int STATE2_VIDEO_ON_FLAG = 1<<0; public int states2; // The wake lock that was acquired at this point. @@ -653,6 +674,7 @@ public abstract class BatteryStats implements Parcelable { | ((((int)batteryVoltage)<<16)&0xffff0000); dest.writeInt(bat); dest.writeInt(states); + dest.writeInt(states2); if (wakelockTag != null) { wakelockTag.writeToParcel(dest, flags); } @@ -680,6 +702,7 @@ public abstract class BatteryStats implements Parcelable { batteryTemperature = (short)(bat2&0xffff); batteryVoltage = (char)((bat2>>16)&0xffff); states = src.readInt(); + states2 = src.readInt(); if ((bat&0x10000000) != 0) { wakelockTag = localWakelockTag; wakelockTag.readFromParcel(src); @@ -718,6 +741,7 @@ public abstract class BatteryStats implements Parcelable { batteryTemperature = 0; batteryVoltage = 0; states = 0; + states2 = 0; wakelockTag = null; wakeReasonTag = null; eventCode = EVENT_NONE; @@ -744,6 +768,7 @@ public abstract class BatteryStats implements Parcelable { batteryTemperature = o.batteryTemperature; batteryVoltage = o.batteryVoltage; states = o.states; + states2 = o.states2; if (o.wakelockTag != null) { wakelockTag = localWakelockTag; wakelockTag.setTo(o.wakelockTag); @@ -774,6 +799,7 @@ public abstract class BatteryStats implements Parcelable { && batteryTemperature == o.batteryTemperature && batteryVoltage == o.batteryVoltage && states == o.states + && states2 == o.states2 && currentTime == o.currentTime; } @@ -970,6 +996,15 @@ public abstract class BatteryStats implements Parcelable { public abstract int getMobileRadioActiveCount(int which); /** + * Returns the time in microseconds that is the difference between the mobile radio + * time we saw based on the elapsed timestamp when going down vs. the given time stamp + * from the radio. + * + * {@hide} + */ + public abstract long getMobileRadioActiveAdjustedTime(int which); + + /** * Returns the time in microseconds that the mobile network has been active * (in a high power state) but not being able to blame on an app. * @@ -1026,9 +1061,10 @@ public abstract class BatteryStats implements Parcelable { * {@hide} */ public abstract int getPhoneDataConnectionCount(int dataType, int which); - + public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS = new BitDescription[] { + new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"), new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"), new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"), @@ -1039,7 +1075,6 @@ public abstract class BatteryStats implements Parcelable { new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"), new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"), new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"), - new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video", "v"), new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"), new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"), new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"), @@ -1062,6 +1097,11 @@ public abstract class BatteryStats implements Parcelable { SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES), }; + public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS + = new BitDescription[] { + new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"), + }; + public static final String[] HISTORY_EVENT_NAMES = new String[] { "null", "proc", "fg", "top", "sync" }; @@ -1294,6 +1334,8 @@ public abstract class BatteryStats implements Parcelable { */ public abstract long computeRealtime(long curTime, int which); + public abstract Map<String, ? extends LongCounter> getWakeupReasonStats(); + public abstract Map<String, ? extends Timer> getKernelWakelockStats(); /** Returns the number of different speeds that the CPU can run at */ @@ -1554,7 +1596,8 @@ public abstract class BatteryStats implements Parcelable { wifiRunningTime / 1000, bluetoothOnTime / 1000, mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, fullWakeLockTimeTotal, partialWakeLockTimeTotal, - getInputEventCount(which), getMobileRadioActiveTime(rawRealtime, which)); + getInputEventCount(which), getMobileRadioActiveTime(rawRealtime, which), + getMobileRadioActiveAdjustedTime(which)); // Dump screen brightness stats Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; @@ -1626,16 +1669,22 @@ public abstract class BatteryStats implements Parcelable { } if (reqUid < 0) { - Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats(); + Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats(); if (kernelWakelocks.size() > 0) { - for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) { + for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) { sb.setLength(0); printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, ""); - - dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), + dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), sb.toString()); } } + Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats(); + if (wakeupReasons.size() > 0) { + for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) { + dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA, + "\"" + ent.getKey() + "\"", ent.getValue().getCountLocked(which)); + } + } } BatteryStatsHelper helper = new BatteryStatsHelper(context); @@ -2111,6 +2160,18 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } + final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which); + if (mobileActiveAdjustedTime != 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Mobile radio active adjusted time: "); + formatTimeMs(sb, mobileActiveAdjustedTime / 1000); + sb.append("("); + sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime)); + sb.append(")"); + pw.println(sb.toString()); + } + pw.print(prefix); pw.print(" Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes)); pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes)); @@ -2346,24 +2407,49 @@ public abstract class BatteryStats implements Parcelable { pw.println(); } } - } - if (timers.size() > 0) { - Collections.sort(timers, timerComparator); - pw.print(prefix); pw.println(" All partial wake locks:"); - for (int i=0; i<timers.size(); i++) { - TimerEntry timer = timers.get(i); - sb.setLength(0); - sb.append(" Wake lock "); - UserHandle.formatUid(sb, timer.mId); - sb.append(" "); - sb.append(timer.mName); - printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": "); - sb.append(" realtime"); - pw.println(sb.toString()); + if (timers.size() > 0) { + Collections.sort(timers, timerComparator); + pw.print(prefix); pw.println(" All partial wake locks:"); + for (int i=0; i<timers.size(); i++) { + TimerEntry timer = timers.get(i); + sb.setLength(0); + sb.append(" Wake lock "); + UserHandle.formatUid(sb, timer.mId); + sb.append(" "); + sb.append(timer.mName); + printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": "); + sb.append(" realtime"); + pw.println(sb.toString()); + } + timers.clear(); + pw.println(); + } + + Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats(); + if (wakeupReasons.size() > 0) { + pw.print(prefix); pw.println(" All wakeup reasons:"); + final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>(); + for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) { + BatteryStats.LongCounter counter = ent.getValue(); + reasons.add(new TimerEntry(ent.getKey(), 0, null, + ent.getValue().getCountLocked(which))); + } + Collections.sort(reasons, timerComparator); + for (int i=0; i<reasons.size(); i++) { + TimerEntry timer = reasons.get(i); + String linePrefix = ": "; + sb.setLength(0); + sb.append(prefix); + sb.append(" Wakeup reason "); + sb.append(timer.mName); + sb.append(": "); + formatTimeMs(sb, timer.mTime); + sb.append("realtime"); + pw.println(sb.toString()); + } + pw.println(); } - timers.clear(); - pw.println(); } for (int iu=0; iu<NU; iu++) { @@ -2772,6 +2858,7 @@ public abstract class BatteryStats implements Parcelable { public static class HistoryPrinter { int oldState = 0; + int oldState2 = 0; int oldLevel = -1; int oldStatus = -1; int oldHealth = -1; @@ -2780,7 +2867,8 @@ public abstract class BatteryStats implements Parcelable { int oldVolt = -1; long lastTime = -1; - public void printNextItem(PrintWriter pw, HistoryItem rec, long now, boolean checkin) { + public void printNextItem(PrintWriter pw, HistoryItem rec, long now, boolean checkin, + boolean verbose) { if (!checkin) { pw.print(" "); if (now >= 0) { @@ -2831,16 +2919,18 @@ public abstract class BatteryStats implements Parcelable { if (rec.batteryLevel < 10) pw.print("00"); else if (rec.batteryLevel < 100) pw.print("0"); pw.print(rec.batteryLevel); - pw.print(" "); - if (rec.states < 0) ; - else if (rec.states < 0x10) pw.print("0000000"); - else if (rec.states < 0x100) pw.print("000000"); - else if (rec.states < 0x1000) pw.print("00000"); - else if (rec.states < 0x10000) pw.print("0000"); - else if (rec.states < 0x100000) pw.print("000"); - else if (rec.states < 0x1000000) pw.print("00"); - else if (rec.states < 0x10000000) pw.print("0"); - pw.print(Integer.toHexString(rec.states)); + if (verbose) { + pw.print(" "); + if (rec.states < 0) ; + else if (rec.states < 0x10) pw.print("0000000"); + else if (rec.states < 0x100) pw.print("000000"); + else if (rec.states < 0x1000) pw.print("00000"); + else if (rec.states < 0x10000) pw.print("0000"); + else if (rec.states < 0x100000) pw.print("000"); + else if (rec.states < 0x1000000) pw.print("00"); + else if (rec.states < 0x10000000) pw.print("0"); + pw.print(Integer.toHexString(rec.states)); + } } else { if (oldLevel != rec.batteryLevel) { oldLevel = rec.batteryLevel; @@ -2934,6 +3024,8 @@ public abstract class BatteryStats implements Parcelable { } printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag, HISTORY_STATE_DESCRIPTIONS, !checkin); + printBitDescriptions(pw, oldState2, rec.states2, null, + HISTORY_STATE2_DESCRIPTIONS, !checkin); if (rec.wakeReasonTag != null) { if (checkin) { pw.print(",Wr="); @@ -3010,6 +3102,7 @@ public abstract class BatteryStats implements Parcelable { public static final int DUMP_CHARGED_ONLY = 1<<1; public static final int DUMP_HISTORY_ONLY = 1<<2; public static final int DUMP_INCLUDE_HISTORY = 1<<3; + public static final int DUMP_VERBOSE = 1<<4; /** * Dumps a human-readable summary of the battery statistics to the given PrintWriter. @@ -3047,7 +3140,8 @@ public abstract class BatteryStats implements Parcelable { while (getNextHistoryLocked(rec)) { lastTime = rec.time; if (rec.time >= histStart) { - hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, false); + hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, false, + (flags&DUMP_VERBOSE) != 0); } } if (histStart >= 0) { @@ -3064,7 +3158,7 @@ public abstract class BatteryStats implements Parcelable { pw.println("Old battery History:"); HistoryPrinter hprinter = new HistoryPrinter(); while (getNextOldHistoryLocked(rec)) { - hprinter.printNextItem(pw, rec, now, false); + hprinter.printNextItem(pw, rec, now, false, (flags&DUMP_VERBOSE) != 0); } pw.println(); } finally { @@ -3150,7 +3244,7 @@ public abstract class BatteryStats implements Parcelable { if (rec.time >= histStart) { pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); pw.print(HISTORY_DATA); pw.print(','); - hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, true); + hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, true, false); } } if (histStart >= 0) { diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 5ba5c57..32f700d 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -55,7 +55,7 @@ interface IBatteryStats { void noteScreenOff(); void noteInputEvent(); void noteUserActivity(int uid, int event); - void noteDataConnectionActive(int type, boolean active); + void noteDataConnectionActive(int type, boolean active, long timestampNs); void notePhoneOn(); void notePhoneOff(); void notePhoneSignalStrength(in SignalStrength signalStrength); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 082f1a5..1d88533 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -87,7 +87,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 99 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 101 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -191,7 +191,7 @@ public final class BatteryStatsImpl extends BatteryStats { long mHistoryBaseTime; boolean mHaveBatteryLevel = false; - boolean mRecordingHistory = true; + boolean mRecordingHistory = false; int mNumHistoryItems; static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB @@ -200,6 +200,7 @@ public final class BatteryStatsImpl extends BatteryStats { final HistoryItem mHistoryLastWritten = new HistoryItem(); final HistoryItem mHistoryLastLastWritten = new HistoryItem(); final HistoryItem mHistoryReadTmp = new HistoryItem(); + final HistoryItem mHistoryAddTmp = new HistoryItem(); final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<HistoryTag, Integer>(); String[] mReadHistoryStrings; int[] mReadHistoryUids; @@ -209,7 +210,8 @@ public final class BatteryStatsImpl extends BatteryStats { int mHistoryBufferLastPos = -1; boolean mHistoryOverflow = false; long mLastHistoryElapsedRealtime = 0; - long mLastHistoryUptime = 0; + long mTrackRunningHistoryElapsedRealtime = 0; + long mTrackRunningHistoryUptime = 0; final HistoryItem mHistoryCur = new HistoryItem(); @@ -287,6 +289,7 @@ public final class BatteryStatsImpl extends BatteryStats { boolean mMobileRadioActive; StopwatchTimer mMobileRadioActiveTimer; StopwatchTimer mMobileRadioActivePerAppTimer; + LongSamplingCounter mMobileRadioActiveAdjustedTime; LongSamplingCounter mMobileRadioActiveUnknownTime; LongSamplingCounter mMobileRadioActiveUnknownCount; @@ -330,12 +333,21 @@ public final class BatteryStatsImpl extends BatteryStats { private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<String, SamplingTimer>(); - public Map<String, ? extends SamplingTimer> getKernelWakelockStats() { + public Map<String, ? extends Timer> getKernelWakelockStats() { return mKernelWakelockStats; } private static int sKernelWakelockUpdateVersion = 0; + String mLastWakeupReason = null; + long mLastWakeupUptimeMs = 0; + private final HashMap<String, LongSamplingCounter> mWakeupReasonStats = + new HashMap<String, LongSamplingCounter>(); + + public Map<String, ? extends LongCounter> getWakeupReasonStats() { + return mWakeupReasonStats; + } + private static final int[] PROC_WAKELOCKS_FORMAT = new int[] { Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name Process.PROC_QUOTES, @@ -719,7 +731,7 @@ public final class BatteryStatsImpl extends BatteryStats { } } - public static class LongSamplingCounter implements TimeBaseObs { + public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { final TimeBase mTimeBase; long mCount; long mLoadedCount; @@ -775,6 +787,14 @@ public final class BatteryStatsImpl extends BatteryStats { return val; } + @Override + public void logState(Printer pw, String prefix) { + pw.println(prefix + "mCount=" + mCount + + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount + + " mUnpluggedCount=" + mUnpluggedCount + + " mPluggedCount=" + mPluggedCount); + } + void addCountLocked(long count) { mCount += count; } @@ -1409,6 +1429,10 @@ public final class BatteryStatsImpl extends BatteryStats { return 0; } + long getLastUpdateTimeMs() { + return mUpdateTime; + } + void stopRunningLocked(long elapsedRealtimeMs) { // Ignore attempt to stop a timer that isn't running if (mNesting == 0) { @@ -1502,6 +1526,19 @@ public final class BatteryStatsImpl extends BatteryStats { } } + /* + * Get the wakeup reason counter, and create a new one if one + * doesn't already exist. + */ + public LongSamplingCounter getWakeupReasonCounterLocked(String name) { + LongSamplingCounter counter = mWakeupReasonStats.get(name); + if (counter == null) { + counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); + mWakeupReasonStats.put(name, counter); + } + return counter; + } + private final Map<String, KernelWakelockStats> readKernelWakelockStats() { FileInputStream is; @@ -1759,6 +1796,10 @@ public final class BatteryStatsImpl extends BatteryStats { if (stateIntChanged) { firstToken |= DELTA_STATE_FLAG; } + final boolean state2IntChanged = cur.states2 != last.states2; + if (state2IntChanged) { + firstToken |= DELTA_STATE2_FLAG; + } if (cur.wakelockTag != null || cur.wakeReasonTag != null) { firstToken |= DELTA_WAKELOCK_FLAG; } @@ -1795,6 +1836,11 @@ public final class BatteryStatsImpl extends BatteryStats { + " batteryPlugType=" + cur.batteryPlugType + " states=0x" + Integer.toHexString(cur.states)); } + if (state2IntChanged) { + dest.writeInt(cur.states2); + if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" + + Integer.toHexString(cur.states2)); + } if (cur.wakelockTag != null || cur.wakeReasonTag != null) { int wakeLockIndex; int wakeReasonIndex; @@ -1917,6 +1963,12 @@ public final class BatteryStatsImpl extends BatteryStats { cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK)); } + if ((firstToken&DELTA_STATE2_FLAG) != 0) { + cur.states2 = src.readInt(); + if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" + + Integer.toHexString(cur.states2)); + } + if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { int indexes = src.readInt(); int wakeLockIndex = indexes&0xffff; @@ -1958,29 +2010,34 @@ public final class BatteryStatsImpl extends BatteryStats { } } - void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs) { + void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { if (!mHaveBatteryLevel || !mRecordingHistory) { return; } final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; - final int diffStates = mHistoryLastWritten.states^mHistoryCur.states; + final int diffStates = mHistoryLastWritten.states^cur.states; + final int diffStates2 = mHistoryLastWritten.states2^cur.states2; final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; + final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" + Integer.toHexString(diffStates) + " lastDiff=" - + Integer.toHexString(lastDiffStates)); + + Integer.toHexString(lastDiffStates) + " diff2=" + + Integer.toHexString(diffStates2) + " lastDiff2=" + + Integer.toHexString(lastDiffStates2)); if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 - && (mHistoryLastWritten.wakelockTag == null || mHistoryCur.wakelockTag == null) - && (mHistoryLastWritten.wakeReasonTag == null || mHistoryCur.wakeReasonTag == null) + && (diffStates2&lastDiffStates2) == 0 + && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) + && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE - || mHistoryCur.eventCode == HistoryItem.EVENT_NONE) - && mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel - && mHistoryLastWritten.batteryStatus == mHistoryCur.batteryStatus - && mHistoryLastWritten.batteryHealth == mHistoryCur.batteryHealth - && mHistoryLastWritten.batteryPlugType == mHistoryCur.batteryPlugType - && mHistoryLastWritten.batteryTemperature == mHistoryCur.batteryTemperature - && mHistoryLastWritten.batteryVoltage == mHistoryCur.batteryVoltage) { + || cur.eventCode == HistoryItem.EVENT_NONE) + && mHistoryLastWritten.batteryLevel == cur.batteryLevel + && mHistoryLastWritten.batteryStatus == cur.batteryStatus + && mHistoryLastWritten.batteryHealth == cur.batteryHealth + && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType + && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature + && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { // We can merge this new change in with the last one. Merging is // allowed as long as only the states have changed, and within those states // as long as no bit has changed both between now and the last entry, as @@ -1994,23 +2051,23 @@ public final class BatteryStatsImpl extends BatteryStats { // Note that the condition above made sure that we aren't in a case where // both it and the current history item have a wakelock tag. if (mHistoryLastWritten.wakelockTag != null) { - mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; - mHistoryCur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); + cur.wakelockTag = cur.localWakelockTag; + cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); } // If the last written history had a wake reason tag, we need to retain it. // Note that the condition above made sure that we aren't in a case where // both it and the current history item have a wakelock tag. if (mHistoryLastWritten.wakeReasonTag != null) { - mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; - mHistoryCur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); + cur.wakeReasonTag = cur.localWakeReasonTag; + cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); } // If the last written history had an event, we need to retain it. // Note that the condition above made sure that we aren't in a case where // both it and the current history item have an event. if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { - mHistoryCur.eventCode = mHistoryLastWritten.eventCode; - mHistoryCur.eventTag = mHistoryCur.localEventTag; - mHistoryCur.eventTag.setTo(mHistoryLastWritten.eventTag); + cur.eventCode = mHistoryLastWritten.eventCode; + cur.eventTag = cur.localEventTag; + cur.eventTag.setTo(mHistoryLastWritten.eventTag); } mHistoryLastWritten.setTo(mHistoryLastLastWritten); } @@ -2019,8 +2076,8 @@ public final class BatteryStatsImpl extends BatteryStats { if (dataSize >= MAX_HISTORY_BUFFER) { if (!mHistoryOverflow) { mHistoryOverflow = true; - addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE); - addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW); + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur); return; } @@ -2028,43 +2085,64 @@ public final class BatteryStatsImpl extends BatteryStats { // 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 && + if (mHistoryLastWritten.batteryLevel == cur.batteryLevel && (dataSize >= MAX_MAX_HISTORY_BUFFER - || ((mHistoryLastWritten.states^mHistoryCur.states) + || ((mHistoryLastWritten.states^cur.states) & HistoryItem.MOST_INTERESTING_STATES) == 0)) { return; } - addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE); + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); return; } - addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE); + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); } - private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd) { + private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, + HistoryItem cur) { if (mIteratingHistory) { throw new IllegalStateException("Can't do this while iterating history!"); } mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); mHistoryLastLastWritten.setTo(mHistoryLastWritten); - mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, mHistoryCur); + mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); mLastHistoryElapsedRealtime = elapsedRealtimeMs; - mLastHistoryUptime = uptimeMs; - mHistoryCur.wakelockTag = null; - mHistoryCur.wakeReasonTag = null; - mHistoryCur.eventCode = HistoryItem.EVENT_NONE; - mHistoryCur.eventTag = null; + cur.wakelockTag = null; + cur.wakeReasonTag = null; + cur.eventCode = HistoryItem.EVENT_NONE; + cur.eventTag = null; if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos + " now " + mHistoryBuffer.dataPosition() + " size is now " + mHistoryBuffer.dataSize()); } int mChangedStates = 0; + int mChangedStates2 = 0; void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { - addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs); + if (mTrackRunningHistoryElapsedRealtime != 0) { + final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; + final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; + if (diffUptime < (diffElapsed-20)) { + final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); + mHistoryAddTmp.setTo(mHistoryLastWritten); + mHistoryAddTmp.wakelockTag = null; + mHistoryAddTmp.wakeReasonTag = null; + mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; + mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; + addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp); + } + } + mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; + mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; + mTrackRunningHistoryUptime = uptimeMs; + addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); + } + + void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); if (!USE_OLD_HISTORY) { return; @@ -2080,25 +2158,28 @@ public final class BatteryStatsImpl extends BatteryStats { // into one record. if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) - && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) { + && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0 + && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) { // If the current is the same as the one before, then we no // longer need the entry. if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) - && mHistoryLastEnd.sameNonEvent(mHistoryCur)) { + && mHistoryLastEnd.sameNonEvent(cur)) { mHistoryLastEnd.next = null; mHistoryEnd.next = mHistoryCache; mHistoryCache = mHistoryEnd; mHistoryEnd = mHistoryLastEnd; mHistoryLastEnd = null; } else { - mChangedStates |= mHistoryEnd.states^mHistoryCur.states; - mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur); + mChangedStates |= mHistoryEnd.states^cur.states; + mChangedStates2 |= mHistoryEnd.states^cur.states2; + mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); } return; } mChangedStates = 0; + mChangedStates2 = 0; if (mNumHistoryItems == MAX_HISTORY_ITEMS || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) { @@ -2111,9 +2192,9 @@ public final class BatteryStatsImpl extends BatteryStats { // Once we've reached the maximum maximum number of items, we only // record changes to the battery level. if (mHistoryEnd != null && mHistoryEnd.batteryLevel - == mHistoryCur.batteryLevel && + == cur.batteryLevel && (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS - || ((mHistoryEnd.states^mHistoryCur.states) + || ((mHistoryEnd.states^cur.states) & HistoryItem.MOST_INTERESTING_STATES) == 0)) { return; } @@ -2128,17 +2209,18 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryCur.eventTag = mHistoryCur.localEventTag; mHistoryCur.eventTag.string = name; mHistoryCur.eventTag.uid = uid; - addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs); + // XXX should be calling addHistoryRecordLocked()? + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); } - void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd) { + void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { HistoryItem rec = mHistoryCache; if (rec != null) { mHistoryCache = rec.next; } else { rec = new HistoryItem(); } - rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, mHistoryCur); + rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); addHistoryRecordLocked(rec); } @@ -2168,7 +2250,8 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryBaseTime = 0; mLastHistoryElapsedRealtime = 0; - mLastHistoryUptime = 0; + mTrackRunningHistoryElapsedRealtime = 0; + mTrackRunningHistoryUptime = 0; mHistoryBuffer.setDataSize(0); mHistoryBuffer.setDataPosition(0); @@ -2284,6 +2367,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (type == WAKE_TYPE_PARTIAL) { // Only care about partial wake locks, since full wake locks // will be canceled when the user puts the screen to sleep. + aggregateLastWakeupUptimeLocked(uptime); if (mWakeLockNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " @@ -2372,14 +2456,26 @@ public final class BatteryStatsImpl extends BatteryStats { } } - public void noteWakeupReasonLocked(int irq, String reason) { + void aggregateLastWakeupUptimeLocked(long uptimeMs) { + if (mLastWakeupReason != null) { + long deltaUptime = uptimeMs - mLastWakeupUptimeMs; + LongSamplingCounter timer = getWakeupReasonCounterLocked(mLastWakeupReason); + timer.addCountLocked(deltaUptime); + mLastWakeupReason = null; + } + } + + public void noteWakeupReasonLocked(String reason) { final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); - if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason irq #" + irq + "\"" + reason +"\": " + if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason reason \"" + reason +"\": " + Integer.toHexString(mHistoryCur.states)); + aggregateLastWakeupUptimeLocked(uptime); mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; mHistoryCur.wakeReasonTag.string = reason; - mHistoryCur.wakeReasonTag.uid = irq; + mHistoryCur.wakeReasonTag.uid = 0; + mLastWakeupReason = reason; + mLastWakeupUptimeMs = uptime; addHistoryRecordLocked(elapsedRealtime, uptime); } @@ -2670,13 +2766,28 @@ public final class BatteryStatsImpl extends BatteryStats { } } - public void noteDataConnectionActive(int type, boolean active) { + public void noteDataConnectionActive(int type, boolean active, long timestampNs) { if (ConnectivityManager.isNetworkTypeMobile(type)) { final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); if (mMobileRadioActive != active) { - if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; - else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; + long realElapsedRealtimeMs; + if (active) { + realElapsedRealtimeMs = elapsedRealtime; + mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; + } else { + realElapsedRealtimeMs = timestampNs / (1000*1000); + long lastUpdateTimeMs = mMobileRadioActiveTimer.getLastUpdateTimeMs(); + if (realElapsedRealtimeMs < lastUpdateTimeMs) { + Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs + + " is before start time " + lastUpdateTimeMs); + realElapsedRealtimeMs = elapsedRealtime; + } else if (realElapsedRealtimeMs < elapsedRealtime) { + mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime + - realElapsedRealtimeMs); + } + mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; + } if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " + Integer.toHexString(mHistoryCur.states)); addHistoryRecordLocked(elapsedRealtime, uptime); @@ -2685,9 +2796,9 @@ public final class BatteryStatsImpl extends BatteryStats { mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); } else { - updateNetworkActivityLocked(NET_UPDATE_MOBILE, elapsedRealtime); - mMobileRadioActiveTimer.stopRunningLocked(elapsedRealtime); - mMobileRadioActivePerAppTimer.stopRunningLocked(elapsedRealtime); + mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); + mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); + updateNetworkActivityLocked(NET_UPDATE_MOBILE, realElapsedRealtimeMs); } } } @@ -2978,7 +3089,7 @@ public final class BatteryStatsImpl extends BatteryStats { final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); if (!mVideoOn) { - mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG; + mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " + Integer.toHexString(mHistoryCur.states)); addHistoryRecordLocked(elapsedRealtime, uptime); @@ -2993,7 +3104,7 @@ public final class BatteryStatsImpl extends BatteryStats { final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); if (mVideoOn) { - mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG; + mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " + Integer.toHexString(mHistoryCur.states)); addHistoryRecordLocked(elapsedRealtime, uptime); @@ -3398,6 +3509,10 @@ public final class BatteryStatsImpl extends BatteryStats { return mMobileRadioActiveTimer.getCountLocked(which); } + @Override public long getMobileRadioActiveAdjustedTime(int which) { + return mMobileRadioActiveAdjustedTime.getCountLocked(which); + } + @Override public long getMobileRadioActiveUnknownTime(int which) { return mMobileRadioActiveUnknownTime.getCountLocked(which); } @@ -5458,6 +5573,7 @@ public final class BatteryStatsImpl extends BatteryStats { } mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase); mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase); + mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); mWifiOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase); @@ -5543,9 +5659,9 @@ public final class BatteryStatsImpl extends BatteryStats { PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); pw.println("Histories differ!"); pw.println("Old history:"); - (new HistoryPrinter()).printNextItem(pw, out, now, false); + (new HistoryPrinter()).printNextItem(pw, out, now, false, true); pw.println("New history:"); - (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now, false); + (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now, false, true); pw.flush(); } } @@ -5719,6 +5835,7 @@ public final class BatteryStatsImpl extends BatteryStats { } mMobileRadioActiveTimer.reset(false); mMobileRadioActivePerAppTimer.reset(false); + mMobileRadioActiveAdjustedTime.reset(false); mMobileRadioActiveUnknownTime.reset(false); mMobileRadioActiveUnknownCount.reset(false); mWifiOnTimer.reset(false); @@ -5744,7 +5861,14 @@ public final class BatteryStatsImpl extends BatteryStats { } mKernelWakelockStats.clear(); } - + + if (mWakeupReasonStats.size() > 0) { + for (LongSamplingCounter timer : mWakeupReasonStats.values()) { + mOnBatteryScreenOffTimeBase.remove(timer); + } + mWakeupReasonStats.clear(); + } + initDischarge(); clearHistoryLocked(); @@ -5828,9 +5952,10 @@ public final class BatteryStatsImpl extends BatteryStats { mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " + Integer.toHexString(mHistoryCur.states)); - mHistoryCur.currentTime = System.currentTimeMillis(); - addHistoryBufferLocked(mSecRealtime, mSecUptime, HistoryItem.CMD_CURRENT_TIME); - mHistoryCur.currentTime = 0; + if (reset) { + mRecordingHistory = true; + startRecordingHistory(mSecRealtime, mSecUptime, reset); + } addHistoryRecordLocked(mSecRealtime, mSecUptime); mDischargeCurrentLevel = mDischargeUnplugLevel = level; if (mScreenOn) { @@ -5843,9 +5968,6 @@ public final class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenOn = 0; mDischargeAmountScreenOff = 0; updateTimeBasesLocked(true, !mScreenOn, uptime, realtime); - if (reset) { - initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); - } } else { pullPendingStateUpdatesLocked(); mHistoryCur.batteryLevel = (byte)level; @@ -5868,6 +5990,18 @@ public final class BatteryStatsImpl extends BatteryStats { } } + private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, + boolean reset) { + mRecordingHistory = true; + mHistoryCur.currentTime = System.currentTimeMillis(); + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME, + mHistoryCur); + mHistoryCur.currentTime = 0; + if (reset) { + initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); + } + } + // This should probably be exposed in the API, though it's not critical private static final int BATTERY_PLUGGED_NONE = 0; @@ -5895,7 +6029,15 @@ public final class BatteryStatsImpl extends BatteryStats { } if (onBattery) { mDischargeCurrentLevel = level; - mRecordingHistory = true; + if (!mRecordingHistory) { + mRecordingHistory = true; + startRecordingHistory(elapsedRealtime, uptime, true); + } + } else if (level < 96) { + if (!mRecordingHistory) { + mRecordingHistory = true; + startRecordingHistory(elapsedRealtime, uptime, true); + } } if (onBattery != mOnBattery) { mHistoryCur.batteryLevel = (byte)level; @@ -6497,15 +6639,14 @@ public final class BatteryStatsImpl extends BatteryStats { } if (mHistoryBuffer.dataPosition() > 0) { + mRecordingHistory = true; final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); if (USE_OLD_HISTORY) { - addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START); + addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); } - addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START); - mHistoryCur.currentTime = System.currentTimeMillis(); - addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_CURRENT_TIME); - mHistoryCur.currentTime = 0; + addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); + startRecordingHistory(elapsedRealtime, uptime, false); } } @@ -6681,6 +6822,7 @@ public final class BatteryStatsImpl extends BatteryStats { mMobileRadioActive = false; mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); + mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); mWifiOn = false; @@ -6708,6 +6850,18 @@ public final class BatteryStatsImpl extends BatteryStats { } } + int NWR = in.readInt(); + if (NWR > 10000) { + Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR); + return; + } + for (int iwr = 0; iwr < NWR; iwr++) { + if (in.readInt() != 0) { + String reasonName = in.readString(); + getWakeupReasonCounterLocked(reasonName).readSummaryFromParcelLocked(in); + } + } + sNumSpeedSteps = in.readInt(); if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) { throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps); @@ -6915,6 +7069,7 @@ public final class BatteryStatsImpl extends BatteryStats { } mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); @@ -6933,7 +7088,19 @@ public final class BatteryStatsImpl extends BatteryStats { if (kwlt != null) { out.writeInt(1); out.writeString(ent.getKey()); - ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL_SYS); + kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } else { + out.writeInt(0); + } + } + + out.writeInt(mWakeupReasonStats.size()); + for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) { + LongSamplingCounter counter = ent.getValue(); + if (counter != null) { + out.writeInt(1); + out.writeString(ent.getKey()); + counter.writeSummaryFromParcelLocked(out); } else { out.writeInt(0); } @@ -7171,6 +7338,7 @@ public final class BatteryStatsImpl extends BatteryStats { mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in); mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase, in); + mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); mWifiOn = false; @@ -7205,12 +7373,22 @@ public final class BatteryStatsImpl extends BatteryStats { for (int ikw = 0; ikw < NKW; ikw++) { if (in.readInt() != 0) { String wakelockName = in.readString(); - in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel SamplingTimer kwlt = new SamplingTimer(mOnBatteryTimeBase, in); mKernelWakelockStats.put(wakelockName, kwlt); } } + mWakeupReasonStats.clear(); + int NWR = in.readInt(); + for (int iwr = 0; iwr < NWR; iwr++) { + if (in.readInt() != 0) { + String reasonName = in.readString(); + LongSamplingCounter counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, + in); + mWakeupReasonStats.put(reasonName, counter); + } + } + mPartialTimers.clear(); mFullTimers.clear(); mWindowTimers.clear(); @@ -7283,6 +7461,7 @@ public final class BatteryStatsImpl extends BatteryStats { } mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); + mMobileRadioActiveAdjustedTime.writeToParcel(out); mMobileRadioActiveUnknownTime.writeToParcel(out); mMobileRadioActiveUnknownCount.writeToParcel(out); mWifiOnTimer.writeToParcel(out, uSecRealtime); @@ -7313,7 +7492,18 @@ public final class BatteryStatsImpl extends BatteryStats { if (kwlt != null) { out.writeInt(1); out.writeString(ent.getKey()); - Timer.writeTimerToParcel(out, kwlt, uSecRealtime); + kwlt.writeToParcel(out, uSecRealtime); + } else { + out.writeInt(0); + } + } + out.writeInt(mWakeupReasonStats.size()); + for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) { + LongSamplingCounter counter = ent.getValue(); + if (counter != null) { + out.writeInt(1); + out.writeString(ent.getKey()); + counter.writeToParcel(out); } else { out.writeInt(0); } @@ -7383,6 +7573,8 @@ public final class BatteryStatsImpl extends BatteryStats { } pr.println("*** Mobile network active timer:"); mMobileRadioActiveTimer.logState(pr, " "); + pr.println("*** Mobile network active adjusted timer:"); + mMobileRadioActiveAdjustedTime.logState(pr, " "); pr.println("*** Wifi timer:"); mWifiOnTimer.logState(pr, " "); pr.println("*** WifiRunning timer:"); diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 9de3efe..41ffdc1 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -103,6 +103,7 @@ class AlarmManagerService extends SystemService { private long mNextNonWakeup; int mBroadcastRefCount = 0; PowerManager.WakeLock mWakeLock; + boolean mLastWakeLockUnimportantForLogging; ArrayList<InFlight> mInFlight = new ArrayList<InFlight>(); final AlarmHandler mHandler = new AlarmHandler(); ClockReceiver mClockReceiver; @@ -1345,17 +1346,21 @@ class AlarmManagerService extends SystemService { */ void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, boolean first) { try { - mWakeLock.setUnimportantForLogging(pi == mTimeTickSender); + final boolean unimportant = pi == mTimeTickSender; + mWakeLock.setUnimportantForLogging(unimportant); if (ws != null) { - if (first) { + if (first || mLastWakeLockUnimportantForLogging) { mWakeLock.setHistoryTag(pi.getTag( type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP ? "*walarm*:" : "*alarm*:")); } else { mWakeLock.setHistoryTag(null); } + mLastWakeLockUnimportantForLogging = unimportant; mWakeLock.setWorkSource(ws); return; + } else { + mLastWakeLockUnimportantForLogging = false; } final int uid = ActivityManagerNative.getDefault() diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index a09d605..5273cec 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -348,7 +348,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub */ private void notifyInterfaceClassActivity(int type, boolean active, long tsNanos) { try { - getBatteryStats().noteDataConnectionActive(type, active); + getBatteryStats().noteDataConnectionActive(type, active, tsNanos); } catch (RemoteException e) { } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index fa4a9d1..0ddb827 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -248,10 +248,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } - public void noteDataConnectionActive(int type, boolean active) { + public void noteDataConnectionActive(int type, boolean active, long timestampNs) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteDataConnectionActive(type, active); + mStats.noteDataConnectionActive(type, active, timestampNs); } } @@ -570,9 +570,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub { int num; while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) { synchronized (mStats) { - for (int i=0; i<num; i++) { - //Slog.i(TAG, "Wakeup: irq #" + mIrqs[i] + " reason=" + mReasons[i]); - mStats.noteWakeupReasonLocked(mIrqs[i], mReasons[i]); + if (num > 0) { + for (int i=0; i<num; i++) { + mStats.noteWakeupReasonLocked(mReasons[i]); + } + } else { + mStats.noteWakeupReasonLocked("unknown"); } } } @@ -653,7 +656,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { dumpHelp(pw); return; } else if ("-a".equals(arg)) { - // fall through + flags |= BatteryStats.DUMP_VERBOSE; } else if (arg.length() > 0 && arg.charAt(0) == '-'){ pw.println("Unknown option: " + arg); dumpHelp(pw); diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index 22cc519..da4cc48 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -139,16 +139,21 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs, } endpos++; } - if (i == 0) { + // For now we are not separating out the first irq. + // This is because in practice there are always multiple + // lines of wakeup reasons, so it is better to just treat + // them all together as a single string. + if (false && i == 0) { firstirq = irq; } else { - int len = snprintf(mergedreasonpos, remainreasonlen, ":%d", irq); + int len = snprintf(mergedreasonpos, remainreasonlen, + i == 0 ? "%d" : ":%d", irq); if (len >= 0 && len < remainreasonlen) { mergedreasonpos += len; remainreasonlen -= len; } } - int len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "%s" : ":%s", pos); + int len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos); if (len >= 0 && len < remainreasonlen) { mergedreasonpos += len; remainreasonlen -= len; |
