From d1eccbea388fde6a575acb4e797efdd07798344a Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 18 Feb 2015 14:02:14 -0800 Subject: [PATCH] Add some detailed data as part of battery history. Every time the battery level changes, a new extended detailed use data structure is written to the history. This currently only contains delta CPU use since the last detailed entry (total CPU and to three uids), but it gives us the infrastructure for adding more detailed data in the future. A detail entry for regular history looks like: Details: cpu=15730u+2307s (u0a57=11312u+502s, 1000=2344u+701s, 0=473u+991s) /proc/stat=15377 usr, 1797 sys, 197 io, 0 irq, 8 sirq, 23103 idle (42.9% of 6m 44s 820ms) u is user-space cpu time, s is system/kernel time. The equivalent check-in output is: 9,h,0,Dcpu=15730:2307/10057:11312:502/1000:2344:701/0:473:991 9,h,0,Dpst=15377,1797,197,0,8,23103 Also add a new "unplug" command to the battery service, to easily put it into a state where it always considers the device to be running on battery. Change-Id: Ic76d966f11e592b9dd671879977bf999ebc11eef --- core/java/android/os/BatteryStats.java | 188 ++++++++++++ .../android/internal/os/BatteryStatsImpl.java | 268 +++++++++++++++--- .../internal/os/ProcessCpuTracker.java | 75 +++-- .../com/android/server/BatteryService.java | 18 ++ .../server/am/ActivityManagerService.java | 77 ++--- 5 files changed, 536 insertions(+), 90 deletions(-) diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index cd45cfb326ac3..4dadda2d7a6e0 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -592,6 +592,86 @@ public abstract class BatteryStats implements Parcelable { } } + /** + * Optional detailed information that can go into a history step. This is typically + * generated each time the battery level changes. + */ + public final static class HistoryStepDetails { + // Time (in 1/100 second) spent in user space and the kernel since the last step. + public int userTime; + public int systemTime; + + // Top three apps using CPU in the last step, with times in 1/100 second. + public int appCpuUid1; + public int appCpuUTime1; + public int appCpuSTime1; + public int appCpuUid2; + public int appCpuUTime2; + public int appCpuSTime2; + public int appCpuUid3; + public int appCpuUTime3; + public int appCpuSTime3; + + // Information from /proc/stat + public int statUserTime; + public int statSystemTime; + public int statIOWaitTime; + public int statIrqTime; + public int statSoftIrqTime; + public int statIdlTime; + + public HistoryStepDetails() { + clear(); + } + + public void clear() { + userTime = systemTime = 0; + appCpuUid1 = appCpuUid2 = appCpuUid3 = -1; + appCpuUTime1 = appCpuSTime1 = appCpuUTime2 = appCpuSTime2 + = appCpuUTime3 = appCpuSTime3 = 0; + } + + public void writeToParcel(Parcel out) { + out.writeInt(userTime); + out.writeInt(systemTime); + out.writeInt(appCpuUid1); + out.writeInt(appCpuUTime1); + out.writeInt(appCpuSTime1); + out.writeInt(appCpuUid2); + out.writeInt(appCpuUTime2); + out.writeInt(appCpuSTime2); + out.writeInt(appCpuUid3); + out.writeInt(appCpuUTime3); + out.writeInt(appCpuSTime3); + out.writeInt(statUserTime); + out.writeInt(statSystemTime); + out.writeInt(statIOWaitTime); + out.writeInt(statIrqTime); + out.writeInt(statSoftIrqTime); + out.writeInt(statIdlTime); + } + + public void readFromParcel(Parcel in) { + userTime = in.readInt(); + systemTime = in.readInt(); + appCpuUid1 = in.readInt(); + appCpuUTime1 = in.readInt(); + appCpuSTime1 = in.readInt(); + appCpuUid2 = in.readInt(); + appCpuUTime2 = in.readInt(); + appCpuSTime2 = in.readInt(); + appCpuUid3 = in.readInt(); + appCpuUTime3 = in.readInt(); + appCpuSTime3 = in.readInt(); + statUserTime = in.readInt(); + statSystemTime = in.readInt(); + statIOWaitTime = in.readInt(); + statIrqTime = in.readInt(); + statSoftIrqTime = in.readInt(); + statIdlTime = in.readInt(); + } + } + public final static class HistoryItem implements Parcelable { public HistoryItem next; @@ -687,6 +767,9 @@ public abstract class BatteryStats implements Parcelable { // Kernel wakeup reason at this point. public HistoryTag wakeReasonTag; + // Non-null when there is more detailed information at this step. + public HistoryStepDetails stepDetails; + public static final int EVENT_FLAG_START = 0x8000; public static final int EVENT_FLAG_FINISH = 0x4000; @@ -3692,10 +3775,115 @@ public abstract class BatteryStats implements Parcelable { } } pw.println(); + if (rec.stepDetails != null) { + if (!checkin) { + pw.print(" Details: cpu="); + pw.print(rec.stepDetails.userTime); + pw.print("u+"); + pw.print(rec.stepDetails.systemTime); + pw.print("s"); + if (rec.stepDetails.appCpuUid1 >= 0) { + pw.print(" ("); + printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1, + rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1); + if (rec.stepDetails.appCpuUid2 >= 0) { + pw.print(", "); + printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2, + rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2); + } + if (rec.stepDetails.appCpuUid3 >= 0) { + pw.print(", "); + printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3, + rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3); + } + pw.print(')'); + } + pw.println(); + pw.print(" /proc/stat="); + pw.print(rec.stepDetails.statUserTime); + pw.print(" usr, "); + pw.print(rec.stepDetails.statSystemTime); + pw.print(" sys, "); + pw.print(rec.stepDetails.statIOWaitTime); + pw.print(" io, "); + pw.print(rec.stepDetails.statIrqTime); + pw.print(" irq, "); + pw.print(rec.stepDetails.statSoftIrqTime); + pw.print(" sirq, "); + pw.print(rec.stepDetails.statIdlTime); + pw.print(" idle"); + int totalRun = rec.stepDetails.statUserTime + rec.stepDetails.statSystemTime + + rec.stepDetails.statIOWaitTime + rec.stepDetails.statIrqTime + + rec.stepDetails.statSoftIrqTime; + int total = totalRun + rec.stepDetails.statIdlTime; + if (total > 0) { + pw.print(" ("); + float perc = ((float)totalRun) / ((float)total) * 100; + pw.print(String.format("%.1f%%", perc)); + pw.print(" of "); + StringBuilder sb = new StringBuilder(64); + formatTimeMsNoSpace(sb, total*10); + pw.print(sb); + pw.print(")"); + } + pw.println(); + } else { + pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); + pw.print(HISTORY_DATA); pw.print(",0,Dcpu="); + pw.print(rec.stepDetails.userTime); + pw.print(":"); + pw.print(rec.stepDetails.systemTime); + if (rec.stepDetails.appCpuUid1 >= 0) { + printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1, + rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1); + if (rec.stepDetails.appCpuUid2 >= 0) { + printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2, + rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2); + } + if (rec.stepDetails.appCpuUid3 >= 0) { + printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3, + rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3); + } + } + pw.println(); + pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(','); + pw.print(HISTORY_DATA); pw.print(",0,Dpst="); + pw.print(rec.stepDetails.statUserTime); + pw.print(','); + pw.print(rec.stepDetails.statSystemTime); + pw.print(','); + pw.print(rec.stepDetails.statIOWaitTime); + pw.print(','); + pw.print(rec.stepDetails.statIrqTime); + pw.print(','); + pw.print(rec.stepDetails.statSoftIrqTime); + pw.print(','); + pw.print(rec.stepDetails.statIdlTime); + pw.println(); + } + } oldState = rec.states; oldState2 = rec.states2; } } + + private void printStepCpuUidDetails(PrintWriter pw, int uid, int utime, int stime) { + UserHandle.formatUid(pw, uid); + pw.print("="); + pw.print(utime); + pw.print("u+"); + pw.print(stime); + pw.print("s"); + } + + private void printStepCpuUidCheckinDetails(PrintWriter pw, int uid, int utime, int stime) { + pw.print('/'); + pw.print(uid); + pw.print(":"); + pw.print(utime); + pw.print(":"); + pw.print(stime); + } } private void printSizeValue(PrintWriter pw, long size) { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 20bb95eeff4c6..d0c7f8c6ebc8b 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -94,7 +94,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 116 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 118 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -208,7 +208,7 @@ public final class BatteryStatsImpl extends BatteryStats { final HistoryItem mHistoryLastLastWritten = new HistoryItem(); final HistoryItem mHistoryReadTmp = new HistoryItem(); final HistoryItem mHistoryAddTmp = new HistoryItem(); - final HashMap mHistoryTagPool = new HashMap(); + final HashMap mHistoryTagPool = new HashMap(); String[] mReadHistoryStrings; int[] mReadHistoryUids; int mReadHistoryChars; @@ -227,6 +227,38 @@ public final class BatteryStatsImpl extends BatteryStats { HistoryItem mHistoryLastEnd; HistoryItem mHistoryCache; + // Used by computeHistoryStepDetails + HistoryStepDetails mLastHistoryStepDetails = null; + byte mLastHistoryStepLevel = 0; + final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); + final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); + final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); + /** + * Total time (in 1/100 sec) spent executing in user code. + */ + long mLastStepCpuUserTime; + long mCurStepCpuUserTime; + /** + * Total time (in 1/100 sec) spent executing in kernel code. + */ + long mLastStepCpuSystemTime; + long mCurStepCpuSystemTime; + /** + * Times from /proc/stat + */ + long mLastStepStatUserTime; + long mLastStepStatSystemTime; + long mLastStepStatIOWaitTime; + long mLastStepStatIrqTime; + long mLastStepStatSoftIrqTime; + long mLastStepStatIdleTime; + long mCurStepStatUserTime; + long mCurStepStatSystemTime; + long mCurStepStatIOWaitTime; + long mCurStepStatIrqTime; + long mCurStepStatSoftIrqTime; + long mCurStepStatIdleTime; + private HistoryItem mHistoryIterator; private boolean mReadOverflow; private boolean mIteratingHistory; @@ -1938,6 +1970,10 @@ public final class BatteryStatsImpl extends BatteryStats { static final int STATE_BATTERY_PLUG_MASK = 0x00000003; static final int STATE_BATTERY_PLUG_SHIFT = 24; + // We use the low bit of the battery state int to indicate that we have full details + // from a battery level change. + static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; + public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { dest.writeInt(DELTA_TIME_ABS); @@ -1958,7 +1994,11 @@ public final class BatteryStatsImpl extends BatteryStats { deltaTimeToken = (int)deltaTime; } int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); - final int batteryLevelInt = buildBatteryLevelInt(cur); + final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel + ? BATTERY_DELTA_LEVEL_FLAG : 0; + final boolean computeStepDetails = includeStepDetails != 0 + || mLastHistoryStepDetails == null; + final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; if (batteryLevelIntChanged) { firstToken |= DELTA_BATTERY_LEVEL_FLAG; @@ -2040,12 +2080,26 @@ public final class BatteryStatsImpl extends BatteryStats { + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" + cur.eventTag.string); } + if (computeStepDetails) { + computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); + if (includeStepDetails != 0) { + mCurHistoryStepDetails.writeToParcel(dest); + } + cur.stepDetails = mCurHistoryStepDetails; + mLastHistoryStepDetails = mCurHistoryStepDetails; + } else { + cur.stepDetails = null; + } + if (mLastHistoryStepLevel < cur.batteryLevel) { + mLastHistoryStepDetails = null; + } + mLastHistoryStepLevel = cur.batteryLevel; } private int buildBatteryLevelInt(HistoryItem h) { return ((((int)h.batteryLevel)<<25)&0xfe000000) - | ((((int)h.batteryTemperature)<<14)&0x01ffc000) - | (((int)h.batteryVoltage)&0x00003fff); + | ((((int)h.batteryTemperature)<<14)&0x01ff8000) + | ((((int)h.batteryVoltage)<<1)&0x00007fff); } private int buildStateInt(HistoryItem h) { @@ -2063,6 +2117,98 @@ public final class BatteryStatsImpl extends BatteryStats { | (h.states&(~DELTA_STATE_MASK)); } + private void computeHistoryStepDetails(final HistoryStepDetails out, + final HistoryStepDetails last) { + final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; + + // Perform a CPU update right after we do this collection, so we have started + // collecting good data for the next step. + requestImmediateCpuUpdate(); + + if (last == null) { + // We are not generating a delta, so all we need to do is reset the stats + // we will later be doing a delta from. + final int NU = mUidStats.size(); + for (int i=0; i= mBaseUserTime && systemtime >= mBaseSystemTime + && iowaittime >= mBaseIoWaitTime && irqtime >= mBaseIrqTime + && softirqtime >= mBaseSoftIrqTime && idletime >= mBaseIdleTime)) { + mRelUserTime = (int)(usertime - mBaseUserTime); + mRelSystemTime = (int)(systemtime - mBaseSystemTime); + mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime); + mRelIrqTime = (int)(irqtime - mBaseIrqTime); + mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime); + mRelIdleTime = (int)(idletime - mBaseIdleTime); + mRelStatsAreGood = true; - if (DEBUG) { - Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1] - + " S:" + sysCpu[2] + " I:" + sysCpu[3] - + " W:" + sysCpu[4] + " Q:" + sysCpu[5] - + " O:" + sysCpu[6]); - Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime - + " I:" + mRelIdleTime + " Q:" + mRelIrqTime); + if (DEBUG) { + Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1] + + " S:" + sysCpu[2] + " I:" + sysCpu[3] + + " W:" + sysCpu[4] + " Q:" + sysCpu[5] + + " O:" + sysCpu[6]); + Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime + + " I:" + mRelIdleTime + " Q:" + mRelIrqTime); + } + + mBaseUserTime = usertime; + mBaseSystemTime = systemtime; + mBaseIoWaitTime = iowaittime; + mBaseIrqTime = irqtime; + mBaseSoftIrqTime = softirqtime; + mBaseIdleTime = idletime; + + } else { + mRelUserTime = 0; + mRelSystemTime = 0; + mRelIoWaitTime = 0; + mRelIrqTime = 0; + mRelSoftIrqTime = 0; + mRelIdleTime = 0; + mRelStatsAreGood = false; + Slog.w(TAG, "/proc/stats has gone backwards; skipping CPU update"); + return; } - - mBaseUserTime = usertime; - mBaseSystemTime = systemtime; - mBaseIoWaitTime = iowaittime; - mBaseIrqTime = irqtime; - mBaseSoftIrqTime = softirqtime; - mBaseIdleTime = idletime; } + mLastSampleTime = mCurrentSampleTime; + mCurrentSampleTime = nowUptime; + mLastSampleRealTime = mCurrentSampleRealTime; + mCurrentSampleRealTime = nowRealtime; + final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); try { mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats); @@ -647,6 +670,10 @@ public class ProcessCpuTracker { return mRelIdleTime; } + final public boolean hasGoodLastStats() { + return mRelStatsAreGood; + } + final public float getTotalCpuPercent() { int denom = mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime; if (denom <= 0) { diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 912a181ef944c..b3b46513ec6a7 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -626,6 +626,22 @@ public final class BatteryService extends SystemService { pw.println(" voltage: " + mBatteryProps.batteryVoltage); pw.println(" temperature: " + mBatteryProps.batteryTemperature); pw.println(" technology: " + mBatteryProps.batteryTechnology); + + } else if ("unplug".equals(args[0])) { + if (!mUpdatesStopped) { + mLastBatteryProps.set(mBatteryProps); + } + mBatteryProps.chargerAcOnline = false; + mBatteryProps.chargerUsbOnline = false; + mBatteryProps.chargerWirelessOnline = false; + long ident = Binder.clearCallingIdentity(); + try { + mUpdatesStopped = true; + processValuesLocked(false); + } finally { + Binder.restoreCallingIdentity(ident); + } + } else if (args.length == 3 && "set".equals(args[0])) { String key = args[1]; String value = args[2]; @@ -662,6 +678,7 @@ public final class BatteryService extends SystemService { } catch (NumberFormatException ex) { pw.println("Bad value: " + value); } + } else if (args.length == 1 && "reset".equals(args[0])) { long ident = Binder.clearCallingIdentity(); try { @@ -676,6 +693,7 @@ public final class BatteryService extends SystemService { } else { pw.println("Dump current battery state, or:"); pw.println(" set [ac|usb|wireless|status|level|invalid] "); + pw.println(" unplug"); pw.println(" reset"); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 511347e1dd119..d53b61bba1aa0 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2255,31 +2255,33 @@ public final class ActivityManagerService extends ActivityManagerNative if (MONITOR_CPU_USAGE && mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { mLastCpuTime.set(now); - haveNewCpuStats = true; mProcessCpuTracker.update(); - //Slog.i(TAG, mProcessCpu.printCurrentState()); - //Slog.i(TAG, "Total CPU usage: " - // + mProcessCpu.getTotalCpuPercent() + "%"); + if (mProcessCpuTracker.hasGoodLastStats()) { + haveNewCpuStats = true; + //Slog.i(TAG, mProcessCpu.printCurrentState()); + //Slog.i(TAG, "Total CPU usage: " + // + mProcessCpu.getTotalCpuPercent() + "%"); - // Slog the cpu usage if the property is set. - if ("true".equals(SystemProperties.get("events.cpu"))) { - int user = mProcessCpuTracker.getLastUserTime(); - int system = mProcessCpuTracker.getLastSystemTime(); - int iowait = mProcessCpuTracker.getLastIoWaitTime(); - int irq = mProcessCpuTracker.getLastIrqTime(); - int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); - int idle = mProcessCpuTracker.getLastIdleTime(); + // Slog the cpu usage if the property is set. + if ("true".equals(SystemProperties.get("events.cpu"))) { + int user = mProcessCpuTracker.getLastUserTime(); + int system = mProcessCpuTracker.getLastSystemTime(); + int iowait = mProcessCpuTracker.getLastIoWaitTime(); + int irq = mProcessCpuTracker.getLastIrqTime(); + int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); + int idle = mProcessCpuTracker.getLastIdleTime(); - int total = user + system + iowait + irq + softIrq + idle; - if (total == 0) total = 1; + int total = user + system + iowait + irq + softIrq + idle; + if (total == 0) total = 1; - EventLog.writeEvent(EventLogTags.CPU, - ((user+system+iowait+irq+softIrq) * 100) / total, - (user * 100) / total, - (system * 100) / total, - (iowait * 100) / total, - (irq * 100) / total, - (softIrq * 100) / total); + EventLog.writeEvent(EventLogTags.CPU, + ((user+system+iowait+irq+softIrq) * 100) / total, + (user * 100) / total, + (system * 100) / total, + (iowait * 100) / total, + (irq * 100) / total, + (softIrq * 100) / total); + } } } @@ -2288,8 +2290,10 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized(bstats) { synchronized(mPidsSelfLocked) { if (haveNewCpuStats) { - if (mOnBattery) { - int perc = bstats.startAddingCpuLocked(); + final int perc = bstats.startAddingCpuLocked(); + if (perc >= 0) { + int remainUTime = 0; + int remainSTime = 0; int totalUTime = 0; int totalSTime = 0; final int N = mProcessCpuTracker.countStats(); @@ -2301,17 +2305,18 @@ public final class ActivityManagerService extends ActivityManagerNative ProcessRecord pr = mPidsSelfLocked.get(st.pid); int otherUTime = (st.rel_utime*perc)/100; int otherSTime = (st.rel_stime*perc)/100; - totalUTime += otherUTime; - totalSTime += otherSTime; + remainUTime += otherUTime; + remainSTime += otherSTime; + totalUTime += st.rel_utime; + totalSTime += st.rel_stime; if (pr != null) { BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; if (ps == null || !ps.isActive()) { pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( pr.info.uid, pr.processName); } - ps.addCpuTimeLocked(st.rel_utime-otherUTime, - st.rel_stime-otherSTime); - ps.addSpeedStepTimes(cpuSpeedTimes); + ps.addCpuTimeLocked(st.rel_utime - otherUTime, + st.rel_stime - otherSTime, cpuSpeedTimes); pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; } else { BatteryStatsImpl.Uid.Proc ps = st.batteryStats; @@ -2319,13 +2324,19 @@ public final class ActivityManagerService extends ActivityManagerNative st.batteryStats = ps = bstats.getProcessStatsLocked( bstats.mapUid(st.uid), st.name); } - ps.addCpuTimeLocked(st.rel_utime-otherUTime, - st.rel_stime-otherSTime); - ps.addSpeedStepTimes(cpuSpeedTimes); + ps.addCpuTimeLocked(st.rel_utime - otherUTime, + st.rel_stime - otherSTime, cpuSpeedTimes); } } - bstats.finishAddingCpuLocked(perc, totalUTime, - totalSTime, cpuSpeedTimes); + final int userTime = mProcessCpuTracker.getLastUserTime(); + final int systemTime = mProcessCpuTracker.getLastSystemTime(); + final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime(); + final int irqTime = mProcessCpuTracker.getLastIrqTime(); + final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); + final int idleTime = mProcessCpuTracker.getLastIdleTime(); + bstats.finishAddingCpuLocked(perc, remainUTime, + remainSTime, totalUTime, totalSTime, userTime, systemTime, + iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes); } } }