From 1e01d16982e6b22ec4c0e2d6dc1e261eb6f92c8e Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 4 Dec 2014 17:46:42 -0800 Subject: [PATCH] Fix issue #17323751: Additional items in aggregated battery stats - Now aggregate number of times each process has crashed and ANRed. - Now aggregate total number of connectivity changes. - Now record connectivity changes in the history. Crash and ANR counts are new entries at the end of "pr" in checkin. Connectivity change counts is a new entry at the end of "m" in checkin. Connectivity changes in the history checkin are Ecn and include the type of connection and its state. Change-Id: I0c01186446034cf6c3fb97d45f5e3b5c69a0438a --- core/java/android/os/BatteryStats.java | 70 +++++++-- core/java/android/util/Log.java | 5 + core/java/android/util/Slog.java | 7 + .../android/internal/app/IBatteryStats.aidl | 1 + .../android/internal/os/BatteryStatsImpl.java | 147 +++++++++++++++--- .../android/server/ConnectivityService.java | 11 ++ .../server/am/ActivityManagerService.java | 19 +++ .../server/am/BatteryStatsService.java | 19 +++ 8 files changed, 245 insertions(+), 34 deletions(-) diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 11fc69e6a2167..5fd697a6b4a58 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -458,6 +458,20 @@ public abstract class BatteryStats implements Parcelable { */ public abstract int getStarts(int which); + /** + * Returns the number of times the process has crashed. + * + * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. + */ + public abstract int getNumCrashes(int which); + + /** + * Returns the number of times the process has ANRed. + * + * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. + */ + public abstract int getNumAnrs(int which); + /** * Returns the cpu time spent in microseconds while the process was in the foreground. * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. @@ -694,8 +708,10 @@ public abstract class BatteryStats implements Parcelable { public static final int EVENT_USER_RUNNING = 0x0007; // Events for foreground user. public static final int EVENT_USER_FOREGROUND = 0x0008; + // Events for connectivity changed. + public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009; // Number of event types. - public static final int EVENT_COUNT = 0x0009; + public static final int EVENT_COUNT = 0x000a; // Mask to extract out only the type part of the event. public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH); @@ -1106,6 +1122,13 @@ public abstract class BatteryStats implements Parcelable { */ public abstract int getLowPowerModeEnabledCount(int which); + /** + * Returns the number of times that connectivity state changed. + * + * {@hide} + */ + public abstract int getNumConnectivityChange(int which); + /** * Returns the time in microseconds that the phone has been on while the device was * running on battery. @@ -1306,11 +1329,11 @@ public abstract class BatteryStats implements Parcelable { }; public static final String[] HISTORY_EVENT_NAMES = new String[] { - "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg" + "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn" }; public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] { - "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf" + "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn" }; /** @@ -1871,6 +1894,7 @@ public abstract class BatteryStats implements Parcelable { final long screenOnTime = getScreenOnTime(rawRealtime, which); final long interactiveTime = getInteractiveTime(rawRealtime, which); final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which); + final int connChanges = getNumConnectivityChange(which); final long phoneOnTime = getPhoneOnTime(rawRealtime, which); final long wifiOnTime = getWifiOnTime(rawRealtime, which); final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which); @@ -1941,7 +1965,7 @@ public abstract class BatteryStats implements Parcelable { fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000, 0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which) / 1000, getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000, - lowPowerModeEnabledTime / 1000); + lowPowerModeEnabledTime / 1000, connChanges); // Dump screen brightness stats Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; @@ -2271,12 +2295,14 @@ public abstract class BatteryStats implements Parcelable { final long userMillis = ps.getUserTime(which) * 10; final long systemMillis = ps.getSystemTime(which) * 10; final long foregroundMillis = ps.getForegroundTime(which) * 10; - final long starts = ps.getStarts(which); + final int starts = ps.getStarts(which); + final int numCrashes = ps.getNumCrashes(which); + final int numAnrs = ps.getNumAnrs(which); if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 - || starts != 0) { + || starts != 0 || numAnrs != 0 || numCrashes != 0) { dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis, - systemMillis, foregroundMillis, starts); + systemMillis, foregroundMillis, starts, numAnrs, numCrashes); } } } @@ -2457,6 +2483,11 @@ public abstract class BatteryStats implements Parcelable { sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime)); sb.append(") "); sb.append(getPhoneOnCount(which)); } + int connChanges = getNumConnectivityChange(which); + if (connChanges != 0) { + pw.print(prefix); + pw.print(" Connectivity changes: "); pw.println(connChanges); + } // Calculate wakelock times across all uids. long fullWakeLockTimeTotalMicros = 0; @@ -3273,11 +3304,13 @@ public abstract class BatteryStats implements Parcelable { systemTime = ps.getSystemTime(which); foregroundTime = ps.getForegroundTime(which); starts = ps.getStarts(which); + final int numCrashes = ps.getNumCrashes(which); + final int numAnrs = ps.getNumAnrs(which); numExcessive = which == STATS_SINCE_CHARGED ? ps.countExcessivePowers() : 0; if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 - || numExcessive != 0) { + || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) { sb.setLength(0); sb.append(prefix); sb.append(" Proc "); sb.append(ent.getKey()); sb.append(":\n"); @@ -3285,9 +3318,26 @@ public abstract class BatteryStats implements Parcelable { formatTime(sb, userTime); sb.append("usr + "); formatTime(sb, systemTime); sb.append("krn ; "); formatTime(sb, foregroundTime); sb.append("fg"); - if (starts != 0) { + if (starts != 0 || numCrashes != 0 || numAnrs != 0) { sb.append("\n"); sb.append(prefix); sb.append(" "); - sb.append(starts); sb.append(" proc starts"); + boolean hasOne = false; + if (starts != 0) { + hasOne = true; + sb.append(starts); sb.append(" starts"); + } + if (numCrashes != 0) { + if (hasOne) { + sb.append(", "); + } + hasOne = true; + sb.append(numCrashes); sb.append(" crashes"); + } + if (numAnrs != 0) { + if (hasOne) { + sb.append(", "); + } + sb.append(numAnrs); sb.append(" anrs"); + } } pw.println(sb.toString()); for (int e=0; e 100) { Slog.w(TAG, "File corrupt: too many speed bins " + NSB); @@ -8143,6 +8233,7 @@ public final class BatteryStatsImpl extends BatteryStats { for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); } + out.writeInt(mNumConnectivityChange); mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); out.writeInt(mKernelWakelockStats.size()); @@ -8326,6 +8417,8 @@ public final class BatteryStatsImpl extends BatteryStats { out.writeLong(ps.mSystemTime); out.writeLong(ps.mForegroundTime); out.writeInt(ps.mStarts); + out.writeInt(ps.mNumCrashes); + out.writeInt(ps.mNumAnrs); final int N = ps.mSpeedBins.length; out.writeInt(N); for (int i=0; i ((proc.initialIdlePss*3)/2)) { + sb = new StringBuilder(128); + sb.append("Kill"); + sb.append(proc.processName); + sb.append(" in idle maint: pss="); + sb.append(proc.lastPss); + sb.append(", initialPss="); + sb.append(proc.initialIdlePss); + sb.append(", period="); + TimeUtils.formatDuration(timeSinceLastIdle, sb); + sb.append(", lowRamPeriod="); + TimeUtils.formatDuration(lowRamSinceLastIdle, sb); + Slog.wtfQuiet(TAG, sb.toString()); proc.kill("idle maint (pss " + proc.lastPss + " from " + proc.initialIdlePss + ")", true); } @@ -12035,6 +12049,11 @@ public final class ActivityManagerService extends ActivityManagerNative return; } + // Log crash in battery stats. + if (r != null) { + mBatteryStatsService.noteProcessCrash(r.processName, r.uid); + } + // If we can't identify the process or it's already exceeded its crash quota, // quit right away without showing a crash dialog. if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 6983ec49beccf..c0928c75564cb 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -143,6 +143,18 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } + void noteProcessCrash(String name, int uid) { + synchronized (mStats) { + mStats.noteProcessCrashLocked(name, uid); + } + } + + void noteProcessAnr(String name, int uid) { + synchronized (mStats) { + mStats.noteProcessAnrLocked(name, uid); + } + } + void noteProcessState(String name, int uid, int state) { synchronized (mStats) { mStats.noteProcessStateLocked(name, uid, state); @@ -349,6 +361,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } + public void noteConnectivityChanged(int type, String extra) { + enforceCallingPermission(); + synchronized (mStats) { + mStats.noteConnectivityChangedLocked(type, extra); + } + } + public void noteMobileRadioPowerState(int powerState, long timestampNs) { enforceCallingPermission(); synchronized (mStats) {